JavaScript: V8 问题:小整数是否合并?
JavaScript: V8 question: are small integers pooled?
正在查看此 V8 design doc,其中有一个部分用于 Constant Pool Entries
它说
Constant pools are used to store heap objects and small integers that are referenced as constants in generated bytecode.
and
... Small integers and the strong referenced oddball type’s have bytecodes to load them directly and do not go into the constant pool.
所以我很困惑:是否合并了小整数?
我的理解是 sizeof(int) < sizeof(int *)
不值得将小整数集中在一起 - 因为只复制实际整数而不是复制指向常量池中整数的指针更便宜。保存整数的变量也可以优化为直接存储在 CPU 寄存器中,而不是先在内存中分配。
还有,它们是在V8堆上还是在栈上?我的理解一直是 smis 只是在堆栈上分配的立即值,而不是在堆上分配的指针 + 整数。此外,如果您使用 chrome devtool 拍摄堆快照,您无法在堆快照中找到 smis - 在我看到这篇文章 https://v8.dev/blog/pointer-compression#value-tagging-in-v8[= 之前,堆上只有堆编号,例如大整数或双精度 3.14 18=]
JavaScript values in V8 are represented as objects and allocated on the V8 heap, no matter if they are objects, arrays, numbers or strings. This allows us to represent any value as a pointer to an object.
现在我很困惑 - smis 是否也分配在堆上?
这里是 V8 开发人员。
are small integers pooled or not?
他们不是(至少现在不是)。也就是说,这是一个小的实现细节,可以通过任何一种方式完成:完全可以为 Smis 使用常量池。我想决定为 Smis 构建特殊机器(而不是重用通用常量池)是因为事实证明那样效率更高。
it is not worth it pooling small integers if sizeof(int) < sizeof(int *)
细节有所不同(Smi 不是 int
,并且常量池槽是通过索引而不是 C++ 指针引用的),但是这个推理确实朝着正确的方向发展:避免间接可以节省时间和记忆。
are smis also allocated on the heap?
是的,一切都分配在堆上。堆栈仅对临时(并且足够小)的东西有用;这在很大程度上与事物的类型无关。
Smis 的“技巧”是它们不会存储为 单独的 对象:当您有一个引用 Smi 的对象时,例如 let foo = {smi: 42}
,那么值 42
可以被 smi 编码并直接存储在 内部 “foo” 对象(而如果值是 42.5
,那么对象将存储指向单独的“HeapNumber”)的指针。但是因为对象在堆上,所以Smi也是。
@DanielCruz
What I understand [...] is that constant small integers are pooled. Variable small integers are not.
没有。源代码中出现的任何文字都是“常量”。无论您使用 let
还是 const
作为变量都与此无关。
正在查看此 V8 design doc,其中有一个部分用于 Constant Pool Entries
它说
Constant pools are used to store heap objects and small integers that are referenced as constants in generated bytecode. and
... Small integers and the strong referenced oddball type’s have bytecodes to load them directly and do not go into the constant pool.
所以我很困惑:是否合并了小整数?
我的理解是 sizeof(int) < sizeof(int *)
不值得将小整数集中在一起 - 因为只复制实际整数而不是复制指向常量池中整数的指针更便宜。保存整数的变量也可以优化为直接存储在 CPU 寄存器中,而不是先在内存中分配。
还有,它们是在V8堆上还是在栈上?我的理解一直是 smis 只是在堆栈上分配的立即值,而不是在堆上分配的指针 + 整数。此外,如果您使用 chrome devtool 拍摄堆快照,您无法在堆快照中找到 smis - 在我看到这篇文章 https://v8.dev/blog/pointer-compression#value-tagging-in-v8[= 之前,堆上只有堆编号,例如大整数或双精度 3.14 18=]
JavaScript values in V8 are represented as objects and allocated on the V8 heap, no matter if they are objects, arrays, numbers or strings. This allows us to represent any value as a pointer to an object.
现在我很困惑 - smis 是否也分配在堆上?
这里是 V8 开发人员。
are small integers pooled or not?
他们不是(至少现在不是)。也就是说,这是一个小的实现细节,可以通过任何一种方式完成:完全可以为 Smis 使用常量池。我想决定为 Smis 构建特殊机器(而不是重用通用常量池)是因为事实证明那样效率更高。
it is not worth it pooling small integers if
sizeof(int) < sizeof(int *)
细节有所不同(Smi 不是 int
,并且常量池槽是通过索引而不是 C++ 指针引用的),但是这个推理确实朝着正确的方向发展:避免间接可以节省时间和记忆。
are smis also allocated on the heap?
是的,一切都分配在堆上。堆栈仅对临时(并且足够小)的东西有用;这在很大程度上与事物的类型无关。
Smis 的“技巧”是它们不会存储为 单独的 对象:当您有一个引用 Smi 的对象时,例如 let foo = {smi: 42}
,那么值 42
可以被 smi 编码并直接存储在 内部 “foo” 对象(而如果值是 42.5
,那么对象将存储指向单独的“HeapNumber”)的指针。但是因为对象在堆上,所以Smi也是。
@DanielCruz
What I understand [...] is that constant small integers are pooled. Variable small integers are not.
没有。源代码中出现的任何文字都是“常量”。无论您使用 let
还是 const
作为变量都与此无关。