JS引擎的工作原理
JS引擎的工作原理基本上差不多,大致流程为:
- 将JS解析为AST(抽象语法树)。
- 基于AST(抽象语法树),解释器(interpreter)/
- 将AST(抽象语法树)转化为字节码(bytecode),实际上在这一步已经在执行JS代码了。
- 为了进一步优化,优化编译器(optimizing compiler)将热点函数优化编译为机器指令(machine code)执行。
- 如果优化失败,优化编译器会将机器码回退到字节码。
各大浏览器JS引擎对比
其实JS引擎的工作大致可以看成如下:
- 解释器负责快速生成没有优化过的字节码
- 优化编译器负责生成优化过后的机器码但是相对于来说花的时间会长一些。
不同的JS引擎的优化策略和过程会有所不同。
浏览器的基本架构都是parser -> interpreter -> compiler。不同之处在于有的只有一个优化编译器,而有的有多个优化编译器,这么做也只是为了权衡利弊。
解释器可以快速生成可执行代码,但是效率不高。编译器需要多花些时间来做编译优化,但是最后省的是有高效执行的机器码。
所以这里需要权衡到底是要 快速执行 还是要 多花些时间生成高效可执行的机器码。引入多个具有不同时间/效率特性的优化编译器来增加复杂性为代价,就是为了这些权衡更细粒度的控制。这中间还涉及到内存的权衡,机器码比字节码占更多的内存。
其实相对于代码而言也就是生成的快跑的慢,生成的慢跑的快的问题
V8引擎工作流程详解
解析过程实际上分为两步:扫描器( scanner ) 做词法分析,语法分析器( parser ) 做语法分析
词法分析
我们编写的代码其实就是字符串,词法分析其实就是将我们编写的这些字符串转为token列表,所谓token列表就是将我们编写的字符串中的每一个单词判断为是什么类型,以及单词的名字。
语法分析
语法分析的输入就是词法分析的输出,输出的是AST抽象语法树,AST表示token关系的一棵树,它是源码语法结构的一种抽象表示,它以树状的形式表现语法结构,树上的每个节点都表示代码的一种结构。
解释器(Ingition)
根据AST来生成字节码,这一步由解释器来做。同时解释器也会执行字节码。在这个过程中,如果一个函数被调用多次,这个函数就会被标记为热点函数,并将该函数的字节码以及相关信息发送给TurboFan进行优化处理。