配置JavaScript引擎

描述可用的环境变量,以控制Javascript的运行方式。

运行JavaScript代码可能会受到一些环境变量的影响,特别是:

环境变量

描述

QV4_JIT_CALL_THRESHOLD

JavaScript引擎包含一个即时编译器(JIT)。JIT会将频繁运行的JavaScript函数编译成机器代码以加快运行速度。此环境变量决定了函数需要运行多少次才能被考虑进行JIT编译。默认值为3次。

QV4_FORCE_INTERPRETER

设置此环境变量将通过解释器运行所有函数和表达式。无论函数或表达式被调用多少次,JIT都不会被使用。函数和表达式仍然可以使用qmlcachegenqmlsc提前编译,但在运行时只使用生成的字节码。任何生成的C++代码及其生成的机器代码都将被忽略。

QV4_JS_MAX_STACK_SIZE

JavaScript引擎保留一个特殊的内存区域作为堆栈来运行JavaScript。这个堆栈与C++堆栈是分开的。通常这个区域的大小为4MB。如果这个环境变量包含一个数字,JavaScript引擎会将其解释为要分配为JavaScript堆栈的内存区域的大小,以字节为单位。

QV4_GC_MAX_STACK_SIZE

除了常规的JavaScript堆栈外,JavaScript引擎还为垃圾收集器保留了另一个堆栈,通常为2MB的内存。如果垃圾收集器需要同时处理过多的对象,这个堆栈可能会溢出。如果它包含一个数字,这个环境变量将被解释为分配给垃圾收集器堆栈的内存区域的大小(以字节为单位)。

QV4_CRASH_ON_STACKOVERFLOW

通常,JavaScript引擎会尝试捕获由过度递归的JavaScript代码引起的C++堆栈溢出,并生成非致命错误条件。对于编译JavaScript和运行JavaScript有单独的递归检查。编译JavaScript时的堆栈溢出表明代码包含深度嵌套的对象和函数。运行时的堆栈溢出表明代码导致了一个深度递归的程序。这个检查与上面提到的JavaScript堆栈大小只有间接关系,因为每个JavaScript函数调用都会消耗C++和JavaScript堆栈上的堆栈空间。检查过度递归的代码必然是保守的,因为可用的堆栈大小取决于许多因素,并且通常可以由用户自定义。设置此环境变量后,JavaScript引擎在编译或运行JavaScript时不会检查堆栈溢出,也不会为它们生成异常。相反,当堆栈溢出时,程序会尝试进行无效的内存访问。这很可能会导致程序终止。反过来,程序可以使用操作系统提供的所有堆栈空间。

警告

恶意代码可能能够通过这种方式逃避终止并访问意外的内存位置。

QV4_MAX_CALL_DEPTH

通过控制调用深度(即嵌套函数调用的次数)来防止在运行(而非编译)JavaScript时发生堆栈溢出。默认情况下,如果调用深度超过根据平台默认堆栈大小调整的最大值,则会生成异常。如果QV4_MAX_CALL_DEPTH环境变量包含一个数字,则使用该数字作为最大调用深度。请注意,编译JavaScript时的递归限制不受影响。在大多数平台上,默认的最大调用深度为1234。在QNX上,由于默认堆栈大小较小,最大调用深度为640。

QV4_MM_AGGRESSIVE_GC

设置此环境变量会在每次内存分配之前运行垃圾收集器。这在运行时非常昂贵,但它能快速揭示许多内存管理错误,例如从C++手动删除属于QML引擎的对象。

QV4_PROFILE_WRITE_PERF_MAP

在Linux上,perf工具可以用来分析程序的性能。为了分析JIT编译的JavaScript函数,它需要知道这些函数在内存中的名称和位置。为了提供这些信息,有一种约定是在/tmp目录下创建一个名为perf-.map的特殊文件,perf工具随后会读取这个文件。如果设置了此环境变量,JIT将生成此文件。

QV4_SHOW_BYTECODE

将Qt生成的IR字节码输出到控制台。必须与QML_DISABLE_DISK_CACHE结合使用,否则已经缓存的字节码将不会显示。

QV4_DUMP_BASIC_BLOCKS

输出每个提前编译的函数的基本块。块的详细信息会打印到控制台。此外,每个编译函数的控制流图以及每个块的字节码会以DOT格式生成。QV4_DUMP_BASIC_BLOCKS的值用作生成DOT文件的文件夹路径。如果路径是["-", "1", "true"]中的任何一个,或者如果文件无法打开,图形将转储到stdout。

QV4_VALIDATE_BASIC_BLOCKS

对提前编译的函数的基本块执行检查,以验证其结构和一致性。如果验证失败,错误消息将打印到控制台。

QML磁盘缓存接受更多的环境变量,这些变量允许微调其行为。特别是QML_DISABLE_DISK_CACHE可能对调试有用。