以下是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和作用域生成字节码
- 解释器解释执行字节码
- 监听热点代码
- 编译器优化热点代码为二进制的机器码
- 反优化二进制机器代码