JavaScript 在 V8 中编译

JavaScript compilation in V8

V8 home(Google 的 JavaScript 引擎)中,我们读到:

V8 compiles and executes JavaScript source code


编辑:还有一个 existing question 已经解决了我的第一个问题,但没有解决第二个问题。

Does it mean that JavaScript is not an interpreted language in V8?

这个问题的答案是 "it depends"。

历史上,V8 使用其 "full-codegen" 编译器直接编译为机器代码,它会生成未优化的代码,这些代码使用 inline caching 来实现大多数操作,例如算术运算、变量和属性的加载和存储,等等

full-codegen 生成的代码跟踪 "hot" 每个函数的状态,方法是在调用函数时和跳回到循环顶部时调整计数器。

它还会跟踪每个表达式中使用的变量类型。

如果它确定一个函数(或函数的一部分)非常热,并且它收集了足够的类型信息,它会触发 "Crankshaft" 编译器生成更好的代码。

但是,V8 开发人员正积极致力于转移到一个不同的系统,他们从一个名为 "Ignition" 的解释器开始,然后使用一个名为 "Turbofan" 的编译器为热门函数生成优化代码.

以下是来自 V8 开发人员博客的几篇文章对此进行了描述:

Does V8 use a just-in-time compilation approach for JavaScript?

是的,在很多方面。

首先,它具有惰性解析和惰性编译机制。这意味着当它解析 Javascript 源文件时,它会急切地解析最外层的范围,立即生成 full-codegen 代码。

但是,对于文件中定义的函数,它会跳过它们,只记录函数的名称和源代码的位置。它生成一个虚拟函数,它只是调用 V8 运行时来触发函数的实际编译。

其次,它有一个如上所述的两阶段编译器管道,使用 full-codegen+曲轴或点火+涡轮风扇。

当触发编译时,它最初会生成未优化的代码或点火字节码(它可以非常快地完成),然后如果代码很热,它会触发优化的 re-compilation(这要慢得多但会生成更好的代码)。