Clearing up the `hidden classes` concept of V8

后端 未结 2 409
野的像风
野的像风 2020-12-29 08:49

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 =         


        
相关标签:
2条回答
  • 2020-12-29 09:34

    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
    
    0 讨论(0)
  • 2020-12-29 09:38

    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

    0 讨论(0)
提交回复
热议问题