summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/ion/inlining/getelem-getter-megamorphic.js
blob: 2b8fdddcd01f9713d736d564bdc9e547ce054d19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Test for inlined getters for jsop_getelem accesses, where the getter is a
// property on the prototype and a megamorphic IC is attached.

function makeObjects(name) {
    class Base {
        constructor(v) {
            this._prop = v;
        }
        get [name]() {
            return this._prop;
        }
    }

    // When we hit |TYPE_FLAG_OBJECT_COUNT_LIMIT|, the objects are marked as
    // |TYPE_FLAG_ANYOBJECT|. That means less than |TYPE_FLAG_OBJECT_COUNT_LIMIT|
    // objects need to be created to have no unknown objects in the type set.
    const TYPE_FLAG_OBJECT_COUNT_LIMIT = 7;

    // |ICState::ICState::MaxOptimizedStubs| defines the maximum number of
    // optimized stubs, so as soon as we hit the maximum number, the megamorphic
    // state is entered.
    const ICState_MaxOptimizedStubs = 6;

    // Create enough classes to enter megamorphic state, but not too much to
    // have |TYPE_FLAG_ANYOBJECT| in the TypeSet.
    const OBJECT_COUNT = Math.min(ICState_MaxOptimizedStubs, TYPE_FLAG_OBJECT_COUNT_LIMIT);

    var objects = [];
    for (var i = 0; i < OBJECT_COUNT; ++i) {
        objects.push(new class extends Base {}(1));
    }

    return objects;
}

// Defined outside of the test functions to ensure they're recognised as
// constants in Ion.
var atom = "prop";
var symbol = Symbol();

function testAtom() {
    var objects = makeObjects(atom);

    function f() {
        var actual = 0;
        var expected = 0;
        for (var i = 0; i < 1000; i++) {
            var obj = objects[i % objects.length];
            actual += obj[atom];
            expected += obj._prop;
        }
        assertEq(actual, expected);
    }

    for (var i = 0; i < 2; ++i) {
        f();
    }
}
testAtom();

function testSymbol() {
    var objects = makeObjects(symbol);

    function f() {
        var actual = 0;
        var expected = 0;
        for (var i = 0; i < 1000; i++) {
            var obj = objects[i % objects.length];
            actual += obj[symbol];
            expected += obj._prop;
        }
        assertEq(actual, expected);
    }

    for (var i = 0; i < 2; ++i) {
        f();
    }
}
testSymbol();