这篇博客文章介绍了 V8 引擎中针对 WebAssembly 的两项优化,即推测性 call_indirect 内联和 WebAssembly 的反优化支持,它们随 Google Chrome M137 一起发布。
- 背景:JavaScript 的快速执行依赖于推测性优化,即 JIT 编译器在生成机器码时根据早期执行收集的反馈进行假设。而 WebAssembly 程序由于静态信息较多,无需推测性优化和反优化。但随着 WasmGC 的引入,WebAssembly 程序的编译需要更多的推测性优化。
- 动机:WasmGC 引入后,需要更多的推测性优化来提高 WebAssembly 的执行速度。其中一个重要的优化是内联,即替换调用指令为被调用函数的主体。但间接调用使得内联变得复杂,推测性内联可以在执行未优化代码时记录目标,在生成优化代码时内联目标函数。
- 推测性内联:理论上间接调用可以指向多个函数,但实际上通常指向单个或少数几个函数。在执行未优化代码时记录目标,在生成优化代码时内联最多四个目标函数。通过推测性内联,可以在生成的优化代码中避免间接调用,进行后续的优化,如常量传播和常量折叠等。
- 技术深入探讨:反馈向量用于记录调用目标和计数,每个条目可以经历四个阶段:未初始化、单态、多态和巨态。在实现中,更新反馈条目的内置函数是用 Torque 编写的。通过一个简单的 WebAssembly 程序示例,展示了推测性内联对程序执行时间和代码大小的影响。此外,还解释了 WebAssembly 实例检查和目标检查的原因和实现方式。
- 反优化:如果优化过程中的假设在运行时被证明是错误的,就会发生反优化。反优化的过程包括保存当前程序状态、将状态转换为适合未优化代码的形式、替换优化的栈帧并跳转到未优化代码的中间。反优化可以避免在优化代码中处理通用的慢路径,从而提高程序的执行速度。
- 结果:通过 Dart 微基准测试和实际应用程序的测试,展示了 call_indirect 内联和 Wasm 反优化支持的有用性。在 Dart 微基准测试中,call_indirect 内联平均加速 1.19 倍,结合反优化支持平均加速 1.59 倍。在实际应用程序中,也有不同程度的加速。
- 结论和展望:总结了两项优化的作用,展望了未来基于 WebAssembly 反优化支持添加更多推测性优化的计划,以及在内联方面的进一步工作。
总的来说,这两项优化显著提高了 WebAssembly 的执行效率,未来还有更多的优化工作可以期待。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。