美文网首页
V8 引擎新特性——静态根

V8 引擎新特性——静态根

作者: 涅槃快乐是金 | 来源:发表于2024-06-12 19:34 被阅读0次

你是否曾想过undefinedtrue等核心JavaScript对象是从哪里来的?这些对象是任何用户定义对象的原子,需要首先存在。V8将它们称为不可移动的不可变根,并且它们存在于自己的堆中——只读堆。由于它们被频繁使用,快速访问至关重要。能比在编译时正确猜测它们的内存地址更快的是什么呢?

举个例子,考虑极为常见的IsUndefined API函数。与其需要查找未定义对象的地址以供参考,不如我们简单地检查对象指针是否以0x61结尾,以确定它是否未定义。这正是V8的静态根功能所实现的。本文探讨了我们必须克服的障碍。该功能已在Chrome 111中推出,并带来了整个虚拟机的性能优势,特别是加快了C++代码和内置函数的速度。

引导只读堆

创建只读对象需要一些时间,因此V8在编译时创建它们。要编译V8,首先编译一个名为mksnapshot的最小原型V8二进制文件。该文件会创建所有共享的只读对象,以及内置函数的本地代码,并将它们写入快照。然后,实际的V8二进制文件被编译并与快照捆绑在一起。启动V8时,将快照加载到内存中,我们可以立即开始使用其中的内容。下图显示了独立d8二进制文件的简化构建过程。


一旦d8启动并运行,所有只读对象都在内存中有固定的位置,永远不会移动。当我们进行JIT(即时编译)代码时,例如,我们可以直接通过其地址引用未定义。然而,在构建快照和编译用于libv8C++代码时,地址尚不为人知。它取决于两个在构建时未知的因素。首先,只读堆的二进制布局,其次是只读堆在内存空间中的位置。

如何预测地址?

V8使用指针压缩。我们不使用完整的64位地址,而是通过一个32位偏移量引用内存中4GB区域中的对象。对于许多操作,如属性加载或比较,这个32位偏移量就足以唯一标识一个对象。因此,我们的第二个问题——不知道只读堆在内存空间中的位置——实际上并不是问题。我们只需将只读堆放置在每个指针压缩区域的开头,从而给它一个已知的位置。例如,在V8的堆中,未定义始终具有最小的压缩地址,从0x61字节开始。这就是我们知道如果任何JS对象的完整地址的低32位是0x61,那么它必须是未定义的方式。

这已经很有用了,但我们希望能够在快照和libv8中使用这个地址——这似乎是一个循环的问题。然而,如果我们确保mksnapshot确定性地创建一个位相同的只读堆,那么我们可以在不同版本中重用这些地址。要在libv8中使用它们,我们基本上需要构建两次V8


第一次调用mksnapshot时,生成的唯一产物是一个文件,其中包含了只读堆中每个对象相对于笼子基址的地址。在构建的第二阶段,我们再次编译libv8,并通过一个标志确保每当我们引用未定义时,我们确实使用cage_base + StaticRoot::kUndefined;当然,未定义的静态偏移量是在static-roots.h文件中定义的。在许多情况下,这将允许C++编译器创建libv8和mksnapshot中的内置函数编译器创建更高效的代码,因为替代方案是总是从全局根对象数组中加载地址。我们最终得到的d8二进制文件中,未定义的压缩地址被硬编码为0x61。

嗯,道理上这就是一切的运作方式,但实际上我们只构建一次V8——没人有时间这么做。生成的static-roots.h文件被缓存在源代码仓库中,只有在更改只读堆的布局时才需要重新创建。

进一步的应用

说到实用性,静态根甚至可以实现更多的优化。例如,我们自那时起已经将常见对象分组在一起,从而使我们能够将一些操作实现为对其地址的范围检查。例如,所有字符串映射(即描述不同字符串类型布局的隐藏类元对象)都彼此相邻,因此如果一个对象的映射具有压缩地址在0xdd0x49d之间,那么它就是一个字符串。或者,真值对象必须具有至少为0xc1的地址。

并不是所有关于V8中JIT代码性能的事情。正如这个项目所展示的,对C++代码的相对较小的改变也可能具有重大的影响。例如,Speedometer 2,一个对V8 API进行测试并测试V8与其嵌入器之间交互的基准测试,在M1 CPU上由于静态根而使得分数增加了约1%

相关文章

  • v8 TurboFan带来的优化

    v8 TurboFan带来的优化 Javascript 引擎 V8 即将采用新的引擎: TurboFan & Ig...

  • JDK1.5新特性

    JDK1.5新特性 一、静态导入 静态导入:jdk1.5新特性 格式: 作用范围:一个类的所有静态成员 未使用静态...

  • JavaScript V8引擎

    很多人都知道v8引擎,v8引擎是一种js引擎的实现。在开始介绍v8之前,先搞清JavaScript引擎是什么,这里...

  • Java新特性

    Java5新特性 可变参数 foreach循环 静态导入 引入: 静态导入: Java8新特性 接口定义的增强(可...

  • node.js 学习 (基础知识篇)

    node.js简介 概要:nodejs是一个基于Google V8引擎开发的一个javascript运行环境特性:...

  • Android JS引擎(V8,JSC,Hermes)的使用

    Android端的JS引擎:V8,JSC,Hermes V8和JSC是Android端常见的JS引擎。Hermes...

  • 一.调用栈执行

    1.JavaScript引擎 1.1 V8引擎 1.是什么? 1.一个流行的JavaScript引擎是谷歌的V8引...

  • v8

    - sync-chromium-behind-proxy- V8引擎深入研究目录贴- 初探v8引擎- 新手应该如何...

  • 如何避免内存泄漏 - 2023-02-18

    V8引擎的内存限制 虽然V8引擎帮助我们实现了自动的垃圾回收管理,解放了我们勤劳的双手,但V8引擎中的内存使用也并...

  • Node.js内存管理基础讲解

    Node与V8 基本概念V8是Node的JavaScript执行引擎,V8引擎实际是一个高性能虚拟机。Node在J...

网友评论

      本文标题:V8 引擎新特性——静态根

      本文链接:https://www.haomeiwen.com/subject/yvrnqjtx.html