15

I've read some articles about V8's hidden classes. However, I still have a few questions in my head:

If, let's say, there are two objects:

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

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

Do they end up with the same hidden class or separate just because one went 0 + x + y and the other 0 + y + x? As I understood, they get different classes but just wanna make sure I got it.

Then, we have this case:

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
}

Do we end up with the same hidden class? I might guess that a, b and c do but d doesn't. Unless there is some sorting done on such object expressions (similarly to array's short declaration being analysed for the type).

Finally, we have this:

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)

It is sorta similar to the second case. These objects seem the same except that their origin (instanceof...) is different. However, do there objects end up with the same hidden class?

Seki
  • 11,135
  • 7
  • 46
  • 70
Pijusn
  • 11,025
  • 7
  • 57
  • 76
  • 1
    Javascript does not have classes. The hidden classes are not concept, they are internal detail of the implementation. Unless you want to hack v8 or other virtual machine that needs to solve similar problem, you don't care. – Jan Hudec Jul 24 '13 at 12:49
  • 4
    I actually care about performance of the code I write. I have experienced my self that it's simpler to care about performance *as you go* rather than caring about it when someone complains it runs too slowly. – Pijusn Jul 24 '13 at 12:52
  • There are aspects of performance that you indeed need to care about as you go. Like choosing optimal algorithms, caching data you need often and such. But if you really need to care about performance at this level, you shouldn't be probably using JavaScript in the first place. – Jan Hudec Jul 24 '13 at 12:59
  • 5
    Actually having object properties work like C structs instead of hashmaps is a significant part of what made Javascript 10x-100x faster it is now and enabled lots of new kind of applications that were not possible before in the browser... – Esailija Jul 24 '13 at 13:00
  • 1
    Performance of hidden classe affects code organization so it is a detail to worry about up front. Old javascript style would be to attach properties to objects. You sorta "teach()" an object how to do something new to extend it under the old style. With hidden classes it's probably better to use a proxy if you can. I've even seen some libraries throw a this.userData = {} in their constructors in case I might want to extend their objects without screwing up the hidden class. – Samuel Danielson May 29 '16 at 21:57

2 Answers2

16

If you download V8 and build the debug version you can pass those objects randomly to a function in an infinite loop and have it print the optimized disassembly and see if they were treated as having the same class.

In first case you are right that they will have different hidden classes.


In the second case you are wrong, you will end up with 4 different classes, so none of them share a class.

Firstly, fields that are added to an object outside constructor or object literal, will not be stored directly on the object but in an array external to the object. So that's why b will have different hidden class from everyone.

A unique constructor will construct objects of unique class, so a will have different hidden class from everyone. The object literals have properties in different order which is the same case as in the first case.

However object literals with exactly the same layout will share a hidden class, so if we added object e:

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

Then c would share same hidden class with e.


In third case they will have different hidden classes for the same reason as in the second case, unique constructors construct objects of different classes.


You might also find this interesting https://codereview.stackexchange.com/a/28360/9258

Community
  • 1
  • 1
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • What is the big deal of having **same hidden class**? Could you please explains? – Tony Dinh Aug 04 '14 at 02:06
  • 2
    It is all about performance since the optimizer handles code sites differently depending on what hidden classes need to be supported. If, for example, in a particular line of code, a particular argument always has the same hidden class, the call can be considered monomorphic which allows for [much more aggressive inline caching](http://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching) and other optimization strategies. – Domi Sep 06 '14 at 12:28
8

You can easily check by using V8's debugging shell d8.

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

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

print( %HaveSameMap( a, b ) ); 

Then run

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

You'll get the expected output:

false

For you second example:

//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 ) );

All 4 objects have different hidden classes:

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

And last but not least:

// 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 ) );

a and b have different hidden classes, but b and cthe same.

$ d8 --allow-natives-syntax test3.js
false
true
user835611
  • 2,309
  • 2
  • 21
  • 29