summaryrefslogtreecommitdiffstats
path: root/tools/profiler/tests/xpcshell/test_feature_js.js
blob: a2c328c0516a9e6d0e3b11ad35a50368d30dc460 (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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * Test that JS capturing works as expected.
 */
add_task(async () => {
  if (!AppConstants.MOZ_GECKO_PROFILER) {
    return;
  }
  const entries = 10000;
  const interval = 1;
  const threads = [];
  const features = ["js"];

  Services.profiler.StartProfiler(entries, interval, features, threads);

  // Call the following to get a nice stack in the profiler:
  // functionA -> functionB -> functionC -> captureAtLeastOneJsSample
  const sampleIndex = await functionA();

  const profile = await Services.profiler.getProfileDataAsync();
  const [thread] = profile.threads;
  const { samples } = thread;

  const inflatedStackFrames = getInflatedStackLocations(
    thread,
    samples.data[sampleIndex]
  );

  expectStackToContain(
    inflatedStackFrames,
    [
      "(root)",
      "js::RunScript",
      // The following regexes match a string similar to:
      //
      // "functionA (/gecko/obj/_tests/xpcshell/tools/profiler/tests/xpcshell/test_feature_js.js:47:0)"
      //
      //          this matches the script location
      //          |                       match the line number
      //          |                       |   match the column number
      //          v                       v   v
      /^functionA \(.+test_feature_js\.js:\d+:\d+\)$/,
      /^functionB \(.+test_feature_js\.js:\d+:\d+\)$/,
      /^functionC \(.+test_feature_js\.js:\d+:\d+\)$/,
    ],
    "The stack contains a few frame labels, as well as the JS functions that we called."
  );
});

function functionA() {
  return functionB();
}

function functionB() {
  return functionC();
}

async function functionC() {
  return captureAtLeastOneJsSample();
}