Title: [89457] trunk/Source/WebCore
Revision
89457
Author
mnaga...@chromium.org
Date
2011-06-22 12:39:41 -0700 (Wed, 22 Jun 2011)

Log Message

2011-06-20  Mikhail Naganov  <mnaga...@chromium.org>

        Reviewed by Pavel Feldman.

        Web Inspector: [Chromium] Improve speed of heap profiles dominators view.
        https://bugs.webkit.org/show_bug.cgi?id=62979

        * inspector/front-end/DetailedHeapshotGridNodes.js:
        (WebInspector.HeapSnapshotDominatorObjectNode.prototype._createProvider):
        * inspector/front-end/HeapSnapshot.js:
        (WebInspector.HeapSnapshotArraySlice.prototype.item):
        (WebInspector.HeapSnapshotArraySlice.prototype.slice):
        (WebInspector.HeapSnapshot.prototype.dispose):
        (WebInspector.HeapSnapshot.prototype._dominatedNodesOfNode):
        (WebInspector.HeapSnapshot.prototype._buildReverseIndex.var):
        (WebInspector.HeapSnapshot.prototype._buildReverseIndex):
        (WebInspector.HeapSnapshot.prototype._buildRetainers):
        (WebInspector.HeapSnapshot.prototype._buildNodeIndex):
        (WebInspector.HeapSnapshot.prototype._buildDominatedNodes):
        (WebInspector.HeapSnapshot.prototype._getDominatedIndex):
        (WebInspector.HeapSnapshot.prototype.createNodesProviderForClass):
        (WebInspector.HeapSnapshot.prototype.createNodesProviderForDominator):
        (WebInspector.HeapSnapshotFilteredOrderedIterator):
        (WebInspector.HeapSnapshotFilteredOrderedIterator.prototype._createIterationOrder):
        (WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.get length):
        (WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.serializeNextItems):
        (WebInspector.HeapSnapshotNodesProvider):
        * inspector/front-end/HeapSnapshotProxy.js:
        (WebInspector.HeapSnapshotProxy.prototype.createNodesProviderForDominator):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (89456 => 89457)


--- trunk/Source/WebCore/ChangeLog	2011-06-22 19:26:46 UTC (rev 89456)
+++ trunk/Source/WebCore/ChangeLog	2011-06-22 19:39:41 UTC (rev 89457)
@@ -1,3 +1,33 @@
+2011-06-20  Mikhail Naganov  <mnaga...@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Web Inspector: [Chromium] Improve speed of heap profiles dominators view.
+        https://bugs.webkit.org/show_bug.cgi?id=62979
+
+        * inspector/front-end/DetailedHeapshotGridNodes.js:
+        (WebInspector.HeapSnapshotDominatorObjectNode.prototype._createProvider):
+        * inspector/front-end/HeapSnapshot.js:
+        (WebInspector.HeapSnapshotArraySlice.prototype.item):
+        (WebInspector.HeapSnapshotArraySlice.prototype.slice):
+        (WebInspector.HeapSnapshot.prototype.dispose):
+        (WebInspector.HeapSnapshot.prototype._dominatedNodesOfNode):
+        (WebInspector.HeapSnapshot.prototype._buildReverseIndex.var):
+        (WebInspector.HeapSnapshot.prototype._buildReverseIndex):
+        (WebInspector.HeapSnapshot.prototype._buildRetainers):
+        (WebInspector.HeapSnapshot.prototype._buildNodeIndex):
+        (WebInspector.HeapSnapshot.prototype._buildDominatedNodes):
+        (WebInspector.HeapSnapshot.prototype._getDominatedIndex):
+        (WebInspector.HeapSnapshot.prototype.createNodesProviderForClass):
+        (WebInspector.HeapSnapshot.prototype.createNodesProviderForDominator):
+        (WebInspector.HeapSnapshotFilteredOrderedIterator):
+        (WebInspector.HeapSnapshotFilteredOrderedIterator.prototype._createIterationOrder):
+        (WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.get length):
+        (WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.serializeNextItems):
+        (WebInspector.HeapSnapshotNodesProvider):
+        * inspector/front-end/HeapSnapshotProxy.js:
+        (WebInspector.HeapSnapshotProxy.prototype.createNodesProviderForDominator):
+
 2011-06-22  Sreeram Ramachandran  <sree...@chromium.org>
 
         Reviewed by Pavel Feldman.

Modified: trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js (89456 => 89457)


--- trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js	2011-06-22 19:26:46 UTC (rev 89456)
+++ trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js	2011-06-22 19:39:41 UTC (rev 89457)
@@ -700,12 +700,9 @@
     _createProvider: function(snapshot, nodeIndex)
     {
         var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData;
-        return snapshot.createNodesProvider(
+        return snapshot.createNodesProviderForDominator(nodeIndex,
             "function (node) {" +
-            "     var dominatorIndex = node.dominatorIndex;" +
-            "     return dominatorIndex === " + nodeIndex + 
-            "         && dominatorIndex !== node.nodeIndex" +
-            "         && (" + showHiddenData + " || !node.isHidden);" +
+            "     return " + showHiddenData + " || !node.isHidden;" +
             "}");
     },
 

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


--- trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2011-06-22 19:26:46 UTC (rev 89456)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2011-06-22 19:39:41 UTC (rev 89457)
@@ -196,6 +196,13 @@
     item: function(index)
     {
         return this._snapshot[this._arrayName][this._start + index];
+    },
+
+    slice: function(start, end)
+    {
+        if (typeof end === "undefined")
+            end = start + this._start + this.length;
+        return this._snapshot[this._arrayName].slice(this._start + start, end);
     }
 }
 
@@ -690,6 +697,8 @@
             this._aggregatesIndexesSorted = false;
         }
         delete this._baseNodeIds;
+        delete this._dominatedNodes;
+        delete this._dominatedIndex;
     },
 
     get _allNodes()
@@ -744,6 +753,16 @@
         return new WebInspector.HeapSnapshotArraySlice(this, "_retainers", retIndexFrom, retIndexTo);
     },
 
+    _dominatedNodesOfNode: function(node)
+    {
+        if (!this._dominatedNodes)
+            this._buildDominatedNodes();
+
+        var dominatedIndexFrom = this._getDominatedIndex(node.nodeIndex);
+        var dominatedIndexTo = this._getDominatedIndex(node._nextNodeIndex);
+        return new WebInspector.HeapSnapshotArraySlice(this, "_dominatedNodes", dominatedIndexFrom, dominatedIndexTo);        
+    },
+
     aggregates: function(sortedIndexes)
     {
         if (!this._aggregates)
@@ -753,45 +772,61 @@
         return this._aggregates;
     },
 
-    _buildRetainers: function()
+    _buildReverseIndex: function(indexArrayName, backRefsArrayName, indexCallback, dataCallback)
     {
         if (!this._nodeIndex)
             this._buildNodeIndex();
 
-        this._retainerIndex = new Array(this._nodeIndex.length);
-        for (var i = 0, l = this._retainerIndex.length; i < l; ++i)
-            this._retainerIndex[i] = 0;
+        // 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 Array(this._nodeIndex.length);
+        for (var i = 0, l = indexArray.length; i < l; ++i)
+            indexArray[i] = 0;
         for (var nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next()) {
-            var node = nodesIter.node;
-            for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next()) {
-                var edge = edgesIter.edge;
-                var nodeIndex = edge.nodeIndex;
-                var position = this._findNodePositionInIndex(nodeIndex);
-                ++this._retainerIndex[position];
-            }
+            indexCallback(nodesIter.node, function (position) { ++indexArray[position]; });
         }
-        var retainerCount = 0;
-        for (i = 0, l = this._retainerIndex.length; i < l; ++i)
-            retainerCount += this._retainerIndex[i];
-        this._retainers = new Array(retainerCount + 1);
-        var retainerPosition = 0;
-        for (i = 0, l = this._retainerIndex.length; i < l; ++i) {
-            retainerCount = this._retainers[retainerPosition] = this._retainerIndex[i];
-            this._retainerIndex[i] = retainerPosition;
-            retainerPosition += retainerCount;
+        var backRefsCount = 0;
+        for (i = 0, l = indexArray.length; i < l; ++i)
+            backRefsCount += indexArray[i];
+        var backRefsArray = this[backRefsArrayName] = new Array(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 (nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next()) {
-            var node = nodesIter.node;
-            for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next()) {
-                var edge = edgesIter.edge;
-                var nodeIndex = edge.nodeIndex;
-                var retIndex = this._getRetainerIndex(nodeIndex);
-                var idx = retIndex + (--this._retainers[retIndex]);
-                this._retainers[idx] = node.nodeIndex + this._firstEdgeOffset + edge.edgeIndex;
-            }
+            dataCallback(nodesIter.node,
+                         function (backRefIndex) { return backRefIndex + (--backRefsArray[backRefIndex]); },
+                         function (backRefIndex, destIndex) { backRefsArray[backRefIndex] = destIndex; });
         }
     },
 
+    _buildRetainers: function()
+    {
+        this._buildReverseIndex(
+            "_retainerIndex",
+            "_retainers",
+            (function (node, callback)
+             {
+                 for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next())
+                     callback(this._findNodePositionInIndex(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));
+    },
+
     _buildAggregates: function()
     {
         this._aggregates = {};
@@ -832,11 +867,10 @@
 
     _buildNodeIndex: function()
     {
-        var count = 0;
-        for (var nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next(), ++count);
+        var count = this.nodeCount;
         this._nodeIndex = new Array(count + 1);
         count = 0;
-        for (nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next(), ++count)
+        for (var nodesIter = this._allNodes; nodesIter.hasNext(); nodesIter.next(), ++count)
             this._nodeIndex[count] = nodesIter.index;
         this._nodeIndex[count] = this._nodes.length;
     },
@@ -865,6 +899,33 @@
         var nodePosition = this._findNodePositionInIndex(nodeIndex);
         return this._retainerIndex[nodePosition];
     },
+
+    _buildDominatedNodes: function()
+    {
+        this._buildReverseIndex(
+            "_dominatedIndex",
+            "_dominatedNodes",
+            (function (node, callback)
+             {
+                 var dominatorIndex = node.dominatorIndex;
+                 if (dominatorIndex !== node.nodeIndex)
+                     callback(this._findNodePositionInIndex(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));
+    },
+
+    _getDominatedIndex: function(nodeIndex)
+    {
+        var nodePosition = this._findNodePositionInIndex(nodeIndex);
+        return this._dominatedIndex[nodePosition];
+    },
   
     _markInvisibleEdges: function()
     {
@@ -937,9 +998,15 @@
 
     createNodesProviderForClass: function(className)
     {
-        return new WebInspector.HeapSnapshotNodesProvider(this, null, className);
+        return new WebInspector.HeapSnapshotNodesProvider(this, null, this.aggregates(false)[className].idxs);
     },
 
+    createNodesProviderForDominator: function(nodeIndex, filter)
+    {
+        var node = new WebInspector.HeapSnapshotNode(this, nodeIndex);
+        return new WebInspector.HeapSnapshotNodesProvider(this, this._parseFilter(filter), this._dominatedNodesOfNode(node));
+    },
+
     createPathFinder: function(targetNodeIndex, skipHidden)
     {
         return new WebInspector.HeapSnapshotPathFinder(this, targetNodeIndex, skipHidden);
@@ -951,11 +1018,12 @@
     }
 };
 
-WebInspector.HeapSnapshotFilteredOrderedIterator = function(iterator, filter, iterationOrder)
+WebInspector.HeapSnapshotFilteredOrderedIterator = function(iterator, filter, unfilteredIterationOrder)
 {
     this._filter = filter;
     this._iterator = iterator;
-    this._iterationOrder = iterationOrder ? iterationOrder.slice(0) : null;
+    this._unfilteredIterationOrder = unfilteredIterationOrder;
+    this._iterationOrder = null;
     this._position = 0;
     this._currentComparator = null;
     this._lastComparator = null;
@@ -964,16 +1032,32 @@
 WebInspector.HeapSnapshotFilteredOrderedIterator.prototype = {
     _createIterationOrder: function()
     {
+        if (this._iterationOrder)
+            return;
+        if (this._unfilteredIterationOrder && !this._filter) {
+            this._iterationOrder = this._unfilteredIterationOrder.slice(0);
+            this._unfilteredIterationOrder = null;
+            return;
+        }
         this._iterationOrder = [];
         var iterator = this._iterator;
-        if (!this._filter) {
+        if (!this._unfilteredIterationOrder && !this._filter) {
             for (iterator.first(); iterator.hasNext(); iterator.next())
                 this._iterationOrder.push(iterator.index);
-        } else {
+        } else if (!this._unfilteredIterationOrder) {
             for (iterator.first(); iterator.hasNext(); iterator.next()) {
                 if (this._filter(iterator.item))
                     this._iterationOrder.push(iterator.index);
             }
+        } else {
+            var order = this._unfilteredIterationOrder.constructor === Array ?
+                this._unfilteredIterationOrder : this._unfilteredIterationOrder.slice(0);
+            for (var i = 0, l = order.length; i < l; ++i) {
+                iterator.index = order[i];
+                if (this._filter(iterator.item))
+                    this._iterationOrder.push(iterator.index);
+            }
+            this._unfilteredIterationOrder = null;
         }
     },
 
@@ -1009,8 +1093,7 @@
 
     get length()
     {
-        if (!this._iterationOrder)
-            this._createIterationOrder();
+        this._createIterationOrder();
         return this._iterationOrder.length;
     },
 
@@ -1021,8 +1104,7 @@
 
     serializeNextItems: function(count)
     {
-        if (!this._iterationOrder)
-            this._createIterationOrder();
+        this._createIterationOrder();
         var result = new Array(count);
         if (this._lastComparator !== this._currentComparator)
             this.sort(this._currentComparator, this._position, this._iterationOrder.length - 1, count);
@@ -1132,13 +1214,10 @@
 
 WebInspector.HeapSnapshotEdgesProvider.prototype.__proto__ = WebInspector.HeapSnapshotFilteredOrderedIterator.prototype;
 
-WebInspector.HeapSnapshotNodesProvider = function(snapshot, filter, className)
+WebInspector.HeapSnapshotNodesProvider = function(snapshot, filter, nodeIndexes)
 {
     this.snapshot = snapshot;
-    if (!className)
-        WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, snapshot._allNodes, filter);
-    else
-        WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, snapshot._allNodes, null, snapshot.aggregates(false)[className].idxs);
+    WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, snapshot._allNodes, filter, nodeIndexes);
 }
 
 WebInspector.HeapSnapshotNodesProvider.prototype = {

Modified: trunk/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js (89456 => 89457)


--- trunk/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js	2011-06-22 19:26:46 UTC (rev 89456)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js	2011-06-22 19:39:41 UTC (rev 89457)
@@ -305,6 +305,11 @@
         return this.callFactoryMethod(null, "createNodesProviderForClass", "WebInspector.HeapSnapshotProviderProxy", className);
     },
 
+    createNodesProviderForDominator: function(nodeIndex, filter)
+    {
+        return this.callFactoryMethod(null, "createNodesProviderForDominator", "WebInspector.HeapSnapshotProviderProxy", nodeIndex, filter);
+    },
+
     createPathFinder: function(targetNodeIndex)
     {
         return this.callFactoryMethod(null, "createPathFinder", "WebInspector.HeapSnapshotPathFinderProxy", targetNodeIndex);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to