清理V8的“隐藏类”概念

时间:2013-07-24 12:28:08

标签: optimization v8 vm-implementation

我读过一些关于V8隐藏类的文章。但是,我脑子里还有几个问题:

如果,假设有两个对象:

var a = { }
a.x = 5
a.y = 6

var b = { }
b.y = 7
b.x = 8

他们最终会使用相同的隐藏课程,还是因为一个人去了0 + x + y而另一个0 + y + x?据我所知,他们会得到不同的课程但只是想确保我得到它。

然后,我们有这个案例:

function Point(x, y) {
    this.x = x
    this.y = y
}
var a = new Point(7, 8)

var b = { }
b.x = 6
b.y = 8

var c = {
    x: 8,
    y: 9
}

var d = {
    y: 9,
    x: 80
}

我们最终会使用相同的隐藏类吗?我猜可能会abc,但d却没有。除非对这些对象表达式进行了一些排序(类似于为类型分析数组的简短声明)。

最后,我们有了这个:

function PointA(x, y) {
    this.x = x
    this.y = y
}
var a = new PointA(7, 8)

function PointB(x, y) {
    this.x = x
    this.y = y
}
var b = new PointB(7, 8)

与第二种情况类似。除了它们的原点(instanceof...)不同之外,这些对象看起来是一样的。但是,那些对象最终会使用相同的隐藏类吗?

2 个答案:

答案 0 :(得分:15)

如果您下载V8并构建调试版本,则可以将这些对象随机传递给无限的函数 循环并让它打印优化的反汇编,看看它们是否被视为具有相同的类。

在第一种情况下,你是对的,他们会有不同的隐藏类。


在第二种情况下,你错了,你最终会得到4个不同的类,所以没有一个人共享一个类。

首先,添加到构造函数或对象文字外部的对象的字段不会直接存储 在对象上,但在对象外部的数组中。这就是为什么b将拥有与所有人不同的隐藏类。

唯一的构造函数将构造唯一类的对象,因此a将拥有与每个人不同的隐藏类。物体 文字具有不同顺序的属性,与第一种情况的情况相同。

然而,具有完全相同布局的对象文字将共享一个隐藏类,因此如果我们添加了对象e

var e = {
    x: 32,
    y: -15
};

然后c会与e分享相同的隐藏课程。


在第三种情况下,它们将具有不同的隐藏类,其原因与第二种情况中的唯一构造函数相同 构建不同类的对象。


您可能还会发现这个有趣的https://codereview.stackexchange.com/a/28360/9258

答案 1 :(得分:7)

您可以使用V8的调试shell d8轻松检查。

// test1.js
var a = { }
a.x = 5
a.y = 6

var b = { }
b.y = 7
b.x = 8

print( %HaveSameMap( a, b ) ); 

然后运行

$ d8 --allow-natives-syntax test1.js

您将获得预期的输出:

false

对于你的第二个例子:

//test2.js
function Point(x, y) {
    this.x = x
    this.y = y
}

var a = new Point(7, 8)

var b = { }
b.x = 6
b.y = 8

var c = {
    x: 8,
    y: 9
}

var d = {
    y: 9,
    x: 80
}

print( %HaveSameMap( a, b ) );
print( %HaveSameMap( b, c ) );
print( %HaveSameMap( b, d ) );
print( %HaveSameMap( c, d ) );

所有4个对象都有不同的隐藏类:

$ d8 --allow-natives-syntax test2.js
false
false
false
false

最后但并非最不重要:

// test3.js
function PointA(x, y) {
    this.x = x
    this.y = y
}
var a = new PointA(7, 8)

function PointB(x, y) {
    this.x = x
    this.y = y
}
var b = new PointB(7, 8)
var c = new PointB(1,4)

print( %HaveSameMap( a, b ) );
print( %HaveSameMap( b, c ) );

ab有不同的隐藏类,但bc相同。

$ d8 --allow-natives-syntax test3.js
false
true