test_dominator_trees_07.js (4633B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test that we can incrementally fetch two subtrees in the same dominator tree 7 // concurrently. This exercises the activeFetchRequestCount machinery. 8 9 const { 10 dominatorTreeState, 11 viewState, 12 } = require("resource://devtools/client/memory/constants.js"); 13 const { 14 takeSnapshotAndCensus, 15 fetchImmediatelyDominated, 16 } = require("resource://devtools/client/memory/actions/snapshot.js"); 17 const DominatorTreeLazyChildren = require("resource://devtools/client/memory/dominator-tree-lazy-children.js"); 18 19 const { 20 changeView, 21 } = require("resource://devtools/client/memory/actions/view.js"); 22 23 add_task(async function () { 24 const front = new StubbedMemoryFront(); 25 const heapWorker = new HeapAnalysesClient(); 26 await front.attach(); 27 const store = Store(); 28 const { getState, dispatch } = store; 29 30 dispatch(changeView(viewState.DOMINATOR_TREE)); 31 dispatch(takeSnapshotAndCensus(front, heapWorker)); 32 33 // Wait for the dominator tree to finish being fetched. 34 await waitUntilState( 35 store, 36 state => 37 state.snapshots[0] && 38 state.snapshots[0].dominatorTree && 39 state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED 40 ); 41 ok( 42 getState().snapshots[0].dominatorTree.root, 43 "The dominator tree was fetched" 44 ); 45 46 // Find a node that has more children. 47 48 function findNode(node) { 49 if (node.moreChildrenAvailable && !node.children) { 50 return node; 51 } 52 53 if (node.children) { 54 for (const child of node.children) { 55 const found = findNode(child); 56 if (found) { 57 return found; 58 } 59 } 60 } 61 62 return null; 63 } 64 65 const oldRoot = getState().snapshots[0].dominatorTree.root; 66 const oldNode = findNode(oldRoot); 67 ok(oldNode, "Should have found a node with more children."); 68 69 // Find another node that has more children. 70 function findNodeRev(node) { 71 if (node.moreChildrenAvailable && !node.children) { 72 return node; 73 } 74 75 if (node.children) { 76 for (const child of node.children.slice().reverse()) { 77 const found = findNodeRev(child); 78 if (found) { 79 return found; 80 } 81 } 82 } 83 84 return null; 85 } 86 87 const oldNode2 = findNodeRev(oldRoot); 88 ok(oldNode2, "Should have found another node with more children."); 89 Assert.notStrictEqual( 90 oldNode, 91 oldNode2, 92 "The second node should not be the same as the first one" 93 ); 94 95 // Fetch both subtrees concurrently. 96 dispatch( 97 fetchImmediatelyDominated( 98 heapWorker, 99 getState().snapshots[0].id, 100 new DominatorTreeLazyChildren(oldNode.nodeId, 0) 101 ) 102 ); 103 dispatch( 104 fetchImmediatelyDominated( 105 heapWorker, 106 getState().snapshots[0].id, 107 new DominatorTreeLazyChildren(oldNode2.nodeId, 0) 108 ) 109 ); 110 111 equal( 112 getState().snapshots[0].dominatorTree.state, 113 dominatorTreeState.INCREMENTAL_FETCHING, 114 "Fetching immediately dominated children should put us in the " + 115 "INCREMENTAL_FETCHING state" 116 ); 117 118 await waitUntilState( 119 store, 120 state => 121 state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED 122 ); 123 ok( 124 true, 125 "The dominator tree should go back to LOADED after the incremental " + 126 "fetching is done." 127 ); 128 129 const newRoot = getState().snapshots[0].dominatorTree.root; 130 Assert.notStrictEqual( 131 oldRoot, 132 newRoot, 133 "When we insert new nodes, we get a new tree" 134 ); 135 136 // Find the new node which has the children inserted. 137 138 function findNodeWithId(id, node) { 139 if (node.nodeId === id) { 140 return node; 141 } 142 143 if (node.children) { 144 for (const child of node.children) { 145 const found = findNodeWithId(id, child); 146 if (found) { 147 return found; 148 } 149 } 150 } 151 152 return null; 153 } 154 155 const newNode = findNodeWithId(oldNode.nodeId, newRoot); 156 ok(newNode, "Should find the node in the new tree again"); 157 Assert.notStrictEqual( 158 newNode, 159 oldNode, 160 "We did not mutate the old node in place, instead created a new node" 161 ); 162 ok( 163 newNode.children.length, 164 "And the new node should have the new children attached" 165 ); 166 167 const newNode2 = findNodeWithId(oldNode2.nodeId, newRoot); 168 ok(newNode2, "Should find the second node in the new tree again"); 169 Assert.notStrictEqual( 170 newNode2, 171 oldNode2, 172 "We did not mutate the second old node in place, instead created a new node" 173 ); 174 ok( 175 newNode2.children, 176 "And the new node should have the new children attached" 177 ); 178 179 heapWorker.destroy(); 180 await front.detach(); 181 });