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

Why does V8 uses pointer tagging and not NaN boxing?

我现在正在学习 V8 的内部结构。我了解到 V8 使用 pointer tagging 进行值存储,但想知道为什么它不使用 NaN 装箱。

A​​FAIK,NaN 拳击更好,因为它还可以存储双打而不仅仅是 SMI。我已阅读 this,并理解(如果那是真的)为什么不在 32 位平台上使用 NaN 装箱。但是在 64 位平台上我不明白为什么。

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

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

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

指针标记的优点是:

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

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