★ 深入理解V8引擎。。。算了简单理解一下吧
浏览器内核
浏览器内核又可以分成两部分:渲染引擎(layout engineer或者RenderingEngine)和JS引擎。
-
渲染引擎
渲染引擎使用JS引擎的接口来处理逻辑代码并获取结果。
-
JS引擎
JS引擎通过桥接接口访问渲染引擎中的DOM及CSSOM
主流 JS 引擎
- V8 (Google)
- SpiderMonkey (Mozilla)
- JavaScriptCore (Apple)
V8基本介绍
-
概念: V8是一个由Google开源的采用C++编写的高性能JavaScript和WebAssembly引擎,应用在 Chrome和Node.js等中。它实现了ECMAScript和WebAssembly,运行在Windows 7及以上、macOS 10.12+以及使用x64、IA-32、ARM或MIPS处理器的Linux系统上。V8可以独立运行,也可以嵌入到任何C++应用程序中。
-
V8由来:V8最初是由Lars Bak团队开发的,以汽车的V8发动机(有八个气缸的V型发动机)进行命名,预示着这将是一款性能极高的JavaScript引擎,在2008年9月2号同chrome一同开源发布。
-
为什么需要V8:我们写的JavaScript代码最终是要在机器中被执行的,但机器无法直接识别这些高级语言。需要经过一系列的处理,将高级语言转换成机器可以识别的的指令,也就是二进制码,交给机器执行。这中间的转换过程就是V8的具体工作。
-
V8组成:首先来看一下V8的内部组成。V8的内部有很多模块,其中最重要的4个如下:
- Parser: 解析器,负责将源代码解析成AST
- Ignition: 解释器,负责将AST转换成字节码并执行,同时会标记热点代码
- TurboFan: 编译器,负责将热点代码编译成机器码并执行
- Orinoco: 垃圾回收器,负责进行内存空间回收
★ V8引擎工作流程
跟我自己讲的ppt里面的webassembly的方案有关系,可以自己参考一下
js代码的执行引擎分为V8和非V8两大类,原则都是按照ECMAscript标准进行实现
js代码执行之前有个编译的过程,这个就是V8的工作流程,V8当做是浏览器的一个组成部分,用来解析编译我们写的js代码
scanner(词法分析) 是一个扫描器
scanner 是一个扫描器,对js代码进行词法的分析,把代码分析成不同的tokenize,也就是得到一个词义的单元(tokenize),是指语法上面没办法再分割的最小单位了,
Parser(解析器)
把词法分析结果的tokenize,去转换成抽象的语法树AST(Abstract Syntax Tree),进行语法校验,有错误就抛出,会得到一个大对象,
- PerParser(预解析)定义的但是没调用,没执行的
- Parser(全量解析)
PerParser(预解析)优点
- 跳过未被使用的代码
- 不生成AST(没有变量声明和队列引用,但是有作用域信息)
- 依据规范抛出特定错误(因为不是全量解析,有的没有解析,所以有的错误抛不出来)
- 解析速度更快(因为做的事情更少一些)
Parser(全量解析)优点
- 跳过被使用的代码
- 生成AST
- 构建具体信息,变量引用、声明等(执行上下文的创建)
- 抛出所有语法错误
函数嵌套太深,会造成多次解析,所以要减少不必要的函数嵌套
Ignition(解释器)
把AST转换成字节码(ByteCode),(可以看做预编译,但是不用区分那么明显)
TurboFan(编译器)
字节码转义成机器码也就是汇编代码,然后就可以开始代码执行了,就是后面分析和理解的堆栈执行过程
总结
浏览器中存在渲染引擎,V8是专门处理js的部分,代码执行前处理很多的步骤,统称为编译的过程,作用域和作用域链在这个编译阶段就已经确定好了,那v8 的基本操作就是 1.词法分析 2.语法分析 3.与解析\全量解析 4.预编译\编译 拿到具体机器码之后就可以执行代码了
js代码-----scanner---->tokenize(最小的词义的单元)
tokenize ----Parser/PerParser---->AST
AST ----Ignition---->ByteCode
ByteCode----TurboFan---->Machine Code
scanner 词法分析 -----------> 词义的单元(tokenize)
Parser/PerParser 解析器-----> AST
Ignition 解释器 -----------> 字节码(Byte Code)
urboFan 编译器 -----------> 机器码(Machine Code)