社区精选|V8 是如何执行 JavaScript 代码的?
今天小编为大家带来的是社区作者 南玖 的文章,让我们一起来了解 V8 是如何执行 JavaScript 代码的。
前言
什么是 V8
JavaScript
代码的。为什么需要编译这一过程?
计算机执行高级语言的基本方式
解释执行
该方式需要先将输入的源代码通过解析器编译成中间代码,之后直接使用解释器解释执行中间代码,然后直接输出结果。
编译执行
采用这种方式时,也需要先将源代码转换为中间代码,然后我们的编译器再将中间代码编译成机器代码。通常编译成的机器代码是以二进制文件形式存储的,需要执行这段程序的时候直接执行二进制文件就可以了。还可以使用虚拟机将编译后的机器代码保存在内存中,然后直接执行内存中的二进制代码。
JavaScript
一门语言,也有好几种流行的虚拟机,它们之间的实现方式也存在着部分差异,比如 Chrome 使用的是 V8 虚拟机,Safari 使用的是 JavaScript Core 虚拟机,而 Firefox 则使用的是 TraceMonkey 虚拟机。V8 是如何执行 JavaScript 代码的?
V8 执行 JavaScript 代码流程图
从这张图的左侧部分我们可以看出,V8 在启动执行 JavaScript 代码之前,它需要初始化好执行环境,这些环境包括:堆空间、栈空间、全局执行上下文、全局作用域、循环系统♻️、内置函数等,这些内容都是在 JavaScript 执行过程中需要使用到的。
在初始化完执行环境后,就可以向 V8 提交需要执行的 JavaScript 代码了。
V8 在接收到 JavaScript 代码后,并不会立即执行,因为 V8 并不能直接理解 JavaScript 代码的含义,这对于它来说只不过就是一段字符串而已。它需要将代码结构化生成抽象语法树(AST),在生成抽象语法树的同时,V8 还会生成相应的作用域。
有了 AST 和作用域后,就可以生成字节码了,字节码是介于 AST 和机器代码之间的中间代码。
生成字节码后,解释器就会按照顺序解释执行字节码,并输出执行结果。
解释器在执行字节码的过程中,如果发现某段代码被多次重复执行,那么这段代码就会被标记成热点代码。
当某段代码被标记成热点代码后,V8 就会将这段代码交给优化编辑器,优化编辑器会在后台将字节码编译为二进制代码,然后再对编译后的二进制代码进行优化操作,优化后的二进制机器代码的执行效率就会大幅提升。
总结
初始化执行环境
解析 JavaScript 代码生成 AST 和作用域
根据 AST 和作用域生成字节码
解释执行字节码
监听热点代码
优化热点代码为二进制的机器代码
优化生成二进制机器代码
往期推荐
面试写:说说执行 JavaScript 的 V8 引擎做了什么?
社区精选|React 的并发悖论
评论