V8引擎学习-V8怎么执行JS的

3,671 阅读3分钟

以下是v8引擎的学习总结内容,这里做个学习笔记,方便自查。

V8是什么?

V8是Google开发的开源js引擎,目前用在chrome浏览器和node.js中,用于执行js代码。V8是js虚拟机中的一种,js虚拟机就是把js编程语言翻译成机器语言。市面上比较流行的js引擎,SpiderMonkey,v8,JS core等。

解释执行/编译执行

由于计算机处理器不能直接识别由高级语言所编写的代码,所以需要将这些高级语言编译成机器可执行的代码。

解释执行

解释执行就是将输入的源代码通过解析器编译成中间代码,再使用解释器解释执行中间代码,然后输出结果。流程图如下:

优点是启动速度快,执行速度慢。

编译执行

编译执行就是将输入的源代码通过解析器转换成中间代码,再通过编译器将中间代码编译成机器代码。

可以直接执行编译后的二进制机器代码文件;也可以通过虚拟机将机器代码保存到内存中,再执行内存中的二进制代码。流程图如下:

优点是启动速度慢,执行速度快。缺点是可移植性差。

V8执行JS的过程

JS虚拟机就是模拟计算机的编译执行流程。比较流行的虚拟机有苹果公司Safari的JSCore虚拟机,Firefox的TraceMonkey虚拟机,Chrome的V8虚拟机。

V8率先引入JIT,使用编译执行和混合执行两种手段,引入惰性编译,内联缓存,隐藏类等机制,提升js执行速度。参考下面V8执行JS的流程图。

  • V8启动JS之前,需要准备执行JS需要的基础环境。这些基础环境包括“堆空间”“栈空间”“全局执行上下文”“全局作用域”“消息循环系统”“内置函数”等。
  • V8接收到JS源代码后,结构化JS字符串,生成AST;同时生成相关的作用域。
  • V8基于AST和作用域,生成可执行的字节码。解释器可以直接执行字节码,或者通过编译器将其编译为二进制的机器代码再执行。
  • 解释器执行字节码过程中,如果发现代码被重复执行,监控机器人会把这段代码标记为热点代码。热点代码会丢给优化编译器编译成二进制代码,然后优化。下次再执行时就执行这段优化后的二进制代码。
  • 如果JS对象发生变更,优化后的二进制代码变为无效代码,编译器执行反优化,下次执行就回退到解释器解释执行。

总结

解释执行/编译执行

  • 解释执行启动速度快,执行速度慢。
  • 编译执行启动速度慢,执行速度快。

V8执行JS的流程

V8结合两种策略,在启动过程中采用解释执行,执行过程中采用编译执行来优化使其生成高效的机器代码。V8执行js的主要流程如下:

  • 初始化基础环境
  • 解析源码生成ast和作用域
  • 依据ast和作用域生成字节码
  • 解释器解释执行字节码
  • 监听热点代码
  • 编译器优化热点代码为二进制的机器码
  • 反优化二进制机器代码

参考文档