正在看这个V8设计文档 https://docs.google.com/document/d/11T2CRex9hXxoJwbYqVQ32yIPMh0uouUZLdyrtmMoL44/edit#其中有一个部分用于Constant Pool Entries
it says
常量池用于存储堆对象和小整数,这些对象和小整数在生成的字节码中作为常量引用。
和
...小整数和强引用的奇怪类型有字节码可以直接加载它们并执行not进入常量池。
所以我很困惑:小整数是否被合并?
我的理解是,如果以下情况,则不值得汇集小整数:sizeof(int) < sizeof(int *)
- 因为只复制实际整数而不是复制指向常量池中整数的指针更便宜。此外,保存整数的变量可以优化为直接存储在 CPU 寄存器中,并跳过首先在内存中分配。
另外,它们位于 V8 堆还是堆栈上?我的理解一直是 smis 只是在堆栈上分配的立即值,而不是在堆上分配的指针+整数。另外,如果您使用 chrome devtool 拍摄堆快照,则在堆快照中找不到 smis - 只有堆编号(例如大整数或双精度(如 3.14))位于堆上,直到我看到这篇文章https://v8.dev/blog/pointer-compression#value-tagging-in-v8 https://v8.dev/blog/pointer-compression#value-tagging-in-v8
V8 中的 JavaScript 值都表示为对象并分配在 V8 堆上,无论它们是对象、数组、数字还是字符串。这允许我们将任何值表示为指向对象的指针。
现在我很困惑 - smis 也分配在堆上吗?
V8 开发者在这里。
小整数是否被合并?
他们不是(至少现在不是)。也就是说,这是一个很小的实现细节,可以通过任何一种方式完成:完全可以使用 Smis 的常量池。我想,之所以做出为 Smis 构建特殊机制(而不是重用通用常量池)的决定,是因为事实证明,这样会更高效。
如果以下情况,则不值得汇集小整数sizeof(int) < sizeof(int *)
细节不同(Smi 不是int
,并且常量池槽是通过索引而不是 C++ 指针引用的),但这种推理确实朝着正确的方向发展:避免间接可以节省时间和内存。
smis 也分配在堆上吗?
是的,所有内容都分配在堆上。堆栈仅对临时(且足够小的)事物有用;这很大程度上与事物的类型无关。
Smis 的“技巧”是它们不存储为separate对象:当你有一个引用 Smi 的对象时,例如let foo = {smi: 42}
,那么值42
可以进行smi编码并直接存储inside“foo”对象(而如果该值是42.5
,那么该对象将存储一个指向单独的“HeapNumber”的指针)。但由于对象在堆上,Smi 也在堆上。
@丹尼尔克鲁兹
我的理解是,恒定的小整数被汇集起来。可变的小整数则不然。
没有。源代码中出现的任何文字都是“常量”。无论你使用let
or const
因为你的变量与此无关。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)