为什么 V8 使用指针标记而不是 NaN 装箱?

Cha*_*man 3 optimization pointers v8 javascript-engine nan-boxing

我现在正在学习 V8 内部结构。我了解到 V8 使用指针标记来存储值,但想知道为什么不使用 NaN 装箱。

AFAIK,NaN 拳击更好,因为它也可以存储双打而不仅仅是 SMI。我已经阅读了这篇文章,并且理解(如果这是真的)为什么不在 32 位平台上使用 NaN 装箱。但是在 64 位平台上我不明白为什么。

我怀疑原因与 SMI 有关。也许它们不能使用 NaN 装箱存储?我认为他们可以。我们有 52 个多余的位(我们甚至可以使用超过 32 位)。也许这将需要额外的屏蔽操作,这会使整数数学运算变慢?但是我们已经需要做按位移位了!

我不知道为什么。感谢任何愿意回答的人。

jmr*_*mrk 5

(此处为 V8 开发人员。)NaN 装箱和指针标记是具有不同权衡的设计选择,严格来说两者都没有比另一个更好。V8 使用指针标记的决定早在我加入该项目之前就已经做出,所以我只能推测当时的具体原因可能是什么。

指针标记的优点是:

  • 显着减少内存消耗(当然在 32 位平台上;在 64 位平台上也有“指针压缩”)
  • 稍微更高效(小)整数运算,因为大多数 CPU 的整数运算比它们的双运算快。一旦优化编译器进入画面,这可能根本无关紧要。
  • 稍微更高效的指针操作,因为您可以在访问对象字段时简单地添加调整后的偏移量(这与根本不玩任何指针技巧的性能相同),而不是必须屏蔽 NaN 的不相关部分。一旦优化编译器进入画面,这可能根本无关紧要。

正如您所指出的,NaN 标记的主要好处是它支持完整的双倍范围,这在某些情况下非常好。您可以基于任一技术构建性能良好的引擎。