Title: [112271] trunk/Source/WebCore
Revision
112271
Author
[email protected]
Date
2012-03-27 08:15:18 -0700 (Tue, 27 Mar 2012)

Log Message

Web Inspector: Speed up snapshot parsing.
https://bugs.webkit.org/show_bug.cgi?id=82325

Replacing the iterators with raw nodes/edges access speeds up
some phases phasses up to 10 times, taking down the whole init
time to less than 6 sec.

Patch by Alexei Filippov <[email protected]> on 2012-03-27
Reviewed by Yury Semikhatsky.

* inspector/front-end/HeapSnapshot.js:
(WebInspector.HeapSnapshot.prototype._buildNodeIndex):
(WebInspector.HeapSnapshot.prototype._buildDominatedNodes):
(WebInspector.HeapSnapshot.prototype._markQueriableHeapObjects):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (112270 => 112271)


--- trunk/Source/WebCore/ChangeLog	2012-03-27 15:03:44 UTC (rev 112270)
+++ trunk/Source/WebCore/ChangeLog	2012-03-27 15:15:18 UTC (rev 112271)
@@ -1,3 +1,19 @@
+2012-03-27  Alexei Filippov  <[email protected]>
+
+        Web Inspector: Speed up snapshot parsing.
+        https://bugs.webkit.org/show_bug.cgi?id=82325
+
+        Replacing the iterators with raw nodes/edges access speeds up
+        some phases phasses up to 10 times, taking down the whole init
+        time to less than 6 sec.
+
+        Reviewed by Yury Semikhatsky.
+
+        * inspector/front-end/HeapSnapshot.js:
+        (WebInspector.HeapSnapshot.prototype._buildNodeIndex):
+        (WebInspector.HeapSnapshot.prototype._buildDominatedNodes):
+        (WebInspector.HeapSnapshot.prototype._markQueriableHeapObjects):
+
 2012-03-27  Antti Koivisto  <[email protected]>
 
         Assertion failure in acid2.

Modified: trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js (112270 => 112271)


--- trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2012-03-27 15:03:44 UTC (rev 112270)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2012-03-27 15:15:18 UTC (rev 112271)
@@ -1029,41 +1029,6 @@
         return aggregates;
     },
 
-    _buildReverseIndex: function(indexArrayName, backRefsArrayName, indexCallback, dataCallback)
-    {
-        // Builds up two arrays:
-        //  - "backRefsArray" is a continuous array, where each node owns an
-        //    interval (can be empty) with corresponding back references.
-        //  - "indexArray" is an array of indexes in the "backRefsArray"
-        //    with the same positions as in the _nodeIndex.
-        var indexArray = this[indexArrayName] = new Uint32Array(this._nodeIndex.length);
-        var nodeIndexes = this.nodeIndexes;
-        var nodeCount = this.nodeCount;
-        var node = new WebInspector.HeapSnapshotNode(this, nodeIndexes[0]);
-        for (var i = 0; i < nodeCount; ++i) {
-            node.nodeIndex = nodeIndexes[i];
-            indexCallback(node, function (position) { ++indexArray[position]; });
-        }
-        var backRefsCount = 0;
-        for (i = 0, l = indexArray.length; i < l; ++i)
-            backRefsCount += indexArray[i];
-        var backRefsArray = this[backRefsArrayName] = new Uint32Array(backRefsCount + 1);
-        // Put in the first slot of each backRefsArray slice the count of entries
-        // that will be filled.
-        var backRefsPosition = 0;
-        for (i = 0, l = indexArray.length; i < l; ++i) {
-            backRefsCount = backRefsArray[backRefsPosition] = indexArray[i];
-            indexArray[i] = backRefsPosition;
-            backRefsPosition += backRefsCount;
-        }
-        for (var i = 0; i < nodeCount; ++i) {
-            node.nodeIndex = nodeIndexes[i];
-            dataCallback(node,
-                         function (backRefIndex) { return backRefIndex + (--backRefsArray[backRefIndex]); },
-                         function (backRefIndex, destIndex) { backRefsArray[backRefIndex] = destIndex; });
-        }
-    },
-
     _buildRetainers: function()
     {
         var nodeIndexes = this.nodeIndexes;
@@ -1076,7 +1041,7 @@
         //    interval (can be empty) with corresponding back references.
         //  - "indexArray" is an array of indexes in the "backRefsArray"
         //    with the same positions as in the _nodeIndex.
-        var indexArray = this._retainerIndex = new Int32Array(nodeCount + 1);
+        var indexArray = this._retainerIndex = new Uint32Array(nodeCount + 1);
         var edgesCountOffset = this._edgesCountOffset;
         var firstEdgeOffset = this._firstEdgeOffset;
         var edgeFieldsCount = this._edgeFieldsCount;
@@ -1093,7 +1058,7 @@
               ++indexArray[nodePositions[targetNodeIndex]];
             }
         }
-        var backRefsArray = this._retainers = new Int32Array(backRefsCount);
+        var backRefsArray = this._retainers = new Uint32Array(backRefsCount);
         // Put in the first slot of each backRefsArray slice the count of entries
         // that will be filled.
         var backRefsPosition = 0;
@@ -1256,13 +1221,18 @@
     _buildNodeIndex: function()
     {
         var count = 0;
-        for (var nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next(), ++count);
+        for (var i = this._rootNodeIndex, l = this._nodes.length; i < l; ++count) {
+            var edgesCount = this._nodes[i + this._edgesCountOffset];
+            i += this._firstEdgeOffset + edgesCount * this._edgeFieldsCount;
+        }
         var nodeIndex = new Uint32Array(count + 1);
         var nodePosition = {};
         count = 0;
-        for (var nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next(), ++count) {
-            nodeIndex[count] = nodesIter.index;
-            nodePosition[nodesIter.index] = count;
+        for (var i = this._rootNodeIndex, l = this._nodes.length; i < l; ++count) {
+            nodeIndex[count] = i;
+            nodePosition[i] = count;
+            var edgesCount = this._nodes[i + this._edgesCountOffset];
+            i += this._firstEdgeOffset + edgesCount * this._edgeFieldsCount;
         }
         nodeIndex[count] = this._nodes.length;
         nodePosition[this._nodes.length] = count;
@@ -1292,23 +1262,39 @@
 
     _buildDominatedNodes: function()
     {
-        this._buildReverseIndex(
-            "_dominatedIndex",
-            "_dominatedNodes",
-            (function (node, callback)
-             {
-                 var dominatorIndex = node.dominatorIndex;
-                 if (dominatorIndex !== node.nodeIndex)
-                     callback(this._nodePosition[dominatorIndex]);
-             }).bind(this),
-            (function (node, indexCallback, dataCallback)
-             {
-                 var dominatorIndex = node.dominatorIndex;
-                 if (dominatorIndex !== node.nodeIndex) {
-                     var dominatedIndex = this._getDominatedIndex(dominatorIndex);
-                     dataCallback(indexCallback(dominatedIndex), node.nodeIndex);
-                 }
-             }).bind(this));
+        var nodeCount = this.nodeCount;
+        // Builds up two arrays:
+        //  - "dominatedNodes" is a continuous array, where each node owns an
+        //    interval (can be empty) with corresponding dominated nodes.
+        //  - "indexArray" is an array of indexes in the "dominatedNodes"
+        //    with the same positions as in the _nodeIndex.
+        var indexArray = this._dominatedIndex = new Uint32Array(nodeCount + 1);
+        // Count the number of retainers for each node
+        for (var i = 0; i < nodeCount; ++i) {
+            var nodeIndex = this.nodeIndexes[i];
+            var dominatorIndex = this._nodes[nodeIndex + this._dominatorOffset];
+            if (nodeIndex === dominatorIndex) continue;
+            ++indexArray[this._nodePosition[dominatorIndex]];
+        }
+        var dominatedNodes = this._dominatedNodes = new Uint32Array(nodeCount - 1);
+        // Put in the first slot of each dominatedNodes slice the count of entries
+        // that will be filled.
+        var dominatedPosition = 0;
+        for (i = 0; i <= nodeCount; ++i) {
+            var dominatedCount = dominatedNodes[dominatedPosition] = indexArray[i];
+            indexArray[i] = dominatedPosition;
+            dominatedPosition += dominatedCount;
+        }
+        // Fill up the dominatedNodes array with indexes of dominated nodes.
+        for (var i = 0; i < nodeCount; ++i) {
+            var nodeIndex = this.nodeIndexes[i];
+            var dominatorIndex = this._nodes[nodeIndex + this._dominatorOffset];
+            if (nodeIndex === dominatorIndex) continue;
+            var dominatorPos = this._nodePosition[dominatorIndex];
+            var dominatedRefIndex = indexArray[dominatorPos];
+            dominatedRefIndex += (--dominatedNodes[dominatedRefIndex]);
+            dominatedNodes[dominatedRefIndex] = nodeIndex;
+        }
     },
 
     _getDominatedIndex: function(nodeIndex)
@@ -1383,27 +1369,33 @@
         var list = [];
         for (var iter = this.rootNode.edges; iter.hasNext(); iter.next()) {
             if (iter.edge.node.isWindow)
-                list.push(iter.edge.node);
+                list.push(iter.edge.node.nodeIndex);
         }
 
+        var edge = new WebInspector.HeapSnapshotEdge(this);
+        var node = new WebInspector.HeapSnapshotNode(this);
         while (list.length) {
-            var node = list.pop();
-            if (this._flags[node.nodeIndex] & flag)
+            var nodeIndex = list.pop();
+            if (this._flags[nodeIndex] & flag)
                 continue;
-            this._flags[node.nodeIndex] |= flag;
-            for (var iter = node.edges; iter.hasNext(); iter.next()) {
-                var edge = iter.edge;
-                var node = edge.node;
-                if (this._flags[node.nodeIndex] & flag)
+            node.nodeIndex = nodeIndex;
+            this._flags[nodeIndex] |= flag;
+            var edgesOffset = nodeIndex + this._firstEdgeOffset;
+            var edgesCount = this._nodes[nodeIndex + this._edgesCountOffset];
+            edge._edges = node.rawEdges;
+            for (var j = 0; j < edgesCount; ++j) {
+                edge.edgeIndex = j * this._edgeFieldsCount;
+                var nodeIndex = this._nodes[edgesOffset + edge.edgeIndex + this._edgeToNodeOffset];
+                if (this._flags[nodeIndex] & flag)
                     continue;
                 if (edge.isHidden || edge.isInvisible)
                     continue;
+                if (edge.isInternal)
+                    continue;
                 var name = edge.name;
                 if (!name)
                     continue;
-                if (edge.isInternal)
-                    continue;
-                list.push(node);
+                list.push(nodeIndex);
             }
         }
     },
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to