专栏首页腾讯IVWEB团队的专栏V8是如何执行JavaScript代码的?

V8是如何执行JavaScript代码的?

编程语言是如何运行的

众所周知,我们通过编程语言完成的程序是通过处理器运行的。但是处理器不能直接理解我们通过高级语言(如C++、Go、JavaScript等)编写的代码,只能理解机器码,所以在执行程序之前,需要经过一系列的步骤,将我们编写的代码翻译成机器语言。这个过程一般是由编译器(Interpreter) 或者解释器(Compiler) 来完成。

那么编译器和解释器的工作流程是怎样的呢?

从上图可以看出它们的大概的工作流程。那么既然编译器和解释器都可以完成代码翻译的工作,为何还同时存在呢?

这是因为编程语言有两个类别:静态类型和动态类型。静态类型的语言,比如C++、Go等,都需要提前编译 (AOT) 成机器码然后执行,这个过程主要使用编译器来完成;而动态语言,比如JavaScript、Python等,只在运行时进行编译执行 (JIT) ,这个过程通过解释器完成。

通过上面的描述,我们已经知道了JavaScript是通过解释器来进行翻译执行的,那么JavaScript引擎V8执行Js代码的详细过程是怎么样的呢?接下来我们详细分析一下。

V8执行Js代码的过程

V8执行Js代码的整体流程如下图所示:

在这个过程中,V8同时使用了Parser(解析器)Ignition(解释器)TurboFan(编译器) 来执行Js代码。

1.Parser生成抽象语法树

在Chrome中开始下载Javascript文件后,Parser就会开始并行在单独的线程上解析代码。这意味着解析可以在下载完成后仅几毫秒内完成,并生成AST。

上图是一段Js代码转成AST后的结构图,从图中可以看出AST是把代码结构化成树状结构表示,这样做是为了更好的让编译器或者解释器理解。此外,AST还广泛应用于各类项目中,比如Babel、ESLint,那么AST的生成过程是怎么样的呢?

1. 词法分析(lexical analysis):主要是将字符流(char stream) 转换成标记流(token stream),字符流就是我们一行一行的代码,token是指语法上不能再分的、最小的单个字符或者字符串。

var name = "ivweb"
//转成token后为

[
    {
        "type": "Keyword",
        "value": "var"
    },
    {
        "type": "Identifier",
        "value": "name"
    },
    {
        "type": "Punctuator",
        "value": "="
    },
    {
        "type": "String",
        "value": "\"ivweb\""
    },
    {
        "type": "Punctuator",
        "value": ";"
    }
]

从上面可以看出,var name = "ivweb"; 这样一段代码,会有关键字"var"、标识符"name"、赋值运算符"="、字符串"ivweb"、分隔符";",共5个token。

2. 语法分析:将前面生成的token流根据语法规则,形成一个有元素层级嵌套的语法规则树,这个树就是AST。在此过程中,如果源代码不符合语法规则,则会终止,并抛出“语法错误”。

2.Ignition生成字节码

字节码是机器码的抽象,可以看作是小型的构建块,这些构建块组合到一起构成任何JavaScript功能。字节码比机器码占用更小的内存,这也是为什么V8使用字节码的一个很重要的原因。字节码不能够直接在处理器上运行,需要通过解释器将其转换为机器码后才能执行。

通过上图可以看出,Ignition把前一步得到的AST通过字节码生成器经过一些列的优化生成字节码。

在这个过程中:

  • Register Optimizer: 主要是避免寄存器不必要的加载和存储;
  • Peephole Optimizer: 寻找直接码中可以复用的部分,并进行合并;
  • Dead-code Elimination: 删除无用的代码,减少字节码的大小

通过上面三个过程的优化进一步减小字节码的大小并提高性能,最后Ignition执行优化后的字节码。

3.执行代码及优化

Ignition执行上一步生成的字节码,并记录代码运行的次数等信息,如果同一段代码执行了很多次,就会被标记为 “HotSpot”(热点代码),然后把这段代码发送给 编译器TurboFan,然后TurboFan把它编译为更高效的机器码储存起来,等到下次再执行到这段代码时,就会用现在的机器码替换原来的字节码进行执行,这样大大提升了代码的执行效率。

另外,当TurboFan判断一段代码不再为热点代码的时候,会执行去优化的过程,把优化的机器码丢掉,然后执行过程回到Ignition。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [译] AssemblyScript简介

    WebAssembly(或者说Wasm)在相对不久前被加入到了Web浏览器标准之中. 而它对于拓展Web平台的能力具有不可小觑的潜力.

    腾讯IVWEB团队
  • 基于ThreeJs Heart animation 动画

    https://bilibiliou.github.io/assets/download/animations/heart-animation.gif

    腾讯IVWEB团队
  • 【译】一种新的 JavaScriptCoere 字节码规范

    在r237547版本我们介绍过一种新的 JavaScriptCore(JSC) 字节码规范。对比之前的规范为了提高编译器的吞吐量而增加了内存使用,这个新的规范提...

    腾讯IVWEB团队
  • C简介

    编译器是把源代码转换成可执行代码的程序。可执行代码是用计算机的机器语言表示的 代码。这种语言由数字码表示的指令组成。如前所述,不同的计算机使用不同的机器语言方案...

    mcxfate
  • PMP之项目质量管理

    管理质量:质量是规划出来的,质量包括产品质量和过程,人人有责,管理层承担85%责任,满意度最重要,质量靠预防和评估

    菲宇
  • 【第011期】如何区分页面上的图片和文字

    在一个网页上,我们会看到有很多的图片,也有很多的文字。对于普通的用户,不需要去在意到底哪些是图片,哪些是文字。

    姬小光
  • 项目管理深入理解03--质量管理

    质量管理一章内容非常驳杂,而且不太好理解,不愧为可以单独成书的一部分内容,尤其其中涉及的质量管理方法非常的多,抓住重点才能学习好这一章节。 ? 项目质量管理实...

    用户1216676
  • 低代码!解锁运维开发新姿势,人人都是OpsDev

    “ 低代码开发模式绝不是一个页面设计工具,而是一种“所见即运行”的应用开发交付新模式。Who Design,Who Build,Who Run!”

    用户1593318
  • 华斧网络科技获SD-WAN峰会“创新应用奖”:企业全球网络新速度

    11月3日,2018中国首届SD-WAN峰会在北京隆重召开。此次会议汇聚了来自政府部门及协会的领导、专家以及领军互联网厂商、运营商、设备厂商、创新企业的资深从业...

    SDNLAB
  • Go是如何实现protobuf的编解码的(1): 原理

    各位朋友咱们又见面了,我是大彬,今天聊一聊Go是如何实现protobuf编解码的。

    大彬

扫码关注云+社区

领取腾讯云代金券