了解V8引擎如何运行JS

前言

今天看了一个视频,关于V8引擎是如何运行JS的。我将视频中主要的知识点记下来,一来加深记忆,二来方便复习

什么是V8

V8是使用C++编写的Google开源高性能JavaScriptWebAssembly引擎。V8第一个版本随着第一个版本的Chrome200892日发布

哪些程序用到V8
  1. Chrome浏览器的JS引擎是V8
  2. Nodejs的运行时环境是V8
  3. electron的底层引擎是V8
V8主要职责

简单来说,V8是一个接收JavaScript代码,编译代码然后执行C++程序,编译后的代码可以在多种操作系统多种处理器上运行。其主要职责:

  1. 编译和执行JS代码
  2. 处理调用栈
  3. 内存分配
  4. 垃圾回收
了解V8引擎如何运行JS_第1张图片

V8如何编译和执行JS代码

一般来说,JS引擎在编译和执行代码都会用到三个重要的组件,分别:

了解V8引擎如何运行JS_第2张图片
  • 解析器 --> 负责将JS源代码解析成抽象语法树AST
了解V8引擎如何运行JS_第3张图片
  • 解释器 --> 负责将AST解析成字节码bytecode,同时解释器也有解释执行bytecode的能力
了解V8引擎如何运行JS_第4张图片
  • 编译器 --> 负责编译出运行更加高效的机器代码
了解V8引擎如何运行JS_第5张图片

但是在V8早期,在5.9版本以前,是没有解释器,但有两个编译器,其编译流程如下

  1. parser 解释器生成抽象语法树AST
  2. compiler 编译器Full-codegen 基准编译器 直接生成机器码
  3. 运行一段时间后,由分析器线程优化js代码
  4. compiler 编译器CrankShaft 优化编译器 重新生成AST提升运行效率
了解V8引擎如何运行JS_第6张图片

这样设计的缺点

  1. 机器码会占用大量的内存
  2. 缺少中间层机器码,无法实现一些优化策略
  3. 无法很好的支持和优化JS的新语特性,无法拥抱未来

正因为存在以上问题,V8团队用了三年半的时间,开发了一套新的V8架构

新版本的V8
  1. parser 解析器 生成AST抽象语法树
  2. interpreter 解释器 Ignition 生成byteCode字节码 并直接执行
  3. 清除AST释放内存空间
  4. 得到25% - 50%的等效机器代码大小
  5. compiler 运行过程中,解释器收集优化信息发送给编译器TurboFan
  6. 重新生成机器码
  7. 有些热点函数变更会由优化后的机器码还原成字节码 也就是deoptimization 回退字节码操作执行
了解V8引擎如何运行JS_第7张图片

优化点:

  1. 值声明未调用,不会被解析生成AST
  2. 函数只被调用一次,bytcode直接被解释执行,不会进入到编译优化阶段
  3. 函数被调用多次,Igniton会收集函数类型信息,可能会被标记为热点函数,可能被编译成优化后的机器代码

好处:

  1. 由于一开始不需要直接编译成机器码,生成了中间层的字节码,从而节约了时间
  2. 优化编译阶段,不需要从源码重新解析,直接通过字节码进行优化,也可以deoptimization回退操作

如:

function sum(x,y){return x + y};
sum(1,2);
sum(3,4);
sum(5,6);
sum("7","8");//会回退字节码操作执行

以上就是V8引擎如何运行JS相关内容

原视频:https://www.bilibili.com/video/BV1zV411z7RX
作者:luke
个人推荐多看两遍

你可能感兴趣的:(了解V8引擎如何运行JS)