了解V8引擎如何运行JS
2021-02-08 本文已影响0人
深度剖析JavaScript
前言
今天看了一个视频,关于V8引擎是如何运行JS的。我将视频中主要的知识点记下来,一来加深记忆,二来方便复习
什么是V8
V8是使用C++编写的Google开源高性能JavaScript和WebAssembly引擎。V8第一个版本随着第一个版本的Chrome于2008年9月2日发布
哪些程序用到V8
-
Chrome浏览器的JS引擎是V8 -
Nodejs的运行时环境是V8 -
electron的底层引擎是V8
V8主要职责
简单来说,V8是一个接收JavaScript代码,编译代码然后执行C++程序,编译后的代码可以在多种操作系统多种处理器上运行。其主要职责:
- 编译和执行
JS代码 - 处理调用栈
- 内存分配
- 垃圾回收
V8如何编译和执行JS代码
一般来说,JS引擎在编译和执行代码都会用到三个重要的组件,分别:
- 解析器 --> 负责将
JS源代码解析成抽象语法树AST
- 解释器 --> 负责将
AST解析成字节码bytecode,同时解释器也有解释执行bytecode的能力
- 编译器 --> 负责编译出运行更加高效的机器代码
但是在V8早期,在5.9版本以前,是没有解释器,但有两个编译器,其编译流程如下
-
parser解释器生成抽象语法树AST -
compiler编译器Full-codegen基准编译器 直接生成机器码 - 运行一段时间后,由分析器线程优化
js代码 -
compiler编译器CrankShaft优化编译器 重新生成AST提升运行效率
这样设计的缺点
- 机器码会占用大量的内存
- 缺少中间层机器码,无法实现一些优化策略
- 无法很好的支持和优化
JS的新语特性,无法拥抱未来
正因为存在以上问题,V8团队用了三年半的时间,开发了一套新的V8架构
新版本的V8
-
parser解析器 生成AST抽象语法树 -
interpreter解释器Ignition生成byteCode字节码 并直接执行 - 清除
AST释放内存空间 - 得到
25% - 50%的等效机器代码大小 -
compiler运行过程中,解释器收集优化信息发送给编译器TurboFan - 重新生成机器码
- 有些热点函数变更会由优化后的机器码还原成字节码 也就是
deoptimization回退字节码操作执行
优化点:
- 值声明未调用,不会被解析生成
AST - 函数只被调用一次,
bytcode直接被解释执行,不会进入到编译优化阶段 - 函数被调用多次,
Igniton会收集函数类型信息,可能会被标记为热点函数,可能被编译成优化后的机器代码
好处:
- 由于一开始不需要直接编译成机器码,生成了中间层的字节码,从而节约了时间
- 优化编译阶段,不需要从源码重新解析,直接通过字节码进行优化,也可以
deoptimization回退操作
如:
function sum(x,y){return x + y};
sum(1,2);
sum(3,4);
sum(5,6);
sum("7","8");//会回退字节码操作执行
以上就是V8引擎如何运行JS相关内容
原视频:https://www.bilibili.com/video/BV1zV411z7RX
作者:luke
个人推荐多看两遍