summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authormnaganov@chromium.org <mnaganov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-02 17:56:44 +0000
committermnaganov@chromium.org <mnaganov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-02 17:56:44 +0000
commit4f967820e2e2e24b438c230cc781df62ecdc2c89 (patch)
tree4f56844017883bb78836abb005143ce881f35bf0 /webkit
parent1421207f89748c1c1cd0ed7240d4dfd1a0efc7f6 (diff)
downloadchromium_src-4f967820e2e2e24b438c230cc781df62ecdc2c89.zip
chromium_src-4f967820e2e2e24b438c230cc781df62ecdc2c89.tar.gz
chromium_src-4f967820e2e2e24b438c230cc781df62ecdc2c89.tar.bz2
DevTools Heap profiler: implement sorting.
BUG=26319 TEST=none Review URL: http://codereview.chromium.org/342076 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30712 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/devtools/js/heap_profiler_panel.js232
1 files changed, 200 insertions, 32 deletions
diff --git a/webkit/glue/devtools/js/heap_profiler_panel.js b/webkit/glue/devtools/js/heap_profiler_panel.js
index 666f17e..ee80506 100644
--- a/webkit/glue/devtools/js/heap_profiler_panel.js
+++ b/webkit/glue/devtools/js/heap_profiler_panel.js
@@ -99,6 +99,12 @@ WebInspector.HeapSnapshotView.prototype = {
this.dataGrid.updateWidths();
},
+ hide: function()
+ {
+ WebInspector.View.prototype.hide.call(this);
+ this._currentSearchResultIndex = -1;
+ },
+
resize: function()
{
if (this.dataGrid)
@@ -123,6 +129,114 @@ WebInspector.HeapSnapshotView.prototype = {
this.refreshVisibleData();
},
+ _deleteSearchMatchedFlags: function(node)
+ {
+ delete node._searchMatchedConsColumn;
+ delete node._searchMatchedCountColumn;
+ delete node._searchMatchedSizeColumn;
+ delete node._searchMatchedCountDeltaColumn;
+ delete node._searchMatchedSizeDeltaColumn;
+ },
+
+ searchCanceled: function()
+ {
+ if (this._searchResults) {
+ for (var i = 0; i < this._searchResults.length; ++i) {
+ var profileNode = this._searchResults[i].profileNode;
+ this._deleteSearchMatchedFlags(profileNode);
+ profileNode.refresh();
+ }
+ }
+
+ delete this._searchFinishedCallback;
+ this._currentSearchResultIndex = -1;
+ this._searchResults = [];
+ },
+
+ performSearch: function(query, finishedCallback)
+ {
+ // Call searchCanceled since it will reset everything we need before doing a new search.
+ this.searchCanceled();
+
+ query = query.trimWhitespace();
+
+ if (!query.length)
+ return;
+
+ this._searchFinishedCallback = finishedCallback;
+
+ var helper = WebInspector.HeapSnapshotView.SearchHelper;
+
+ var operationAndNumber = helper.parseOperationAndNumber(query);
+ var operation = operationAndNumber[0];
+ var queryNumber = operationAndNumber[1];
+
+ var percentUnits = helper.percents.test(query);
+ var megaBytesUnits = helper.megaBytes.test(query);
+ var kiloBytesUnits = helper.kiloBytes.test(query);
+ var bytesUnits = helper.bytes.test(query);
+
+ var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber));
+
+ function matchesQuery(heapSnapshotDataGridNode)
+ {
+ WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode);
+
+ if (percentUnits) {
+ heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber);
+ } else if (megaBytesUnits || kiloBytesUnits || bytesUnits) {
+ heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes);
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes);
+ } else {
+ heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber);
+ }
+
+ if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true))
+ heapSnapshotDataGridNode._searchMatchedConsColumn = true;
+
+ if (heapSnapshotDataGridNode._searchMatchedConsColumn ||
+ heapSnapshotDataGridNode._searchMatchedCountColumn ||
+ heapSnapshotDataGridNode._searchMatchedSizeColumn ||
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn ||
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) {
+ heapSnapshotDataGridNode.refresh();
+ return true;
+ }
+
+ return false;
+ }
+
+ var current = this.snapshotDataGridList.children[0];
+ var depth = 0;
+ var info = {};
+
+ // The second and subsequent levels of heap snapshot nodes represent retainers,
+ // so recursive expansion will be infinite, since a graph is being traversed.
+ // So default to a recursion cap of 2 levels.
+ var maxDepth = 2;
+
+ while (current) {
+ if (matchesQuery(current))
+ this._searchResults.push({ profileNode: current });
+ current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
+ depth += info.depthChange;
+ }
+
+ finishedCallback(this, this._searchResults.length);
+ },
+
+ jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult,
+ jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult,
+ jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult,
+ jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult,
+ showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult,
+ showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult,
+ _jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult,
+
refreshVisibleData: function()
{
var child = this.dataGrid.children[0];
@@ -139,6 +253,15 @@ WebInspector.HeapSnapshotView.prototype = {
this._resetDataGridList();
this.refresh();
+
+ if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
+ return;
+
+ // The current search needs to be performed again. First negate out previous match
+ // count by calling the search finished callback with a negative number of matches.
+ // Then perform the search again with the same query and callback.
+ this._searchFinishedCallback(this, -this._searchResults.length);
+ this.performSearch(this.currentQuery, this._searchFinishedCallback);
},
_createSnapshotDataGridList: function()
@@ -193,9 +316,8 @@ WebInspector.HeapSnapshotView.prototype = {
{
this.baseSnapshot = WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex];
var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false);
- if (this.snapshotDataGridList) {
+ if (this.snapshotDataGridList)
lastComparator = this.snapshotDataGridList.lastComparator;
- }
this.snapshotDataGridList = this._createSnapshotDataGridList();
this.snapshotDataGridList.sort(lastComparator, true);
},
@@ -205,14 +327,14 @@ WebInspector.HeapSnapshotView.prototype = {
var sortAscending = this.dataGrid.sortOrder === "ascending";
var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
var sortProperty = {
- "cons": "constructorName",
- "count": "count",
- "size": "size",
- "countDelta": this.showCountDeltaAsPercent ? "countDeltaPercent" : "countDelta",
- "sizeDelta": this.showSizeDeltaAsPercent ? "sizeDeltaPercent" : "sizeDelta"
+ "cons": ["constructorName", null],
+ "count": ["count", null],
+ "size": ["size", "count"],
+ "countDelta": this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
+ "sizeDelta": this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"]
}[sortColumnIdentifier];
- this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty, sortAscending));
+ this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending));
this.refresh();
},
@@ -251,6 +373,40 @@ WebInspector.HeapSnapshotView.prototype = {
WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype;
+WebInspector.HeapSnapshotView.SearchHelper = {
+ // In comparators, we assume that a value from a node is passed as the first parameter.
+ operations: { LESS: function (a, b) { return a !== null && a < b; },
+ LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; },
+ EQUAL: function (a, b) { return a !== null && a == b; },
+ GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; },
+ GREATER: function (a, b) { return a !== null && a > b; } },
+
+ operationParsers: { LESS: /^<(\d+)/,
+ LESS_OR_EQUAL: /^<=(\d+)/,
+ GREATER_OR_EQUAL: /^>=(\d+)/,
+ GREATER: /^>(\d+)/ },
+
+ parseOperationAndNumber: function(query)
+ {
+ var operations = WebInspector.HeapSnapshotView.SearchHelper.operations;
+ var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers;
+ for (var operation in parsers) {
+ var match = query.match(parsers[operation]);
+ if (match != null)
+ return [operations[operation], parseFloat(match[1])];
+ }
+ return [operations.EQUAL, parseFloat(query)];
+ },
+
+ percents: /%$/,
+
+ megaBytes: /MB$/i,
+
+ kiloBytes: /KB$/i,
+
+ bytes: /B$/i
+}
+
WebInspector.HeapSummaryCalculator = function(total)
{
this.total = total;
@@ -425,9 +581,8 @@ WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
getTotalCount: function() {
if (!this._count) {
this._count = 0;
- for (var i = 0, n = this.children.length; i < n; ++i) {
+ for (var i = 0, n = this.children.length; i < n; ++i)
this._count += this.children[i].count;
- }
}
return this._count;
},
@@ -435,9 +590,8 @@ WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
getTotalSize: function() {
if (!this._size) {
this._size = 0;
- for (var i = 0, n = this.children.length; i < n; ++i) {
+ for (var i = 0, n = this.children.length; i < n; ++i)
this._size += this.children[i].size;
- }
}
return this._size;
},
@@ -474,7 +628,7 @@ WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
return Number.POSITIVE_INFINITY;
},
- getData: function(showSize)
+ get data()
{
var data = {};
@@ -485,30 +639,42 @@ WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
else
data["count"] = this.count;
- if (showSize) {
+ if (this.size !== null) {
if (this.snapshotView.showSizeAsPercent)
data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent);
else
data["size"] = Number.bytesToString(this.size);
- } else {
+ } else
data["size"] = "";
- }
if (this.snapshotView.showCountDeltaAsPercent)
data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent);
else
data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta));
- if (showSize) {
+ if (this.sizeDelta != null) {
if (this.snapshotView.showSizeDeltaAsPercent)
data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent);
else
data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta)));
- } else {
+ } else
data["sizeDelta"] = "";
- }
return data;
+ },
+
+ createCell: function(columnIdentifier)
+ {
+ var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
+
+ if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) ||
+ (columnIdentifier === "count" && this._searchMatchedCountColumn) ||
+ (columnIdentifier === "size" && this._searchMatchedSizeColumn) ||
+ (columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) ||
+ (columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn))
+ cell.addStyleClass("highlight");
+
+ return cell;
}
};
@@ -536,13 +702,6 @@ WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapsh
WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
};
-WebInspector.HeapSnapshotDataGridNode.prototype = {
- get data()
- {
- return this.getData(true);
- }
-};
-
WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries)
@@ -586,16 +745,19 @@ WebInspector.HeapSnapshotDataGridList.prototype = {
WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}];
-WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, isAscending)
+WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending)
{
- var comparator = this.propertyComparators[(isAscending ? 1 : 0)][property];
+ var propertyHash = property + '#' + property2;
+ var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash];
if (!comparator) {
comparator = function(lhs, rhs) {
var l = lhs[property], r = rhs[property];
+ if ((l === null || r === null) && property2 !== null)
+ l = lhs[property2], r = rhs[property2];
var result = l < r ? -1 : (l > r ? 1 : 0);
return isAscending ? result : -result;
};
- this.propertyComparators[(isAscending ? 1 : 0)][property] = comparator;
+ this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator;
}
return comparator;
};
@@ -616,15 +778,21 @@ WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry
this.countDelta = this.count - this.baseCount;
this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters);
- this.size = this.count; // This way, when sorting by sizes entries will be sorted by references count.
+ this.size = null;
+ this.sizeDelta = null;
WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
}
WebInspector.HeapSnapshotDataGridRetainerNode.prototype = {
- get data()
+ get sizePercent()
+ {
+ return null;
+ },
+
+ get sizeDeltaPercent()
{
- return this.getData(false);
+ return null;
},
_calculateRetainers: function(snapshot, clusters) {