Bug 1226024 - Expose the root of the dominator tree to JavaScript; r=bz,sfink

This commit is contained in:
Nick Fitzgerald 2015-11-19 08:10:13 -08:00
parent 34d2f24766
commit 95712126f0
6 changed files with 66 additions and 8 deletions

View File

@ -42,6 +42,7 @@ public:
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
uint64_t Root() const { return mDominatorTree.root().identifier(); }
};
} // namespace devtools

View File

@ -117,6 +117,13 @@ function saveNewHeapSnapshot(opts = { runtime: true }) {
return filePath;
}
function readHeapSnapshot(filePath) {
const snapshot = ChromeUtils.readHeapSnapshot(filePath);
ok(snapshot, "Should have read a heap snapshot back from " + filePath);
ok(snapshot instanceof HeapSnapshot, "snapshot should be an instance of HeapSnapshot");
return snapshot;
}
/**
* Save a heap snapshot to the file with the given name in the current
* directory, read it back as a HeapSnapshot instance, and then take a census of
@ -138,18 +145,40 @@ function saveNewHeapSnapshot(opts = { runtime: true }) {
*/
function saveHeapSnapshotAndTakeCensus(dbg=null, censusOptions=undefined) {
const snapshotOptions = dbg ? { debugger: dbg } : { runtime: true };
const filePath = ChromeUtils.saveHeapSnapshot(snapshotOptions);
ok(filePath, "Should get a file path to save the core dump to.");
ok(true, "Should have saved a heap snapshot to " + filePath);
const snapshot = ChromeUtils.readHeapSnapshot(filePath);
ok(snapshot, "Should have read a heap snapshot back from " + filePath);
ok(snapshot instanceof HeapSnapshot, "snapshot should be an instance of HeapSnapshot");
const filePath = saveNewHeapSnapshot(snapshotOptions);
const snapshot = readHeapSnapshot(filePath);
equal(typeof snapshot.takeCensus, "function", "snapshot should have a takeCensus method");
return snapshot.takeCensus(censusOptions);
}
/**
* Save a heap snapshot to disk, read it back as a HeapSnapshot instance, and
* then compute its dominator tree.
*
* @param {Debugger|null} dbg
* If a Debugger object is given, only serialize the subgraph covered by
* the Debugger's debuggees. If null, serialize the whole heap graph.
*
* @returns {DominatorTree}
*/
function saveHeapSnapshotAndComputeDominatorTree(dbg = null) {
const snapshotOptions = dbg ? { debugger: dbg } : { runtime: true };
const filePath = saveNewHeapSnapshot(snapshotOptions);
const snapshot = readHeapSnapshot(filePath);
equal(typeof snapshot.computeDominatorTree, "function",
"snapshot should have a `computeDominatorTree` method");
const dominatorTree = snapshot.computeDominatorTree();
ok(dominatorTree, "Should be able to compute a dominator tree");
ok(dominatorTree instanceof DominatorTree, "Should be an instance of DominatorTree");
return dominatorTree;
}
function isSavedFrame(obj) {
return Object.prototype.toString.call(obj) === "[object SavedFrame]";
}

View File

@ -0,0 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that we can get the root of dominator trees.
function run_test() {
const dominatorTree = saveHeapSnapshotAndComputeDominatorTree();
equal(typeof dominatorTree.root, "number", "root should be a number");
equal(Math.floor(dominatorTree.root), dominatorTree.root, "root should be an integer");
ok(dominatorTree.root >= 0, "root should be positive");
ok(dominatorTree.root <= Math.pow(2, 48), "root should be less than or equal to 2^48");
do_test_finished();
}

View File

@ -30,6 +30,7 @@ support-files =
[test_census-tree-node-08.js]
[test_DominatorTree_01.js]
[test_DominatorTree_02.js]
[test_DominatorTree_03.js]
[test_HeapAnalyses_getCreationTime_01.js]
[test_HeapAnalyses_readHeapSnapshot_01.js]
[test_HeapAnalyses_takeCensusDiff_01.js]

View File

@ -4,6 +4,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
typedef unsigned long long NodeId;
/**
* In a directed graph with a root node `R`, a node `A` is said to "dominate" a
* node `B` iff every path from `R` to `B` contains `A`. A node `A` is said to
@ -37,5 +39,10 @@
*/
[ChromeOnly, Exposed=(Window,System,Worker)]
interface DominatorTree {
/**
* The `NodeId` for the root of the dominator tree. This is a "meta-root" in
* that it has an edge to each GC root in the heap snapshot this dominator
* tree was created from.
*/
readonly attribute NodeId root;
};

View File

@ -546,6 +546,13 @@ class JS_PUBLIC_API(DominatorTree)
mozilla::Move(*maybeDominatedSets)));
}
/**
* Get the root node for this dominator tree.
*/
const Node& root() const {
return postOrder[postOrder.length() - 1];
}
/**
* Return the immediate dominator of the given `node`. If `node` was not
* reachable from the `root` that this dominator tree was constructed from,