V8有了全新的超快速非优化JS编译器,性能提高5-15%


V8有了全新的超快速非优化JS编译器,性能提高5-15%
本文插图
作者 | V8 团队
译者 | 王强
策划 | 蔡芳芳
V8 引入全新的非优化 JS 编译器 —— Sparkplug
想要编写高性能的 JavaScript 引擎 , 光是有高度优化的编译器(如 TurboFan)是不够的 。 特别是对于短生命周期的会话(例如加载网站或命令行工具) , 在高优化编译器开始优化之前就已经有很多工作要做 , 更没有时间去生成什么优化代码了 。
正因如此 , 自 2016 年起 , 我们不再跟踪综合基准测试(如 Octane)的成绩 , 而是转而去衡量实际场景中的性能表现 。 并且从那时起 , 我们就一直在努力研究如何提升高优化编译器作用范围之外的 JavaScript 性能 。 这意味着我们需要在解析器、流式处理、对象模型、垃圾收集中的并发性、缓存编译后的代码等事项上逐个攻关……每一个领域都有新鲜的感觉 。
当我们转向提升现实场景中初始 JavaScript 的执行性能 , 我们在优化解析器时开始遇到诸多局限 。 V8 的解析器经过高度优化 , 速度极快 , 但解析器总有一些固有开销是我们无法摆脱的;字节码解码开销或调度开销是解析器功能的内在组成部分 。
基于我们目前的双编译器模式 , 我们很难更快地升级(tier-up)到优化代码;我们可以(并且正在)提升优化的效果 , 但在某些时候 , 想要提升速度就只能去掉一些优化项 , 但这会降低峰值性能 。 更糟糕的是 , 我们还无法提前优化进程 , 因为我们还没有稳定的对象形态反馈 。
今天我们向大家介绍 Sparkplug:这是我们将随 V8 v9.1 发布的 , 全新的非优化 JavaScript 编译器 , 位于 Ignition 解析器和 TurboFan 优化编译器之间 。
新的编译器管道
这是一款速度很快的编译器
Sparkplug 的设计目标是快速编译 。 非常快 , 如此之快 , 让我们可以随时随地进行编译 , 于是我们就可以比 TurboFan 代码更积极地升级到 Sparkplug 代码 。
Sparkplug 编译器的速度来自于一些技巧 。 首先 , 它会作弊;它所编译的函数已经被编译为字节码 , 并且字节码编译器已经完成了大多数艰苦的工作 , 例如变量解析、弄清楚括号是否实际上是箭头函数、消除结构化语句等等 。 Sparkplug 从字节码而不是 JavaScript 源代码进行编译 , 因此不必操心这些麻烦的事情 。
第二招是 , Sparkplug 不会像大多数编译器那样生成任何中间表示(IR) 。 相反 , Sparkplug 通过字节码的一次线性 pass 直接编译为机器码 , 并发出与该字节码的执行相匹配的代码 。 实际上 , 整个编译器是一个 for 循环内的一个 switch 语句 , 分派给固定的 , 按字节码的机器码生成函数 。