summaryrefslogtreecommitdiffstats
path: root/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_deepStack_01.js
blob: 9eb11d9afe8e735f5abba0a96b550cd7e25543f0 (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
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

// Test that we can save a core dump with very deep allocation stacks and read
// it back into a HeapSnapshot.

function stackDepth(stack) {
  return stack ? 1 + stackDepth(stack.parent) : 0;
}

function run_test() {
  // Create a Debugger observing a debuggee's allocations.
  const debuggee = new Cu.Sandbox(null);
  const dbg = new Debugger(debuggee);
  dbg.memory.trackingAllocationSites = true;

  // Allocate some objects in the debuggee that will have their allocation
  // stacks recorded by the Debugger.

  debuggee.eval("this.objects = []");
  debuggee.eval(
    (function recursiveAllocate(n) {
      if (n <= 0)
        return;

      // Make sure to recurse before pushing the object so that when TCO is
      // implemented sometime in the future, it doesn't invalidate this test.
      recursiveAllocate(n - 1);
      this.objects.push({});
    }).toString()
  );
  debuggee.eval("recursiveAllocate = recursiveAllocate.bind(this);");
  debuggee.eval("recursiveAllocate(200);");

  // Now save a snapshot that will include the allocation stacks and read it
  // back again.

  const filePath = ChromeUtils.saveHeapSnapshot({ runtime: true });
  ok(true, "Should be able to save a snapshot.");

  const snapshot = ChromeUtils.readHeapSnapshot(filePath);
  ok(snapshot, "Should be able to read a heap snapshot");
  ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot");

  const report = snapshot.takeCensus({
    breakdown: { by: "allocationStack",
                 then: { by: "count", bytes: true, count: true },
                 noStack: { by: "count", bytes: true, count: true }
               }
  });

  // Keep this synchronized with `HeapSnapshot::MAX_STACK_DEPTH`!
  const MAX_STACK_DEPTH = 60;

  let foundStacks = false;
  report.forEach((v, k) => {
    if (k === "noStack") {
      return;
    }

    foundStacks = true;
    const depth = stackDepth(k);
    dumpn("Stack depth is " + depth);
    ok(depth <= MAX_STACK_DEPTH,
       "Every stack should have depth less than or equal to the maximum stack depth");
  });
  ok(foundStacks);

  do_test_finished();
}