Index: Source/devtools/front_end/HeapSnapshot.js |
diff --git a/Source/devtools/front_end/HeapSnapshot.js b/Source/devtools/front_end/HeapSnapshot.js |
index 9eea0b2b8dcb9334240d864c0ac99f6046956122..bd30745c4b9f24182c844736b26bc84eba82ba56 100644 |
--- a/Source/devtools/front_end/HeapSnapshot.js |
+++ b/Source/devtools/front_end/HeapSnapshot.js |
@@ -773,10 +773,11 @@ WebInspector.HeapSnapshot = function(profile, progress) |
var traceNodeId = node.traceNodeId(); |
var stats = liveObjects[traceNodeId]; |
if (!stats) { |
- liveObjects[traceNodeId] = stats = { count: 0, size: 0}; |
+ liveObjects[traceNodeId] = stats = { count: 0, size: 0, ids: []}; |
} |
stats.count++; |
stats.size += node.selfSize(); |
+ stats.ids.push(node.id()); |
} |
this._allocationProfile = new WebInspector.AllocationProfile(profile, liveObjects); |
this._progress.updateStatus("Done"); |
@@ -1012,45 +1013,83 @@ WebInspector.HeapSnapshot.prototype = { |
{ |
var minNodeId = nodeFilter.minNodeId; |
var maxNodeId = nodeFilter.maxNodeId; |
+ var allocationNodeId = nodeFilter.allocationNodeId; |
var key; |
var filter; |
+ if (typeof allocationNodeId === "number") { |
+ filter = this._createAllocationStackFilter(allocationNodeId); |
+ } else if (typeof minNodeId === "number" && typeof maxNodeId === "number") { |
+ key = minNodeId + ".." + maxNodeId; |
+ filter = this._createNodeIdFilter(minNodeId, maxNodeId); |
+ } else { |
+ key = "allObjects"; |
+ } |
+ return this.aggregates(false, key, filter); |
+ }, |
+ |
+ /** |
+ * @param {number} minNodeId |
+ * @param {number} maxNodeId |
+ * @return {function(!WebInspector.HeapSnapshotNode):boolean} |
+ */ |
+ _createNodeIdFilter: function(minNodeId, maxNodeId) |
+ { |
/** |
* @param {!WebInspector.HeapSnapshotNode} node |
* @return boolean |
*/ |
- function filterById(node) |
+ function nodeIdFilter(node) |
{ |
var id = node.id(); |
return id > minNodeId && id <= maxNodeId; |
} |
- if (typeof minNodeId === "number") { |
- key = minNodeId + ".." + maxNodeId; |
- filter = filterById; |
- } else { |
- key = "allObjects"; |
- } |
- return this.aggregates(false, key, filter); |
+ return nodeIdFilter; |
+ }, |
+ |
+ /** |
+ * @param {number} bottomUpAllocationNodeId |
+ * @return {function(!WebInspector.HeapSnapshotNode):boolean|undefined} |
+ */ |
+ _createAllocationStackFilter: function(bottomUpAllocationNodeId) |
+ { |
+ var traceIds = this._allocationProfile.traceIds(bottomUpAllocationNodeId); |
+ if (!traceIds.length) |
+ return undefined; |
+ var set = {}; |
+ for (var i = 0; i < traceIds.length; i++) |
+ set[traceIds[i]] = true; |
+ /** |
+ * @param {!WebInspector.HeapSnapshotNode} node |
+ * @return boolean |
+ */ |
+ function traceIdFilter(node) |
+ { |
+ return !!set[node.traceNodeId()]; |
+ }; |
+ return traceIdFilter; |
}, |
/** |
* @param {boolean} sortedIndexes |
- * @param {string} key |
+ * @param {string=} key |
* @param {function(!WebInspector.HeapSnapshotNode):boolean=} filter |
* @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>} |
*/ |
aggregates: function(sortedIndexes, key, filter) |
{ |
- var aggregatesByClassName = this._aggregates[key]; |
+ var aggregatesByClassName = key && this._aggregates[key]; |
if (!aggregatesByClassName) { |
var aggregates = this._buildAggregates(filter); |
this._calculateClassesRetainedSize(aggregates.aggregatesByClassIndex, filter); |
aggregatesByClassName = aggregates.aggregatesByClassName; |
- this._aggregates[key] = aggregatesByClassName; |
+ if (key) |
+ this._aggregates[key] = aggregatesByClassName; |
} |
- if (sortedIndexes && !this._aggregatesSortedFlags[key]) { |
+ if (sortedIndexes && (!key || !this._aggregatesSortedFlags[key])) { |
this._sortAggregateIndexes(aggregatesByClassName); |
- this._aggregatesSortedFlags[key] = sortedIndexes; |
+ if (key) |
+ this._aggregatesSortedFlags[key] = sortedIndexes; |
} |
return aggregatesByClassName; |
}, |
@@ -1064,7 +1103,7 @@ WebInspector.HeapSnapshot.prototype = { |
}, |
/** |
- * @param {string} nodeId |
+ * @param {number} nodeId |
* @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} |
*/ |
allocationNodeCallers: function(nodeId) |