Title: [137742] trunk/Source
Revision
137742
Author
yu...@chromium.org
Date
2012-12-14 06:10:00 -0800 (Fri, 14 Dec 2012)

Log Message

Web Inspector: add data grid for exploring native heap graph
https://bugs.webkit.org/show_bug.cgi?id=105012

Reviewed by Pavel Feldman.

Source/WebCore:

Added a view for displaying native heap graph nodes.

* inspector/HeapGraphSerializer.cpp:
(WebCore::HeapGraphSerializer::reportEdge):
* inspector/front-end/NativeMemorySnapshotView.js:
(WebInspector.NativeMemorySnapshotView):
(WebInspector.NativeMemorySnapshotView.prototype._onSelectedViewChanged):
(WebInspector.NativeMemorySnapshotView.prototype.get statusBarItems):
(WebInspector.NativeHeapGraphNode):
(WebInspector.NativeHeapGraphNode.prototype.id):
(WebInspector.NativeHeapGraphNode.prototype.type):
(WebInspector.NativeHeapGraphNode.prototype.size):
(WebInspector.NativeHeapGraphNode.prototype.className):
(WebInspector.NativeHeapGraphNode.prototype.name):
(WebInspector.NativeHeapGraphNode.prototype.hasReferencedNodes):
(WebInspector.NativeHeapGraphNode.prototype.referencedNodes):
(WebInspector.NativeHeapGraphNode.prototype._firstEdgePoistion):
(WebInspector.NativeHeapGraphNode.prototype._afterLastEdgePosition):
(WebInspector.NativeHeapGraphNode.prototype._getStringField):
(WebInspector.NativeHeapGraph):
(WebInspector.NativeHeapGraph.prototype.rootNodes):
(WebInspector.NativeHeapGraph.prototype._calculateNodeEdgeIndexes):
(WebInspector.NativeHeapGraphDataGrid):
(WebInspector.NativeHeapGraphDataGridRoot):
(WebInspector.NativeHeapGraphDataGridRoot.prototype._populate):
(WebInspector.NativeHeapGraphDataGridNode):
(WebInspector.NativeHeapGraphDataGridNode.prototype._populate):
(WebInspector.NativeMemoryProfileType.prototype.buttonClicked.didReceiveMemorySnapshot):
(WebInspector.NativeMemoryProfileType.prototype.buttonClicked):

Source/WTF:

Do not report edges with null target.

* wtf/MemoryInstrumentation.h:
(WTF::MemoryInstrumentation::addObjectImpl):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (137741 => 137742)


--- trunk/Source/WTF/ChangeLog	2012-12-14 13:54:22 UTC (rev 137741)
+++ trunk/Source/WTF/ChangeLog	2012-12-14 14:10:00 UTC (rev 137742)
@@ -1,3 +1,15 @@
+2012-12-14  Yury Semikhatsky  <yu...@chromium.org>
+
+        Web Inspector: add data grid for exploring native heap graph
+        https://bugs.webkit.org/show_bug.cgi?id=105012
+
+        Reviewed by Pavel Feldman.
+
+        Do not report edges with null target.
+
+        * wtf/MemoryInstrumentation.h:
+        (WTF::MemoryInstrumentation::addObjectImpl):
+
 2012-12-13  Filip Pizlo  <fpi...@apple.com>
 
         Attempt to rationalize and simplify WTF::binarySearch

Modified: trunk/Source/WTF/wtf/MemoryInstrumentation.h (137741 => 137742)


--- trunk/Source/WTF/wtf/MemoryInstrumentation.h	2012-12-14 13:54:22 UTC (rev 137741)
+++ trunk/Source/WTF/wtf/MemoryInstrumentation.h	2012-12-14 14:10:00 UTC (rev 137742)
@@ -233,8 +233,10 @@
     if (owningType == byReference)
         reportMemoryUsage(object, ownerObjectInfo);
     else {
+        if (!object)
+            return;
         reportEdge(ownerObjectInfo, object, edgeName);
-        if (!object || visited(object))
+        if (visited(object))
             return;
         deferObject(adoptPtr(new Wrapper<T>(object, getObjectType(ownerObjectInfo))));
     }

Modified: trunk/Source/WebCore/ChangeLog (137741 => 137742)


--- trunk/Source/WebCore/ChangeLog	2012-12-14 13:54:22 UTC (rev 137741)
+++ trunk/Source/WebCore/ChangeLog	2012-12-14 14:10:00 UTC (rev 137742)
@@ -1,3 +1,40 @@
+2012-12-14  Yury Semikhatsky  <yu...@chromium.org>
+
+        Web Inspector: add data grid for exploring native heap graph
+        https://bugs.webkit.org/show_bug.cgi?id=105012
+
+        Reviewed by Pavel Feldman.
+
+        Added a view for displaying native heap graph nodes.
+
+        * inspector/HeapGraphSerializer.cpp:
+        (WebCore::HeapGraphSerializer::reportEdge):
+        * inspector/front-end/NativeMemorySnapshotView.js:
+        (WebInspector.NativeMemorySnapshotView):
+        (WebInspector.NativeMemorySnapshotView.prototype._onSelectedViewChanged):
+        (WebInspector.NativeMemorySnapshotView.prototype.get statusBarItems):
+        (WebInspector.NativeHeapGraphNode):
+        (WebInspector.NativeHeapGraphNode.prototype.id):
+        (WebInspector.NativeHeapGraphNode.prototype.type):
+        (WebInspector.NativeHeapGraphNode.prototype.size):
+        (WebInspector.NativeHeapGraphNode.prototype.className):
+        (WebInspector.NativeHeapGraphNode.prototype.name):
+        (WebInspector.NativeHeapGraphNode.prototype.hasReferencedNodes):
+        (WebInspector.NativeHeapGraphNode.prototype.referencedNodes):
+        (WebInspector.NativeHeapGraphNode.prototype._firstEdgePoistion):
+        (WebInspector.NativeHeapGraphNode.prototype._afterLastEdgePosition):
+        (WebInspector.NativeHeapGraphNode.prototype._getStringField):
+        (WebInspector.NativeHeapGraph):
+        (WebInspector.NativeHeapGraph.prototype.rootNodes):
+        (WebInspector.NativeHeapGraph.prototype._calculateNodeEdgeIndexes):
+        (WebInspector.NativeHeapGraphDataGrid):
+        (WebInspector.NativeHeapGraphDataGridRoot):
+        (WebInspector.NativeHeapGraphDataGridRoot.prototype._populate):
+        (WebInspector.NativeHeapGraphDataGridNode):
+        (WebInspector.NativeHeapGraphDataGridNode.prototype._populate):
+        (WebInspector.NativeMemoryProfileType.prototype.buttonClicked.didReceiveMemorySnapshot):
+        (WebInspector.NativeMemoryProfileType.prototype.buttonClicked):
+
 2012-12-14  Ilya Tikhonovsky  <loi...@chromium.org>
 
         Web Inspector: Native Memory Instrumentation: do not validate InlineFlowBox objects against tcmalloc data.

Modified: trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp (137741 => 137742)


--- trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp	2012-12-14 13:54:22 UTC (rev 137741)
+++ trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp	2012-12-14 14:10:00 UTC (rev 137742)
@@ -109,6 +109,7 @@
 void HeapGraphSerializer::reportEdge(const void*, const void* to, const char* name)
 {
     HeapGraphEdge edge;
+    ASSERT(to);
     edge.m_toObject = to;
     edge.m_name = addString(name);
     m_edges.append(edge);

Modified: trunk/Source/WebCore/inspector/compile-front-end.py (137741 => 137742)


--- trunk/Source/WebCore/inspector/compile-front-end.py	2012-12-14 13:54:22 UTC (rev 137741)
+++ trunk/Source/WebCore/inspector/compile-front-end.py	2012-12-14 14:10:00 UTC (rev 137742)
@@ -431,4 +431,4 @@
     os.system("rm " + inspector_path + "/" + "InjectedScriptCanvasModuleSourceTmp.js")
 
 shutil.rmtree(modules_dir)
-os.system("rm " + protocol_externs_path)
+#os.system("rm " + protocol_externs_path)

Modified: trunk/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js (137741 => 137742)


--- trunk/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js	2012-12-14 13:54:22 UTC (rev 137741)
+++ trunk/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js	2012-12-14 14:10:00 UTC (rev 137742)
@@ -39,14 +39,54 @@
     this.registerRequiredCSS("nativeMemoryProfiler.css");
 
     this.element.addStyleClass("native-snapshot-view");
-    this.containmentDataGrid = new WebInspector.NativeSnapshotDataGrid(profile._memoryBlock);
-    this.containmentDataGrid.show(this.element);
+    this._containmentDataGrid = new WebInspector.NativeSnapshotDataGrid(profile._memoryBlock);
+    this._containmentDataGrid.show(this.element);
+
+    this._heapGraphDataGrid = new WebInspector.NativeHeapGraphDataGrid(new WebInspector.NativeHeapGraph(profile._graph));
+
+    this._viewSelectElement = document.createElement("select");
+    this._viewSelectElement.className = "status-bar-item";
+    this._viewSelectElement.addEventListener("change", this._onSelectedViewChanged.bind(this), false);
+
+    this._views = [{title: "Aggregated", view: this._containmentDataGrid},
+                  {title: "Graph", view: this._heapGraphDataGrid}];
+    this._currentViewIndex = 0;
+    for (var i = 0; i < this._views.length; ++i) {
+        var view = this._views[i];
+        var option = document.createElement("option");
+        option.label = WebInspector.UIString(view.title);
+        this._viewSelectElement.appendChild(option);
+    }
 }
 
 WebInspector.NativeMemorySnapshotView.prototype = {
+    _onSelectedViewChanged: function(event)
+    {
+        var index = event.target.selectedIndex;
+        if (index === this._currentViewIndex)
+            return;
+
+        var currentView = this._views[this._currentViewIndex].view;
+        currentView.detach();
+
+        this._currentViewIndex = index;
+        var selectedView = this._views[index].view;
+        selectedView.show(this.element);
+    },
+
+    get statusBarItems()
+    {
+        var span = document.createElement("span");
+        span.className = "status-bar-select-container";
+        span.appendChild(this._viewSelectElement);
+        return [span];
+    },
+
     __proto__: WebInspector.View.prototype
 }
 
+
+
 /**
  * @constructor
  * @extends {WebInspector.DataGrid}
@@ -229,8 +269,231 @@
     __proto__: WebInspector.DataGridNode.prototype
 }
 
+
 /**
  * @constructor
+ * @param {WebInspector.NativeHeapGraph} graph
+ * @param {number} position
+ */
+WebInspector.NativeHeapGraphNode = function(graph, position)
+{
+    this._graph = graph;
+    this._position = position;
+}
+
+WebInspector.NativeHeapGraphNode.prototype = {
+    id: function()
+    {
+        return this._position / this._graph._nodeFieldCount;
+    },
+
+    type: function()
+    {
+        return this._getStringField(this._graph._nodeTypeOffset);
+    },
+
+    size: function()
+    {
+        return this._graph._rawGraph.nodes[this._position + this._graph._nodeSizeOffset];
+    },
+
+    className: function()
+    {
+        return this._getStringField(this._graph._nodeClassNameOffset);
+    },
+
+    name: function()
+    {
+        return this._getStringField(this._graph._nodeNameOffset);
+    },
+
+    hasReferencedNodes: function()
+    {
+        return this._afterLastEdgePosition() > this._firstEdgePoistion();
+    },
+
+    referencedNodes: function()
+    {
+        var edges = this._graph._rawGraph.edges;
+        var nodes = this._graph._rawGraph.nodes;
+        var edgeFieldCount = this._graph._edgeFieldCount;
+        var nodeFieldCount = this._graph._nodeFieldCount;
+
+        var firstEdgePosition = this._firstEdgePoistion();
+        var afterLastEdgePosition = this._afterLastEdgePosition();
+        var result = [];
+        for (var i = firstEdgePosition + this._graph._edgeTargetOffset; i < afterLastEdgePosition; i += edgeFieldCount)
+            result.push(new WebInspector.NativeHeapGraphNode(this._graph, edges[i] * nodeFieldCount));
+        return result;
+    },
+
+    _firstEdgePoistion: function()
+    {
+        return this._graph._rawGraph.nodes[this._position + this._graph._nodeFirstEdgeOffset] * this._graph._edgeFieldCount;
+    },
+
+    _afterLastEdgePosition: function()
+    {
+        var edges = this._graph._rawGraph.edges;
+        var nodes = this._graph._rawGraph.nodes;
+        var afterLastEdgePosition = nodes[this._position + this._graph._nodeFieldCount + this._graph._nodeFirstEdgeOffset];
+        if (afterLastEdgePosition)
+            afterLastEdgePosition *= this._graph._edgeFieldCount;
+        else
+            afterLastEdgePosition = edges.length;
+        return afterLastEdgePosition;
+    },
+
+    _getStringField: function(offset)
+    {
+        var typeIndex = this._graph._rawGraph.nodes[this._position + offset];
+        return this._graph._rawGraph.strings[typeIndex];
+    }
+}
+
+
+/**
+ * @constructor
+ */
+WebInspector.NativeHeapGraph = function(rawGraph)
+{
+    this._rawGraph = rawGraph;
+
+    this._nodeFieldCount = 5;
+    this._nodeTypeOffset = 0;
+    this._nodeSizeOffset = 1;
+    this._nodeClassNameOffset = 2;
+    this._nodeNameOffset = 3;
+    this._nodeEdgeCountOffset = 4;
+    this._nodeFirstEdgeOffset = this._nodeEdgeCountOffset;
+
+    this._edgeFieldCount = 3;
+    this._edgeTypeOffset = 0;
+    this._edgeTargetOffset = 1;
+    this._edgeNameOffset = 2;
+
+    this._calculateNodeEdgeIndexes();
+}
+
+WebInspector.NativeHeapGraph.prototype = {
+    rootNodes: function()
+    {
+        var nodeHasIncomingEdges = new Uint8Array(this._rawGraph.nodes.length / this._nodeFieldCount);
+        var edges = this._rawGraph.edges;
+        var edgesLength = edges.length;
+        var edgeFieldCount = this._edgeFieldCount;
+        var nodeFieldCount = this._nodeFieldCount;
+        for (var i = this._edgeTargetOffset; i < edgesLength; i += edgeFieldCount) {
+            var targetIndex = edges[i];
+            nodeHasIncomingEdges[targetIndex] = 1;
+        }
+        var roots = [];
+        var nodeCount = nodeHasIncomingEdges.length;
+        for (var i = 0; i < nodeCount; i++) {
+            if (!nodeHasIncomingEdges[i])
+                roots.push(new WebInspector.NativeHeapGraphNode(this, i * nodeFieldCount));
+        }
+        return roots;
+    },
+
+    _calculateNodeEdgeIndexes: function()
+    {
+        var nodes = this._rawGraph.nodes;
+        var nodeFieldCount = this._nodeFieldCount;
+        var nodeLength = nodes.length;
+        var firstEdgeIndex = 0;
+        for (var i = this._nodeEdgeCountOffset; i < nodeLength; i += nodeFieldCount) {
+            var count = nodes[i];
+            nodes[i] = firstEdgeIndex;
+            firstEdgeIndex += count;
+        }
+    }
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.DataGrid}
+ * @param {WebInspector.NativeHeapGraph} nativeHeapGraph
+ */
+WebInspector.NativeHeapGraphDataGrid = function(nativeHeapGraph)
+{
+    var columns = {
+        id: { title: WebInspector.UIString("id"), width: "80px", disclosure: true, sortable: true },
+        type: { title: WebInspector.UIString("Type"), width: "200px", sortable: true },
+        className: { title: WebInspector.UIString("Class name"), width: "200px", sortable: true },
+        name: { title: WebInspector.UIString("Name"), width: "200px", sortable: true },
+        size: { title: WebInspector.UIString("Size"), sortable: true, sort: "descending" },
+    };
+    WebInspector.DataGrid.call(this, columns);
+    this._nativeHeapGraph = nativeHeapGraph;
+    this._root = new WebInspector.NativeHeapGraphDataGridRoot(this._nativeHeapGraph);
+    this.setRootNode(this._root);
+    this._root._populate();
+}
+
+WebInspector.NativeHeapGraphDataGrid.prototype = {
+    __proto__: WebInspector.DataGrid.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.DataGridNode}
+ * @param {WebInspector.NativeHeapGraph} graph
+ */
+WebInspector.NativeHeapGraphDataGridRoot = function(graph)
+{
+    WebInspector.DataGridNode.call(this, { id: "root" }, true);
+    this._graph = graph;
+    this.addEventListener("populate", this._populate, this);
+}
+
+WebInspector.NativeHeapGraphDataGridRoot.prototype = {
+    _populate: function() {
+        this.removeEventListener("populate", this._populate, this);
+        var roots = this._graph.rootNodes();
+        for (var i = 0; i < roots.length; i++)
+            this.appendChild(new WebInspector.NativeHeapGraphDataGridNode(roots[i]));
+    },
+
+    __proto__: WebInspector.DataGridNode.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.DataGridNode}
+ * @param {WebInspector.NativeHeapGraphNode} node
+ */
+WebInspector.NativeHeapGraphDataGridNode = function(node)
+{
+    var data = {
+        id: node.id(),
+        size: node.size(),
+        type: node.type(),
+        className: node.className(),
+        name: node.name(),
+    };
+    WebInspector.DataGridNode.call(this, data, node.hasReferencedNodes());
+    this._node = node;
+    this.addEventListener("populate", this._populate, this);
+}
+
+WebInspector.NativeHeapGraphDataGridNode.prototype = {
+    _populate: function() {
+        this.removeEventListener("populate", this._populate, this);
+        var children = this._node.referencedNodes();
+        for (var i = 0; i < children.length; i++)
+            this.appendChild(new WebInspector.NativeHeapGraphDataGridNode(children[i]));
+    },
+
+    __proto__: WebInspector.DataGridNode.prototype
+}
+
+
+/**
+ * @constructor
  * @extends {WebInspector.ProfileType}
  */
 WebInspector.NativeMemoryProfileType = function()
@@ -258,7 +521,12 @@
         ++this._nextProfileUid;
         profileHeader.isTemporary = true;
         profilesPanel.addProfileHeader(profileHeader);
-        function didReceiveMemorySnapshot(error, memoryBlock)
+        /**
+         * @param {?string} error
+         * @param {?MemoryAgent.MemoryBlock} memoryBlock
+         * @param {?Object=} graph
+         */
+        function didReceiveMemorySnapshot(error, memoryBlock, graph)
         {
             if (memoryBlock.size && memoryBlock.children) {
                 var knownSize = 0;
@@ -277,10 +545,11 @@
                 }
             }
             profileHeader._memoryBlock = memoryBlock;
+            profileHeader._graph = graph;
             profileHeader.isTemporary = false;
-            profileHeader.sidebarElement.subtitle = Number.bytesToString(memoryBlock.size);
+            profileHeader.sidebarElement.subtitle = Number.bytesToString(/** @type{number} */(memoryBlock.size));
         }
-        MemoryAgent.getProcessMemoryDistribution(didReceiveMemorySnapshot.bind(this));
+        MemoryAgent.getProcessMemoryDistribution(true, didReceiveMemorySnapshot.bind(this));
         return false;
     },
 
@@ -562,7 +831,13 @@
 WebInspector.NativeMemoryBarChart.prototype = {
     _updateStats: function()
     {
-        function didReceiveMemorySnapshot(error, memoryBlock)
+
+        /**
+         * @param {?string} error
+         * @param {?MemoryAgent.MemoryBlock} memoryBlock
+         * @param {?Object=} graph
+         */
+        function didReceiveMemorySnapshot(error, memoryBlock, graph)
         {
             if (memoryBlock.size && memoryBlock.children) {
                 var knownSize = 0;
@@ -583,7 +858,7 @@
             this._memorySnapshot = memoryBlock;
             this._updateView();
         }
-        MemoryAgent.getProcessMemoryDistribution(didReceiveMemorySnapshot.bind(this));
+        MemoryAgent.getProcessMemoryDistribution(false, didReceiveMemorySnapshot.bind(this));
     },
 
     /**
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to