Reputation: 4643
When I look into the v8 design elements of fast property access, it mentions this point in the last paragraph for this topic:
There are two advantages to using hidden classes: property access does not require a dictionary lookup, and they enable V8 to use the classic class-based optimization, inline caching.
This is a bit vague for me. Can anyone elaborate this on why hidden class does not require a dictionary lookup and enable v8 to use the classic class-based optimization, inline-caching?
Please do this as detail as possible.
Upvotes: 3
Views: 1298
Reputation: 11596
I think the idea of hidden-classes is well explained in the article you referred. Whenever a new property is added to an object a new hidden-class is created. The object keeps a reference to this hidden-class. In addition, the hidden-class also keeps a reference to the previously created hidden-class. For instance:
function Point(x, y) {
this.x = x;
this.y = y;
}
var point = new Point(10, 10);
When new Point()
is called a new hidden-class is created, and point
keeps a reference to that hidden-class. That initial hidden-class is empty, that means, it contains no properties. Then, when this.x
is called, a new hidden-class is created. That hidden class keeps a reference to the previous hidden class, and point updates its reference to that new hidden-class. The same happens again when this.y = y
is executed.
As in JavaScript is possible to add and delete properties to an object dinamically, the way to resolve property access is by using a map. On the other hand, hidden-classes store properties linearly, one after another, like an struct in C. Thanks to hidden-classes, accessing a property is as fast as accessing an array's element.
Now let's take a look at what inline caching means. Inline caching is an old optimization technique, used in dynamic languages such as Smalltak 80 or Self and popularized by JavaScript. When a property is accessed at runtime, it is necessary to determine the type of the calling object in order to know exactly what implementation code to call. That is called dynamic dispatch or late binding, and is what happens in JavaScript when accessing a property or when summing up two operands (they could be integer, double, etc). Consider the following code:
var x = 10;
var y = 10;
var total = x + y;
When using inline caching, when var total = x + y
is compiled, you don't compile in a procedure call to a generic addition subroutine. Instead, that code is compiled to a stub (the inline cache). The code generated in the inline cache takes a look at the types of the parameters received and generates code specialized for those types. Later, if another addition is called, the inline cache is executed assuming that the types will be the same as before. It could happen that the types were different though, thus the first thing an inline cache does is to check the types of the parameters. If the types are different that results into a cache miss, and new code is generated for those specific types. If the inline cache can handle many different types that is called a polymorphic inline cache (one with entries for more than one set of types).
Inline caching saves the computation of inferring the parameter types in a function call and their benefit is bigger if the call happens inside a loop for instance.
Inline caching happens in JavaScript while accessing the property of an object, and before we saw how hidden-classes can help us to have quick property access.
For more information about hidden-classes and inline-caches I recommend the following articles (specially the first two, from V8 hacker Vyacheslav Egorov):
Upvotes: 4