简单介绍V8引擎

V8引擎

Chrome V8引擎JavaScript引擎的一种实现,最初由一些语言方面专家设计,后被谷歌收购,随后谷歌对其进行了开源

何为JavaScript引擎?

JavaScript引擎是执行JS代码的程序或解释器。JavaScript引擎可以实现为标准解释器或即时编译器,它以某种形式将JS编译为字节码。

V8使用C++开发,在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能

有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。

V8支持众多操作系统,如windowslinuxandroid等,也支持其他硬件架构,如IA32,X64,ARM等,具有很好的可移植跨平台特性

除了V8引擎,还有这些JS引擎:

  • SpiderMonkey - 第一个JavaScript引擎,Netscape Navigator,Firefox

  • JavaScriptCore - 苹果公司为Safari开发

  • Rhin - 由Mozilla基金会开源,完全用Java开发

  • Chakra (JavaScript) - Microsoft IE9-IE11、Microsoft Edge

  • JerryScript - 一个物联网的轻量级引擎

  • Nashorn - 作为OpenJDK的一部分,由Oracle Java语言和工具组编写

V8引擎的工作原理

V8引擎的工作原理

V8的四个重要子模块

V8由许多子模块构成,其中这4个模块是最重要的:

  • Parser:负责将JS源码转换为Abstract Syntax Tree(AST)(抽象语法树)
    • 如果函数没有被调用,那么就不会被转换为AST
  • IgnitionInterpreter(解释器),负责将AST转换为Bytecode,解释执行Bytecode;同时收集TurboFan优化编译所需的信息:比如函数参数的类型,因为有了类型才能进行真实的运算
    • 如果函数只调用一次,Ignition会解释执行ByteCode

补充知识:

通常虚拟机有两种类型:基于栈(Stack-based)基于寄存器(Register-based)

基于栈的虚拟机使用栈保存函数参数、中间运算结果、变量等;基于寄存器的虚拟机使用寄存器保存参数、中间计算结果,支持寄存器的指令操作。

通常,基于栈的虚拟机也定义了少量的寄存器,基于寄存器的虚拟机也有堆栈,其区别体现在它们提供的指令集体系结构(ISA , Instruction Set Architecture)不同。

大多数解释器是基于栈的,比如Java虚拟机.Net虚拟机,还有早期的V8虚拟机。基于堆栈的虚拟机在处理函数调用、解决递归问题和切换上下文时,更加简单明快。

现在的V8虚拟机,则采用了基于寄存器的设计,它将一些中间数据保存到寄存器中。

下图为基于寄存器的解释器架构:

基于寄存器的解释器架构

  • TurboFanCompiler(编译器),负责利用Ignition所收集的类型信息,将Bytecode转换为优化后的汇编代码

    • 如果一个函数被多次调用,那么就会被标记为热点函数,那么就会经过TurboFan转换成优化的机器码,提高代码的执行性能
    • 机器码实际上也会被还原为ByteCode,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执行的是number类型,后来执行变成了string类型),之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码
  • OrinocoGarbage Collector(垃圾回收模块),负责将程序不再需要的内存空间回收

参考资料

万字干货!详解JavaScript执行过程