V8内联缓存如何与删除和计算属性访问一起工作? [英] How does V8 inline caching work with delete and computed property access?

查看:40
本文介绍了V8内联缓存如何与删除和计算属性访问一起工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

https://github.com/v8/v8/wiki/Design%20Elements#fast-property-access中所示,我试图理解对象的属性是基于其构造函数的隐藏类(称为"C[N]")存储的。我可能没有正确地理解它。例如:

// Let's suppose Object has these hidden classes already

/* Object[[HiddenClasses]] > C0, C1, C2
 *
 * C0 - for "x", goto C1
 * C1 - "x"; for "y", goto C2
 * C2 - "x", "y";
 */

var obj = {
    x: 0
};
// Currently based in C1 to get/put properties

obj.y = 0;
// Now based in C2

1.如果此新对象添加新属性,会发生什么情况?

obj.z = 0

它的行为是否仍与Object的第一个实例相同?

2.如果同一构造函数的对象以与隐藏类相反的顺序添加属性,会发生什么情况?

({ y: 5; }); // Will this be based in C2?

3.如果删除属性,会发生什么情况?其值是否仅在内存中更改以表示deleted

4.当编译器无法看到其计算属性访问的对象或名称时,是否在隐藏类中进行查找?即:

({ [Math.random()]: 0 }),
randomlyReceivedObject.property;

推荐答案

  1. obj.z = 0之后,C2获取新的转换for "z", goto C3,并为该对象创建新的隐藏类C3 - "x", "y", "z"

  2. 该对象将有一个新隐藏类。和C0获得新的转换:for "y", goto C4。如果该对象稍后获得"x"属性,则将创建一个新隐藏类C5 - "y", "x",并在C4for "x", goto C5中进行转换。C5C2将永远保持不同。这实际上是由JavaScript规范规定的,因为例如一个for..in循环Object.getOwnPropertyKeys必须按照创建顺序迭代属性,而V8通过隐藏类跟踪属性创建顺序。 由于拥有更多隐藏类自然会有速度和内存成本,因此通常建议始终以相同的顺序创建属性(例如,通过使用构造函数)。

    /li>
  3. 删除属性时,对象将进入字典模式,并且不再使用隐藏类来跟踪其属性。在内部,这是通过一个特殊的隐藏类实现的:C6 - all properties are in the properties dictionary。然后,每个后续的属性访问都需要查找字典。如果您想避免这种情况,您可以手动覆盖属性,而不是删除它们:obj.x = null或类似的。(详细说明:在最新的V8版本中,有一个例外,如果删除了last属性,则回滚最后一个隐藏的类转换。此实现细节在未来可能会保留,也可能不会保留,因此不要依赖它。)

  4. 隐藏类始终用于查找。内联缓存只是缓存这些查找的结果;这总是在执行时发生,而不是在编译时。"编译器"通常无法"看到"对象,因为在编译时还没有对象。

这篇关于V8内联缓存如何与删除和计算属性访问一起工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆