V8 如何执行一段 JavaScript 代码

编译

是的,JavaScript 代码在执行前的瞬间(通常几微秒)会经过编译阶段。此阶段会创建变量环境、分词,这也就造成了变量提升效果。

为什么需要先编译再执行

CPU 只能识别形如1000100111011000的二进制指令,为了方便记忆,程序员通过将二进制指令转为汇编指令集进行开发。所以 CPU 执行的是汇编代码经过编译后的机器码。

1000100111011000 机器指令
mov ax,bx 汇编指令

汇编的缺陷

  • 不同架构的 CPU 有不同的指令集,需要为不同架构编写特定的汇编代码
  • 在编写汇编代码,还需要了解处理器架构相关的硬件知识,增加学习成本

为了避免接触和兼容不同计算机架构,高级语言出现了。

执行

高级语言需要经过编译器或解释器翻译才能被 CPU 执行。

编译

为了更快的执行速度,V8 混合使用编译器和解释器,称为 JIT(Just In Time)。

初始化

初始化执行环境,包括栈堆内存、全局上下文、作用域、事件循环系统...

结构化,为什么要 AST

源代码经过解析器结构化生成 AST(抽象语法树),确定作用域

为什么需要字节码

依据 AST 和作用域生成字节码,解释执行字节码。

最开始是没有字节码的,V8 直接将 AST 转换成机器码。虽然少了中间步骤,但也造成了内存占用的问题,因为字节码比机器码占用内存空间更少,可以减少系统的内存使用。特别是在 512MB 运存的手机时代。

优化

监听热点代码,优化热点代码生成二进制的机器代码。