JavaScript v8引擎

137 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

为什么需要js引擎?

因为javascript代码最终都需要由CPU来执行,但是javascript作为一项高级编程语言,是不能直接被CPU所理解执行的。CPU只识别CPU指令,或者说是机器语言。所以就需要浏览器引擎来将javascript代码转换为CPU能够理解的CPU指令。

V8引擎的原理

V8引擎是由C++编写的。主要有三大块构成,Parse模块,Ignition解释器,TurboFan编译器。其中parse模块用于将javasccript代码转换为AST(抽象语法树),Ignition用于将AST转换为字节码,Turbofun用于将字节码转换为对应运行环境下的机器码。

parse模块

parse模块通过词法分析和语法分析将javascript代码转换为AST。

词法分析

词法分析用于确定各个单词的词性。它会从左到右逐行扫描源程序的字符,识别出各个单词,确定单词的类型,并转换为统一的token表示,{type='',value=''},并将其放在一个token数组中。比如下方代码:

const name="echo"

词法阶段从左到右扫描,首先扫描到const字符。const是一个关键字,因此它的type是'keyword',因此得到的表示是{type='keyword',value='const'}。然后扫描到name,再是"=",最后是"echo"。

image.png 扫描完这一行代码得到的token序列为

token:[{type='keyword',value='const'},{type='identifier',value='name'},{type='assignment',value='='},{type='Literal',value='echo'}]
语法分析

语法分析是将上一步生成的token数据,根据语法规则转为AST。如果源码符合语法规则,这一步就会顺利完成,但如果源码存在错误,这一步就会终止并抛出一个"语法错误"。

Ignition解释器

得到AST后,V8就会生成该段代码的执行上下文,有了AST和执行上下文,接下来就需要解释器上场将AST转换生成字节码。

为什么需要生成字节码

原本V8引擎是直接将AST转换为机器码的,但是机器码是很消耗内存的。并且字节码是跨平台的,机器码不同环境下的可能不相同。所以后来引入了字节码。字节码是介于AST和机器码之间的一种代码,字节码需要通过Ignition解释器将其转换为机器码后才能执行。

turboFan编译器

如果有一段第一次执行的字节码,解释器Ignition会逐条对其进行解释执行,当解释器执行解释字节码的时候会同时收集代码信息,当发现其中的热点代码时(热点代码:被多次重复执行的代码),那么后台的TurboFan编译器就会将热点代码编译为高效的机器码,当再次执行这段代码时,就会执行编译后的机器码了。机器码的执行效率是很高的。就可以提升代码的执行效率了。这也就是为什么会说"V8执行时间越久,执行效率越高"。因为执行时间越久的话就会有越多的热点代码被编译为机器码。