2.1 V8的编译流水线

77 阅读2分钟

一、v8基础运行环境

v8执行javascript代码的时候需要一些基础环境,如:堆空间、栈空间、消息循环系统、全局上下文和全局作用域等,那么这些是由宿主提供如浏览器或node,v8自身提供核心函数和垃圾回收机制。以下是宿主与v8的关系:

宿主环境和V8的关系.webp

  1. 堆空间和栈空间
    栈空间:提供连续的存储空间,容量小,先进后出;因为地址是固定的,所以查询效率比较高,但不适合修改数据,这会导致数据的位移
    堆空间:树形存储结构,存储离散的引用数据类型,存储空间大
  2. 全局上下文和全局作用域
    全局上下文:
    • 上下文提供词法环境,变量环境,this关键字
    • 存储在堆中,v8初始化后不会被销毁
    • 全局上下文和其他函数上下文会形成栈结构,通过进栈出栈的形式控制函数执行位置
      全局作用域:
    • 作用域是变量和函数所能访问的范围,作用域控制变量和函数的访问性和生命周期
    • 上下文内可以有多个作用域
    • 作用域又分为函数作用域、代码块作用域、文件作用域、原型作用域和全局作用域
  3. 消息循环系统
    循环执行消息队列里面任务的机制,也是V8的核心机制

二、V8如何运行js代码

  1. 混合解析执行和编译执行(JIT)
  2. js代码通过解析器转成抽象语法书AST
  3. v8解析执行会将AST转换成字节码,编译执行会将AST转换成二进制机器码
  4. 通过解释器识别执行字节码;二进制代码则直接被CPU识别执行,执行效率高
  5. 解释器在执行字节码过程中将监控代码,如果代码频繁使用则标记为热点代码,并将其转换成优化后的二进制代码存储,下次运行相同代码会直接运行优化二进制代码
  6. 如果优化后的二进制代码结构或类型被修改,则会触发反优化操作,将优化二进制代码重新转成字节码给解释器执行
    执行流程图如下所示: js在V8执行流程.webp

三、理解v8编译流水线具备知识点

  1. 二进制代码如何在CPU上执行
  2. 堆和栈如何影响内存布局
  3. v8如何通过延迟解析实现闭包
  4. v8为什么映入字节码
  5. 解释器如何解释字节码
  6. 如何通过隐藏类实现快速查找对象属性
  7. v8如何通过内联缓存IC提升函数执行效率