Title: [112090] trunk/Source/WebCore
Revision
112090
Author
[email protected]
Date
2012-03-26 07:32:52 -0700 (Mon, 26 Mar 2012)

Log Message

Web Inspector: Speed up the retainers build phase.
https://bugs.webkit.org/show_bug.cgi?id=81763

Replacing the edge iterator in retainers building phase
makes it run 10 times faster (400 ms vs. 4 sec).

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

* inspector/front-end/HeapSnapshot.js:
(WebInspector.HeapSnapshot.prototype._buildRetainers):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (112089 => 112090)


--- trunk/Source/WebCore/ChangeLog	2012-03-26 14:20:05 UTC (rev 112089)
+++ trunk/Source/WebCore/ChangeLog	2012-03-26 14:32:52 UTC (rev 112090)
@@ -1,3 +1,16 @@
+2012-03-26  Alexei Filippov  <[email protected]>
+
+        Web Inspector: Speed up the retainers build phase.
+        https://bugs.webkit.org/show_bug.cgi?id=81763
+
+        Replacing the edge iterator in retainers building phase
+        makes it run 10 times faster (400 ms vs. 4 sec).
+
+        Reviewed by Yury Semikhatsky.
+
+        * inspector/front-end/HeapSnapshot.js:
+        (WebInspector.HeapSnapshot.prototype._buildRetainers):
+
 2012-03-22  Alexander Pavlov  <[email protected]>
 
         Web Inspector: Migrate InspectorCSSAgent to strict protocol types

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


--- trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2012-03-26 14:20:05 UTC (rev 112089)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2012-03-26 14:32:52 UTC (rev 112090)
@@ -1069,22 +1069,58 @@
 
     _buildRetainers: function()
     {
-        this._buildReverseIndex(
-            "_retainerIndex",
-            "_retainers",
-            (function (node, callback)
-             {
-                 for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next())
-                     callback(this._nodePosition[edgesIter.edge.nodeIndex]);
-             }).bind(this),
-            (function (node, indexCallback, dataCallback)
-             {
-                 for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next()) {
-                     var edge = edgesIter.edge;
-                     var retIndex = this._getRetainerIndex(edge.nodeIndex);
-                     dataCallback(indexCallback(retIndex), node.nodeIndex + this._firstEdgeOffset + edge.edgeIndex);
-                 }
-             }).bind(this));
+        var nodeIndexes = this.nodeIndexes;
+        var nodePositions = this._nodePosition;
+        var nodeCount = this.nodeCount;
+        var nodes = this._nodes;
+
+        // 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._retainerIndex = new Int32Array(nodeCount + 1);
+        var edgesCountOffset = this._edgesCountOffset;
+        var firstEdgeOffset = this._firstEdgeOffset;
+        var edgeFieldsCount = this._edgeFieldsCount;
+        var edgeToNodeOffset = this._edgeToNodeOffset;
+        var backRefsCount = 0;
+        // Count the number of retainers for each node
+        for (var i = 0; i < nodeCount; ++i) {
+            var nodeIndex = nodeIndexes[i];
+            var edgesOffset = nodeIndex + firstEdgeOffset + edgeToNodeOffset;
+            var edgesCount = nodes[nodeIndex + edgesCountOffset];
+            backRefsCount += edgesCount;
+            for (var j = 0; j < edgesCount; ++j) {
+              var targetNodeIndex = nodes[j * edgeFieldsCount + edgesOffset];
+              ++indexArray[nodePositions[targetNodeIndex]];
+            }
+        }
+        var backRefsArray = this._retainers = new Int32Array(backRefsCount);
+        // Put in the first slot of each backRefsArray slice the count of entries
+        // that will be filled.
+        var backRefsPosition = 0;
+        // The one extra slot in the _retainerIndex array is set to the
+        // end of _retainers array. It is used in the retainers iterator.
+        for (i = 0; i <= nodeCount; ++i) {
+            backRefsCount = backRefsArray[backRefsPosition] = indexArray[i];
+            indexArray[i] = backRefsPosition;
+            backRefsPosition += backRefsCount;
+        }
+        var retainerIndex = this._retainerIndex;
+        // Fill up the retainers array with indexes of edges.
+        for (var i = 0; i < nodeCount; ++i) {
+            var nodeIndex = nodeIndexes[i];
+            var edgesOffset = nodeIndex + firstEdgeOffset;
+            var edgesCount = nodes[nodeIndex + edgesCountOffset];
+            for (var j = 0; j < edgesCount; ++j) {
+                var edgeIndex = j * edgeFieldsCount + edgesOffset;
+                var retNode = nodePositions[nodes[edgeIndex + edgeToNodeOffset]];
+                var retIndex = indexArray[retNode];
+                var backRefIndex = retIndex + (--backRefsArray[retIndex]);
+                backRefsArray[backRefIndex] = edgeIndex;
+            }
+        }
     },
 
     _calculateObjectToWindowDistance: function()
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to