Changeset 107106 in webkit


Ignore:
Timestamp:
Feb 8, 2012 10:49:55 AM (12 years ago)
Author:
loislo@chromium.org
Message:

Web Inspector: heap snapshot: implement Distance column in Object's retaining tree.
https://bugs.webkit.org/show_bug.cgi?id=78113

Retaining path list was replaced with Retaining tree some time ago.
But it was not so useful when we want to track the retaining path from an object to a DOM Window node.

Drive by fix: sort doesn't work in retaining tree panel.
Drive by fix: save/load child nodes doesn't work for the retaining tree panel.

Reviewed by Yury Semikhatsky.

  • inspector/front-end/DetailedHeapshotGridNodes.js:

(WebInspector.HeapSnapshotObjectNode):
(WebInspector.HeapSnapshotObjectNode.prototype._childHashForEntity): save/load children fix
(WebInspector.HeapSnapshotObjectNode.prototype._childHashForNode): save/load children fix
(WebInspector.HeapSnapshotObjectNode.prototype.comparator):
(WebInspector.HeapSnapshotObjectNode.prototype._enhanceData):

  • inspector/front-end/DetailedHeapshotView.js:

(WebInspector.HeapSnapshotContainmentDataGrid):
(WebInspector.HeapSnapshotRetainmentDataGrid):
(WebInspector.HeapSnapshotRetainmentDataGrid.prototype._sortFields):

  • inspector/front-end/HeapSnapshot.js:

(WebInspector.HeapSnapshotRetainerEdge.prototype.set retainerIndex):
(WebInspector.HeapSnapshotRetainerEdge.prototype.set edgeIndex):
(WebInspector.HeapSnapshotRetainerEdge.prototype.get _node):
(WebInspector.HeapSnapshotRetainerEdge.prototype.get _edge):
(WebInspector.HeapSnapshotNode.prototype.get distanceToWindow):
(WebInspector.HeapSnapshot.prototype._init):
(WebInspector.HeapSnapshot.prototype._buildRetainers):
(WebInspector.HeapSnapshot.prototype._calculateObjectToWindowDistance):
(WebInspector.HeapSnapshot.prototype._bfs):
(WebInspector.HeapSnapshotEdgesProvider.prototype._serialize):
(WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareEdgeFieldName):
(WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareNodeField):
(WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareEdgeAndNode):
(WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareNodeAndEdge):
(WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareNodeAndNode):
(WebInspector.HeapSnapshotEdgesProvider.prototype.sort):
(WebInspector.HeapSnapshotNodesProvider.prototype._serialize):

  • inspector/front-end/heapProfiler.css:

(.detailed-heapshot-view .data-grid td.distanceToWindow-column):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r107102 r107106  
     12012-02-08  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Web Inspector: heap snapshot: implement Distance column in Object's retaining tree.
     4        https://bugs.webkit.org/show_bug.cgi?id=78113
     5
     6        Retaining path list was replaced with Retaining tree some time ago.
     7        But it was not so useful when we want to track the retaining path from an object to a DOM Window node.
     8
     9        Drive by fix: sort doesn't work in retaining tree panel.
     10        Drive by fix: save/load child nodes doesn't work for the retaining tree panel.
     11
     12        Reviewed by Yury Semikhatsky.
     13
     14        * inspector/front-end/DetailedHeapshotGridNodes.js:
     15        (WebInspector.HeapSnapshotObjectNode):
     16        (WebInspector.HeapSnapshotObjectNode.prototype._childHashForEntity): save/load children fix
     17        (WebInspector.HeapSnapshotObjectNode.prototype._childHashForNode): save/load children fix
     18        (WebInspector.HeapSnapshotObjectNode.prototype.comparator):
     19        (WebInspector.HeapSnapshotObjectNode.prototype._enhanceData):
     20        * inspector/front-end/DetailedHeapshotView.js:
     21        (WebInspector.HeapSnapshotContainmentDataGrid):
     22        (WebInspector.HeapSnapshotRetainmentDataGrid):
     23        (WebInspector.HeapSnapshotRetainmentDataGrid.prototype._sortFields):
     24        * inspector/front-end/HeapSnapshot.js:
     25        (WebInspector.HeapSnapshotRetainerEdge.prototype.set retainerIndex):
     26        (WebInspector.HeapSnapshotRetainerEdge.prototype.set edgeIndex):
     27        (WebInspector.HeapSnapshotRetainerEdge.prototype.get _node):
     28        (WebInspector.HeapSnapshotRetainerEdge.prototype.get _edge):
     29        (WebInspector.HeapSnapshotNode.prototype.get distanceToWindow):
     30        (WebInspector.HeapSnapshot.prototype._init):
     31        (WebInspector.HeapSnapshot.prototype._buildRetainers):
     32        (WebInspector.HeapSnapshot.prototype._calculateObjectToWindowDistance):
     33        (WebInspector.HeapSnapshot.prototype._bfs):
     34        (WebInspector.HeapSnapshotEdgesProvider.prototype._serialize):
     35        (WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareEdgeFieldName):
     36        (WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareNodeField):
     37        (WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareEdgeAndNode):
     38        (WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareNodeAndEdge):
     39        (WebInspector.HeapSnapshotEdgesProvider.prototype.sort.compareNodeAndNode):
     40        (WebInspector.HeapSnapshotEdgesProvider.prototype.sort):
     41        (WebInspector.HeapSnapshotNodesProvider.prototype._serialize):
     42        * inspector/front-end/heapProfiler.css:
     43        (.detailed-heapshot-view .data-grid td.distanceToWindow-column):
     44
    1452012-02-08  Anders Carlsson  <andersca@apple.com>
    246
  • trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js

    r107089 r107106  
    372372    this._referenceType = edge.type;
    373373    this._propertyAccessor = edge.propertyAccessor;
     374    this._distanceToWindow = edge.distanceToWindow;
    374375    this.showRetainingEdges = tree.showRetainingEdges;
    375376    this._isFromBaseSnapshot = isFromBaseSnapshot;
     
    416417    _childHashForEntity: function(edge)
    417418    {
    418         return edge.type + "#" + edge.name;
     419        var prefix = this.showRetainingEdges ? edge.node.id + "#" : "";
     420        return prefix + edge.type + "#" + edge.name;
    419421    },
    420422
    421423    _childHashForNode: function(childNode)
    422424    {
    423         return childNode._referenceType + "#" + childNode._referenceName;
     425        var prefix = this.showRetainingEdges ? childNode.snapshotNodeId + "#" : "";
     426        return prefix + childNode._referenceType + "#" + childNode._referenceName;
    424427    },
    425428
     
    432435            count: ["!edgeName", true, "retainedSize", false],
    433436            shallowSize: ["selfSize", sortAscending, "!edgeName", true],
    434             retainedSize: ["retainedSize", sortAscending, "!edgeName", true]
     437            retainedSize: ["retainedSize", sortAscending, "!edgeName", true],
     438            distanceToWindow: ["distanceToWindow", sortAscending, "_name", true]
    435439        }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
    436440        return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
     
    461465        data["object"].nameClass = nameClass;
    462466        data["object"].name = name;
     467        data["distanceToWindow"] = this._distanceToWindow;
    463468        return data;
    464469    },
  • trunk/Source/WebCore/inspector/front-end/DetailedHeapshotView.js

    r107089 r107106  
    113113WebInspector.HeapSnapshotSortableDataGrid.prototype.__proto__ = WebInspector.DataGrid.prototype;
    114114
    115 WebInspector.HeapSnapshotContainmentDataGrid = function()
     115WebInspector.HeapSnapshotContainmentDataGrid = function(columns)
    116116{
    117     var columns = {
     117    columns = columns || {
    118118        object: { title: WebInspector.UIString("Object"), disclosure: true, sortable: true },
    119119        shallowSize: { title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true },
     
    184184{
    185185    this.showRetainingEdges = true;
    186     WebInspector.HeapSnapshotContainmentDataGrid.call(this);
     186    var columns = {
     187        object: { title: WebInspector.UIString("Object"), disclosure: true, sortable: true },
     188        shallowSize: { title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true },
     189        retainedSize: { title: WebInspector.UIString("Retained Size"), width: "120px", sortable: true },
     190        distanceToWindow: { title: WebInspector.UIString("Distance"), width: "80px", sortable: true, sort: "ascending" }
     191    };
     192    WebInspector.HeapSnapshotContainmentDataGrid.call(this, columns);
    187193}
    188194
    189195WebInspector.HeapSnapshotRetainmentDataGrid.prototype = {
     196    _sortFields: function(sortColumn, sortAscending)
     197    {
     198        return {
     199            object: ["_name", sortAscending, "_count", false],
     200            count: ["_count", sortAscending, "_name", true],
     201            shallowSize: ["_shallowSize", sortAscending, "_name", true],
     202            retainedSize: ["_retainedSize", sortAscending, "_name", true],
     203            distanceToWindow: ["_distanceToWindow", sortAscending, "_name", true]
     204        }[sortColumn];
     205    },
     206
    190207    reset: function()
    191208    {
  • trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js

    r106928 r107106  
    437437        if (newIndex !== this._retainerIndex) {
    438438            this._retainerIndex = newIndex;
    439             this._setupEdge();
    440         }
    441     },
    442 
    443     _setupEdge: function()
    444     {
    445         var globalEdgeIndex = this._retainers.item(this._retainerIndex);
    446         this._nodeIndex = this._snapshot._findNearestNodeIndex(globalEdgeIndex);
    447         this._node = new WebInspector.HeapSnapshotNode(this._snapshot, this._nodeIndex);
    448         var edgeIndex = globalEdgeIndex - this._nodeIndex - this._snapshot._firstEdgeOffset;
    449         this._edge = new WebInspector.HeapSnapshotEdge(this._snapshot, this._node.rawEdges, edgeIndex);
     439            this.edgeIndex = newIndex;
     440        }
     441    },
     442
     443    set edgeIndex(edgeIndex)
     444    {
     445        this._globalEdgeIndex = this._retainers.item(edgeIndex);
     446        this._nodeIndex = this._snapshot._findNearestNodeIndex(this._globalEdgeIndex);
     447        delete this._edgeInstance;
     448        delete this._nodeInstance;
     449    },
     450
     451    get _node()
     452    {
     453        if (!this._nodeInstance)
     454            this._nodeInstance = new WebInspector.HeapSnapshotNode(this._snapshot, this._nodeIndex);
     455        return this._nodeInstance;
     456    },
     457
     458    get _edge()
     459    {
     460        if (!this._edgeInstance) {
     461            var edgeIndex = this._globalEdgeIndex - this._nodeIndex - this._snapshot._firstEdgeOffset;
     462            this._edgeInstance = new WebInspector.HeapSnapshotEdge(this._snapshot, this._node.rawEdges, edgeIndex);
     463        }
     464        return this._edgeInstance;
    450465    },
    451466
     
    510525        var flags = this._snapshot._flagsOfNode(this);
    511526        return !!(flags & this._snapshot._nodeFlags.canBeQueried);
     527    },
     528
     529    get distanceToWindow()
     530    {
     531        return this._snapshot._distancesToWindow[this.nodeIndex];
    512532    },
    513533
     
    732752        };
    733753
     754        this._distancesToWindow = [];
    734755        this._markInvisibleEdges();
    735756    },
     
    918939                 }
    919940             }).bind(this));
     941        this._calculateObjectToWindowDistance();
     942    },
     943
     944    _calculateObjectToWindowDistance: function()
     945    {
     946        this._distancesToWindow = new Array(this.nodeCount);
     947
     948        // bfs for DOMWindow roots
     949        var list = [];
     950        for (var iter = this.rootNode.edges; iter.hasNext(); iter.next()) {
     951            if (iter.edge.node.isDOMWindow) {
     952                list.push(iter.edge.node);
     953                this._distancesToWindow[iter.edge.node.nodeIndex] = 0;
     954            }
     955        }
     956        this._bfs(list);
     957
     958        // bfs for root
     959        list = [];
     960        list.push(this.rootNode);
     961        this._distancesToWindow[this.rootNode.nodeIndex] = 0;
     962        this._bfs(list);
     963    },
     964
     965    _bfs: function(list)
     966    {
     967        var index = 0;
     968        while (index < list.length) {
     969            var node = list[index++]; // shift generates too much garbage.
     970            if (index > 100000) {
     971                list = list.slice(index);
     972                index = 0;
     973            }
     974            var distance = this._distancesToWindow[node.nodeIndex] + 1;
     975            for (var iter = node.edges; iter.hasNext(); iter.next()) {
     976                var edge = iter.edge;
     977                var childNode = edge.node;
     978                if (typeof this._distancesToWindow[childNode.nodeIndex] !== "undefined")
     979                    continue;
     980                this._distancesToWindow[childNode.nodeIndex] = distance;
     981                list.push(childNode);
     982            }
     983        }
    920984    },
    921985
     
    13531417    _serialize: function(edge)
    13541418    {
    1355         return {name: edge.name, propertyAccessor: edge.toString(), node: WebInspector.HeapSnapshotNodesProvider.prototype._serialize(edge.node), nodeIndex: edge.nodeIndex, type: edge.type};
     1419        return {
     1420            name: edge.name,
     1421            propertyAccessor: edge.toString(),
     1422            node: WebInspector.HeapSnapshotNodesProvider.prototype._serialize(edge.node),
     1423            nodeIndex: edge.nodeIndex,
     1424            type: edge.type,
     1425            distanceToWindow: edge.node.distanceToWindow
     1426        };
    13561427    },
    13571428
     
    13681439        var nodeB = new WebInspector.HeapSnapshotNode(this.snapshot);
    13691440
    1370         function sortByEdgeFieldName(ascending, indexA, indexB)
     1441        function compareEdgeFieldName(ascending, indexA, indexB)
    13711442        {
    13721443            edgeA.edgeIndex = indexA;
     
    13811452        }
    13821453
    1383         function sortByNodeField(fieldName, ascending, indexA, indexB)
     1454        function compareNodeField(fieldName, ascending, indexA, indexB)
    13841455        {
    13851456            edgeA.edgeIndex = indexA;
     1457            nodeA.nodeIndex = edgeA.nodeIndex;
     1458            var valueA = nodeA[fieldName];
     1459
    13861460            edgeB.edgeIndex = indexB;
    1387             nodeA.nodeIndex = edgeA.nodeIndex;
    13881461            nodeB.nodeIndex = edgeB.nodeIndex;
    1389             var valueA = nodeA[fieldName];
    13901462            var valueB = nodeB[fieldName];
     1463
    13911464            var result = valueA < valueB ? -1 : (valueA > valueB ? 1 : 0);
    13921465            return ascending ? result : -result;
    13931466        }
    13941467
    1395         function sortByEdgeAndNode(indexA, indexB) {
    1396             var result = sortByEdgeFieldName(ascending1, indexA, indexB);
     1468        function compareEdgeAndNode(indexA, indexB) {
     1469            var result = compareEdgeFieldName(ascending1, indexA, indexB);
    13971470            if (result === 0)
    1398                 result = sortByNodeField(fieldName2, ascending2, indexA, indexB);
     1471                result = compareNodeField(fieldName2, ascending2, indexA, indexB);
    13991472            return result;
    14001473        }
    14011474
    1402         function sortByNodeAndEdge(indexA, indexB) {
    1403             var result = sortByNodeField(fieldName1, ascending1, indexA, indexB);
     1475        function compareNodeAndEdge(indexA, indexB) {
     1476            var result = compareNodeField(fieldName1, ascending1, indexA, indexB);
    14041477            if (result === 0)
    1405                 result = sortByEdgeFieldName(ascending2, indexA, indexB);
     1478                result = compareEdgeFieldName(ascending2, indexA, indexB);
    14061479            return result;
    14071480        }
    14081481
    1409         function sortByNodeAndNode(indexA, indexB) {
    1410             var result = sortByNodeField(fieldName1, ascending1, indexA, indexB);
     1482        function compareNodeAndNode(indexA, indexB) {
     1483            var result = compareNodeField(fieldName1, ascending1, indexA, indexB);
    14111484            if (result === 0)
    1412                 result = sortByNodeField(fieldName2, ascending2, indexA, indexB);
     1485                result = compareNodeField(fieldName2, ascending2, indexA, indexB);
    14131486            return result;
    14141487        }
    14151488
    14161489        if (fieldName1 === "!edgeName")
    1417             this._iterationOrder.sortRange(sortByEdgeAndNode, leftBound, rightBound, count);
     1490            this._iterationOrder.sortRange(compareEdgeAndNode, leftBound, rightBound, count);
    14181491        else if (fieldName2 === "!edgeName")
    1419             this._iterationOrder.sortRange(sortByNodeAndEdge, leftBound, rightBound, count);
     1492            this._iterationOrder.sortRange(compareNodeAndEdge, leftBound, rightBound, count);
    14201493        else
    1421             this._iterationOrder.sortRange(sortByNodeAndNode, leftBound, rightBound, count);
     1494            this._iterationOrder.sortRange(compareNodeAndNode, leftBound, rightBound, count);
    14221495    }
    14231496};
     
    14341507    _serialize: function(node)
    14351508    {
    1436         return {id: node.id, name: node.name, nodeIndex: node.nodeIndex, retainedSize: node.retainedSize, selfSize: node.selfSize, type: node.type, flags: node.flags};
     1509        return {
     1510            id: node.id,
     1511            name: node.name,
     1512            nodeIndex: node.nodeIndex,
     1513            retainedSize: node.retainedSize,
     1514            selfSize: node.selfSize,
     1515            type: node.type,
     1516            flags: node.flags
     1517        };
    14371518    },
    14381519
  • trunk/Source/WebCore/inspector/front-end/heapProfiler.css

    r106808 r107106  
    116116}
    117117
     118.detailed-heapshot-view .data-grid td.distanceToWindow-column {
     119    text-align: right;
     120}
     121
    118122.detailed-heapshot-view .data-grid span.percent-column {
    119123    color: grey;
Note: See TracChangeset for help on using the changeset viewer.