/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; // Test that we can get the set of immediately dominated nodes for any given // node and that this forms a tree. function run_test() { const dominatorTree = saveHeapSnapshotAndComputeDominatorTree(); equal( typeof dominatorTree.getImmediatelyDominated, "function", "getImmediatelyDominated should be a function" ); // Do a traversal of the dominator tree. // // Note that we don't assert directly, only if we get an unexpected // value. There are just way too many nodes in the heap graph to assert for // every one. This test would constantly time out and assertion messages would // overflow the log size. const root = dominatorTree.root; equal( dominatorTree.getImmediateDominator(root), null, "The root should not have a parent" ); const seen = new Set(); const stack = [root]; while (stack.length) { const top = stack.pop(); if (seen.has(top)) { ok( false, "This is a tree, not a graph: we shouldn't have " + "multiple edges to the same node" ); } seen.add(top); if (seen.size % 1000 === 0) { dumpn("Progress update: seen size = " + seen.size); } const newNodes = dominatorTree.getImmediatelyDominated(top); if (Object.prototype.toString.call(newNodes) !== "[object Array]") { ok( false, "getImmediatelyDominated should return an array for known node ids" ); } const topSize = dominatorTree.getRetainedSize(top); let lastSize = Infinity; for (let i = 0; i < newNodes.length; i++) { if (typeof newNodes[i] !== "number") { ok(false, "Every dominated id should be a number"); } if (dominatorTree.getImmediateDominator(newNodes[i]) !== top) { ok(false, "child's parent should be the expected parent"); } const thisSize = dominatorTree.getRetainedSize(newNodes[i]); if (thisSize >= topSize) { ok( false, "the size of children in the dominator tree should" + " always be less than that of their parent" ); } if (thisSize > lastSize) { ok( false, "children should be sorted by greatest to least retained size, " + "lastSize = " + lastSize + ", thisSize = " + thisSize ); } lastSize = thisSize; stack.push(newNodes[i]); } } ok(true, "Successfully walked the tree"); dumpn("Walked " + seen.size + " nodes"); do_test_finished(); }