求star

开源不易,喜欢请点个star吧

Ocean Han
1098 字
5 分钟
浅析V8引擎的基本工作原理
2022-05-07

什么是V8引擎?#

TIP

首先,JavaScript是一门高级编程语言,所以JavaScript代码直接交给浏览器或者Node执行时,底层的CPU是不认识的,也没法执行。CPU只认识自己的指令集,指令集对应的是汇编代码。

汇编语言: 由于机器语言是一系列二进制代码,不方便程序员记忆、使用和阅读,所以汇编语言应运而生,通常高级语言需要转换成汇编语言,然后在通过编译器转换成机器语言。

TIP

V8引擎是一个JavaScript引擎,最初由一些语言方面专家设计,后被谷歌收购,随后谷歌对其进行了开源。

目前比较出名的js引擎有:

  • V8 (Google)
  • SpiderMonkey (Mozilla)
  • JavaScriptCore (Apple)
  • Chakra (Microsoft)
  • IOT:duktape、JerryScript

简单来说,V8是一个接收js代码,然后进行编译执行的C++程序,编译后的代码可以在多种操作系统多种处理器上执行。

V8引擎是如何编译JS代码的?#

1. 早期的V8引擎#

WARNING

早期的(5.9版本之前)V8引擎,没有解释器,但有两个编译器

它的编译流程是这样的:

  • 首先js代码由解析器解析成AST抽象语法树
  • 然后,由Full-codegen编译器直接使用AST编译出机器代码,没有进行任何中间转换
  • 当代码运行一段时间后,V8引擎中的分析线程收集了足够的数据,帮助另一个编辑器Crankshaft对代码进行优化
  • 需要优化的JS源码重新生成AST,然后Crankshaft使用AST再生成优化后的机器代码,提升运行效率

这种设计模式带来的问题:

  • 生成的机器码会占用大量的内存空间,并且有些代码仅执行一次,没有必要直接生成机器码
  • 缺少中间层字节码,很多优化策略无法实施,导致V8引擎性能提升缓慢
  • 无法很好的支持JS新的语法特性,无法拥抱未来

2. 目前大部分的JS引擎#

TIP

大部分的JS引擎都会用到以下三个重要的组件

2.1 解析器(parser)#

TIP

解析器(parser)负责将JS源代码解析成抽象语法树AST

2.2 解释器(interpreter)#

TIP

解释器(interpreter)负责将AST解释成字节码bytecode

WARNING

需要注意的是,解释器也有直接执行字节码的能力

2.3 编译器(compiler)#

TIP

编译器(compiler)负责编译出更加有效(相对于bytecode来说)的机器代码

3. 现代V8引擎(改进之后)#

3.1 语法树的解析和之前保持一致#

JS源代码首先被解析器解析成AST抽象语法树

3.2 引入了基准解释器(Ignition),优化编译器(TurboFan)#

TIP
  • 语法树通过Ignition生成了bytecode字节码,此时AST就被清除,释放内存空间
  • 生成的bytecode直接被解释器执行,生成的bytecode相当于等效的基准基准机器代码的25%-50%作用
  • 在代码运行的过程中,解释器收集到了很多可以用来优化代码的信息,然后发送给编译器TurboFan
  • TurboFan编译出经过优化的机器代码

3.3 V8引擎一些简单的优化策略#

TIP
  • 如果函数只被声明,而未被调用,则不会生成抽象语法树AST
  • 如果函数只被调用一次,bytecode会直接被解释执行,而不会生成机器代码
  • 函数被调用多次,可能会被标记为热点函数,而能会被编译成机器代码

3.4 deoptimization#

TIP

因为JS是动态语言,有时会导致Ignition收集到错误的信息

优化后的机器代码,有时会被逆向还原成字节码

3.5 新的设计模式带来的好处#

TIP
  • 由于不需要一开始直接编译成机器码,而是生成了中间层的字节码,bytecode的生成速度是远远大于机器码的,所以网页初始化解析执行JS的时间缩短了
  • 生成优化的机器代码时,不需要从源码重新编译,而是使用字节码,而且需要deoptimization时,只需要回到中间层的字节码直接解释执行即可

4. 查看JS源代码生成的字节码的命令:#

node --print-bytecode xxx.js
浅析V8引擎的基本工作原理
https://blog.oceanh.top/posts/frontend/浅析google-v8引擎的基本工作原理/
作者
Ocean Han
发布于
2022-05-07
许可协议
CC BY-NC-SA 4.0
最后修改时间
2024-08-10 10:08:49