From de6b75a5f7a677bc3601175fece8ce1662002e4d Mon Sep 17 00:00:00 2001 From: Alexei Filippov Date: Thu, 29 Nov 2018 23:44:14 +0000 Subject: [PATCH] DevTools: Assign proper distances to non user reachable objects. Do not assign zero distance to all GC root objects. Instead assign zero to the global root and follow strong roots only from there. BUG=906847 Change-Id: Iee22162ac11a6700e019276daee1357ef33e61b9 Reviewed-on: https://chromium-review.googlesource.com/c/1353995 Commit-Queue: Alexei Filippov Reviewed-by: Ulan Degenbaev Cr-Original-Commit-Position: refs/heads/master@{#612438} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 6befba52c6daa1ebf7b542859af8afe3e499d2fb --- .../heap_snapshot_worker/HeapSnapshot.js | 92 +++---------------- 1 file changed, 11 insertions(+), 81 deletions(-) diff --git a/front_end/heap_snapshot_worker/HeapSnapshot.js b/front_end/heap_snapshot_worker/HeapSnapshot.js index 8c67f784b0..eda95dc235 100644 --- a/front_end/heap_snapshot_worker/HeapSnapshot.js +++ b/front_end/heap_snapshot_worker/HeapSnapshot.js @@ -1281,18 +1281,6 @@ HeapSnapshotWorker.HeapSnapshot = class { return true; } - /** - * @param {function(!HeapSnapshotWorker.HeapSnapshotNode)} action - * @param {boolean=} userRootsOnly - */ - forEachRoot(action, userRootsOnly) { - for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { - const node = iter.edge.node(); - if (!userRootsOnly || this.isUserRoot(node)) - action(node); - } - } - /** * @param {function(!HeapSnapshotWorker.HeapSnapshotNode,!HeapSnapshotWorker.HeapSnapshotEdge):boolean=} filter */ @@ -1306,24 +1294,20 @@ HeapSnapshotWorker.HeapSnapshot = class { const nodesToVisit = new Uint32Array(this.nodeCount); let nodesToVisitLength = 0; - /** - * @param {number} distance - * @param {!HeapSnapshotWorker.HeapSnapshotNode} node - */ - function enqueueNode(distance, node) { - const ordinal = node.ordinal(); - if (distances[ordinal] !== noDistance) - return; - distances[ordinal] = distance; - nodesToVisit[nodesToVisitLength++] = node.nodeIndex; + // BFS for user root objects. + for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { + const node = iter.edge.node(); + if (this.isUserRoot(node)) { + distances[node.ordinal()] = 1; + nodesToVisit[nodesToVisitLength++] = node.nodeIndex; + } } - - this.forEachRoot(enqueueNode.bind(null, 1), true); this._bfs(nodesToVisit, nodesToVisitLength, distances, filter); - // bfs for the rest of objects - nodesToVisitLength = 0; - this.forEachRoot(enqueueNode.bind(null, HeapSnapshotModel.baseSystemDistance), false); + // BFS for objects not reached from user roots. + distances[this.rootNode().ordinal()] = HeapSnapshotModel.baseSystemDistance; + nodesToVisit[0] = this.rootNode().nodeIndex; + nodesToVisitLength = 1; this._bfs(nodesToVisit, nodesToVisitLength, distances, filter); } @@ -2581,60 +2565,6 @@ HeapSnapshotWorker.JSHeapSnapshot = class extends HeapSnapshotWorker.HeapSnapsho return node.isUserRoot() || node.isDocumentDOMTreesRoot(); } - /** - * @override - * @param {function(!HeapSnapshotWorker.HeapSnapshotNode)} action - * @param {boolean=} userRootsOnly - */ - forEachRoot(action, userRootsOnly) { - /** - * @param {!HeapSnapshotWorker.HeapSnapshotNode} node - * @param {string} name - * @return {?HeapSnapshotWorker.HeapSnapshotNode} - */ - function getChildNodeByName(node, name) { - for (let iter = node.edges(); iter.hasNext(); iter.next()) { - const child = iter.edge.node(); - if (child.name() === name) - return child; - } - return null; - } - - const visitedNodes = {}; - /** - * @param {!HeapSnapshotWorker.HeapSnapshotNode} node - */ - function doAction(node) { - const ordinal = node.ordinal(); - if (!visitedNodes[ordinal]) { - action(node); - visitedNodes[ordinal] = true; - } - } - - const gcRoots = getChildNodeByName(this.rootNode(), '(GC roots)'); - if (!gcRoots) - return; - - if (userRootsOnly) { - for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) { - const node = iter.edge.node(); - if (this.isUserRoot(node)) - doAction(node); - } - } else { - for (let iter = gcRoots.edges(); iter.hasNext(); iter.next()) { - const subRoot = iter.edge.node(); - for (let iter2 = subRoot.edges(); iter2.hasNext(); iter2.next()) - doAction(iter2.edge.node()); - doAction(subRoot); - } - for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) - doAction(iter.edge.node()); - } - } - /** * @override * @return {?{map: !Uint32Array, flag: number}}