summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/profiler/interpreter-stacks.js
blob: 737a8fce181ed672934958a94f60c48d88bb80c0 (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// |jit-test| --no-blinterp
// Disable Baseline Interpreter and JITs because we only read information about
// C++ Interpreter profiling frames.

enableGeckoProfilingWithSlowAssertions();

function assertStack(stack, expected) {
    assertEq(stack.length, expected.length);
    for (let i = 0; i < stack.length; i++) {
        // Use |split| to get rid of the file name.
        assertEq(stack[i].dynamicString.split(" (")[0], expected[i]);
    }
}

// We currently don't push entries for frames that were already on the stack
// when the profiler was enabled.
assertStack(readGeckoInterpProfilingStack(), []);

function testBasic() {
    let g1 = function() {
        return readGeckoInterpProfilingStack();
    }
    let f1 = () => g1();
    assertStack(f1(), ["testBasic", "f1", "g1"]);

    // Test non-function frames.
    assertStack(evaluate("eval(`(function foo() { return readGeckoInterpProfilingStack(); })()`)"),
                ["testBasic", "@evaluate", "@evaluate line 1 > eval:1:1", "foo"]);
}
testBasic();
testBasic();

function testThrow() {
    let stacks = [];
    let thrower = function() {
        stacks.push(readGeckoInterpProfilingStack());
        throw 1;
    };
    let catcher = function() {
        try {
            thrower();
        } catch (e) {
            stacks.push(readGeckoInterpProfilingStack());
        }
    };
    catcher();
    assertEq(stacks.length, 2);
    assertStack(stacks[0], ["testThrow", "catcher", "thrower"]);
    assertStack(stacks[1], ["testThrow", "catcher"]);
}
testThrow();
testThrow();

function testSelfHosted() {
    let stacks = [1, 2, 3].map(function() {
        return readGeckoInterpProfilingStack();
    });
    assertEq(stacks.length, 3);
    for (var stack of stacks) {
        assertStack(stack, ["testSelfHosted", "map", "testSelfHosted/stacks<"]);
    }
}
testSelfHosted();
testSelfHosted();

function testGenerator() {
    let stacks = [];
    let generator = function*() {
        stacks.push(readGeckoInterpProfilingStack());
        yield 1;
        stacks.push(readGeckoInterpProfilingStack());
        yield 2;
        stacks.push(readGeckoInterpProfilingStack());
    };
    for (let x of generator()) {}
    assertStack(readGeckoInterpProfilingStack(), ["testGenerator"]);

    assertEq(stacks.length, 3);
    for (var stack of stacks) {
        assertStack(stack, ["testGenerator", "next", "generator"]);
    }
}
testGenerator();
testGenerator();

async function testAsync() {
    let stacks = [];
    let asyncFun = async function() {
        stacks.push(readGeckoInterpProfilingStack());
        await 1;
        stacks.push(readGeckoInterpProfilingStack());
    };
    await asyncFun();
    assertStack(readGeckoInterpProfilingStack(), ["AsyncFunctionNext", "testAsync"]);

    assertEq(stacks.length, 2);
    assertStack(stacks[0], ["testAsync", "asyncFun"]);
    assertStack(stacks[1], ["AsyncFunctionNext", "asyncFun"]);
}
testAsync();
drainJobQueue();
testAsync();
drainJobQueue();

disableGeckoProfiling();