Index: third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js |
index a4b1350c057abceb65823b281ddd36f2ae5b6822..0bd9ee63c92ef3234f87ba97309d61e00c5da29a 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js |
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js |
@@ -1,55 +1,53 @@ |
// Copyright 2014 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
- |
/** |
- * @constructor |
- * @extends {WebInspector.ProfileNode} |
- * @param {!ProfilerAgent.ProfileNode} node |
- * @param {number} sampleTime |
+ * @unrestricted |
*/ |
-WebInspector.CPUProfileNode = function(node, sampleTime) |
-{ |
+WebInspector.CPUProfileNode = class extends WebInspector.ProfileNode { |
+ /** |
+ * @param {!ProfilerAgent.ProfileNode} node |
+ * @param {number} sampleTime |
+ */ |
+ constructor(node, sampleTime) { |
var callFrame = node.callFrame || /** @type {!RuntimeAgent.CallFrame} */ ({ |
- // Backward compatibility for old SamplingHeapProfileNode format. |
- functionName: node["functionName"], |
- scriptId: node["scriptId"], |
- url: node["url"], |
- lineNumber: node["lineNumber"] - 1, |
- columnNumber: node["columnNumber"] - 1 |
- }); |
- WebInspector.ProfileNode.call(this, callFrame); |
+ // Backward compatibility for old SamplingHeapProfileNode format. |
+ functionName: node['functionName'], |
+ scriptId: node['scriptId'], |
+ url: node['url'], |
+ lineNumber: node['lineNumber'] - 1, |
+ columnNumber: node['columnNumber'] - 1 |
+ }); |
+ super(callFrame); |
this.id = node.id; |
this.self = node.hitCount * sampleTime; |
this.positionTicks = node.positionTicks; |
// Compatibility: legacy backends could provide "no reason" for optimized functions. |
- this.deoptReason = node.deoptReason && node.deoptReason !== "no reason" ? node.deoptReason : null; |
-}; |
- |
-WebInspector.CPUProfileNode.prototype = { |
- __proto__: WebInspector.ProfileNode.prototype |
+ this.deoptReason = node.deoptReason && node.deoptReason !== 'no reason' ? node.deoptReason : null; |
+ } |
}; |
/** |
- * @constructor |
- * @extends {WebInspector.ProfileTreeModel} |
- * @param {!ProfilerAgent.Profile} profile |
+ * @unrestricted |
*/ |
-WebInspector.CPUProfileDataModel = function(profile) |
-{ |
- WebInspector.ProfileTreeModel.call(this); |
- var isLegacyFormat = !!profile["head"]; |
+WebInspector.CPUProfileDataModel = class extends WebInspector.ProfileTreeModel { |
+ /** |
+ * @param {!ProfilerAgent.Profile} profile |
+ */ |
+ constructor(profile) { |
+ super(); |
+ var isLegacyFormat = !!profile['head']; |
if (isLegacyFormat) { |
- // Legacy format contains raw timestamps and start/stop times are in seconds. |
- this.profileStartTime = profile.startTime * 1000; |
- this.profileEndTime = profile.endTime * 1000; |
- this.timestamps = profile.timestamps; |
- this._compatibilityConversionHeadToNodes(profile); |
+ // Legacy format contains raw timestamps and start/stop times are in seconds. |
+ this.profileStartTime = profile.startTime * 1000; |
+ this.profileEndTime = profile.endTime * 1000; |
+ this.timestamps = profile.timestamps; |
+ this._compatibilityConversionHeadToNodes(profile); |
} else { |
- // Current format encodes timestamps as deltas. Start/stop times are in microseconds. |
- this.profileStartTime = profile.startTime / 1000; |
- this.profileEndTime = profile.endTime / 1000; |
- this.timestamps = this._convertTimeDeltas(profile); |
+ // Current format encodes timestamps as deltas. Start/stop times are in microseconds. |
+ this.profileStartTime = profile.startTime / 1000; |
+ this.profileEndTime = profile.endTime / 1000; |
+ this.timestamps = this._convertTimeDeltas(profile); |
} |
this.samples = profile.samples; |
this.totalHitCount = 0; |
@@ -57,322 +55,311 @@ WebInspector.CPUProfileDataModel = function(profile) |
this.initialize(this.profileHead); |
this._extractMetaNodes(); |
if (this.samples) { |
- this._buildIdToNodeMap(); |
- this._sortSamples(); |
- this._normalizeTimestamps(); |
+ this._buildIdToNodeMap(); |
+ this._sortSamples(); |
+ this._normalizeTimestamps(); |
} |
-}; |
+ } |
-WebInspector.CPUProfileDataModel.prototype = { |
+ /** |
+ * @param {!ProfilerAgent.Profile} profile |
+ */ |
+ _compatibilityConversionHeadToNodes(profile) { |
+ if (!profile.head || profile.nodes) |
+ return; |
+ /** @type {!Array<!ProfilerAgent.ProfileNode>} */ |
+ var nodes = []; |
+ convertNodesTree(profile.head); |
+ profile.nodes = nodes; |
+ delete profile.head; |
/** |
- * @param {!ProfilerAgent.Profile} profile |
+ * @param {!ProfilerAgent.ProfileNode} node |
+ * @return {number} |
*/ |
- _compatibilityConversionHeadToNodes: function(profile) |
- { |
- if (!profile.head || profile.nodes) |
- return; |
- /** @type {!Array<!ProfilerAgent.ProfileNode>} */ |
- var nodes = []; |
- convertNodesTree(profile.head); |
- profile.nodes = nodes; |
- delete profile.head; |
- /** |
- * @param {!ProfilerAgent.ProfileNode} node |
- * @return {number} |
- */ |
- function convertNodesTree(node) |
- { |
- nodes.push(node); |
- node.children = (/** @type {!Array<!ProfilerAgent.ProfileNode>} */(node.children)).map(convertNodesTree); |
- return node.id; |
- } |
- }, |
+ function convertNodesTree(node) { |
+ nodes.push(node); |
+ node.children = (/** @type {!Array<!ProfilerAgent.ProfileNode>} */ (node.children)).map(convertNodesTree); |
+ return node.id; |
+ } |
+ } |
+ |
+ /** |
+ * @param {!ProfilerAgent.Profile} profile |
+ * @return {?Array<number>} |
+ */ |
+ _convertTimeDeltas(profile) { |
+ if (!profile.timeDeltas) |
+ return null; |
+ var lastTimeUsec = profile.startTime; |
+ var timestamps = new Array(profile.timeDeltas.length); |
+ for (var i = 0; i < timestamps.length; ++i) { |
+ lastTimeUsec += profile.timeDeltas[i]; |
+ timestamps[i] = lastTimeUsec; |
+ } |
+ return timestamps; |
+ } |
+ /** |
+ * @param {!Array<!ProfilerAgent.ProfileNode>} nodes |
+ * @return {!WebInspector.CPUProfileNode} |
+ */ |
+ _translateProfileTree(nodes) { |
/** |
- * @param {!ProfilerAgent.Profile} profile |
- * @return {?Array<number>} |
+ * @param {!ProfilerAgent.ProfileNode} node |
+ * @return {boolean} |
*/ |
- _convertTimeDeltas: function(profile) |
- { |
- if (!profile.timeDeltas) |
- return null; |
- var lastTimeUsec = profile.startTime; |
- var timestamps = new Array(profile.timeDeltas.length); |
- for (var i = 0; i < timestamps.length; ++i) { |
- lastTimeUsec += profile.timeDeltas[i]; |
- timestamps[i] = lastTimeUsec; |
- } |
- return timestamps; |
- }, |
- |
+ function isNativeNode(node) { |
+ if (node.callFrame) |
+ return !!node.callFrame.url && node.callFrame.url.startsWith('native '); |
+ return !!node.url && node.url.startsWith('native '); |
+ } |
/** |
* @param {!Array<!ProfilerAgent.ProfileNode>} nodes |
- * @return {!WebInspector.CPUProfileNode} |
*/ |
- _translateProfileTree: function(nodes) |
- { |
- /** |
- * @param {!ProfilerAgent.ProfileNode} node |
- * @return {boolean} |
- */ |
- function isNativeNode(node) |
- { |
- if (node.callFrame) |
- return !!node.callFrame.url && node.callFrame.url.startsWith("native "); |
- return !!node.url && node.url.startsWith("native "); |
- } |
- /** |
- * @param {!Array<!ProfilerAgent.ProfileNode>} nodes |
- */ |
- function buildChildrenFromParents(nodes) |
- { |
- if (nodes[0].children) |
- return; |
- nodes[0].children = []; |
- for (var i = 1; i < nodes.length; ++i) { |
- var node = nodes[i]; |
- var parentNode = nodeByIdMap.get(node.parent); |
- if (parentNode.children) |
- parentNode.children.push(node.id); |
- else |
- parentNode.children = [node.id]; |
- } |
- } |
- /** @type {!Map<number, !ProfilerAgent.ProfileNode>} */ |
- var nodeByIdMap = new Map(); |
- for (var i = 0; i < nodes.length; ++i) { |
- var node = nodes[i]; |
- nodeByIdMap.set(node.id, node); |
- } |
- buildChildrenFromParents(nodes); |
- this.totalHitCount = nodes.reduce((acc, node) => acc + node.hitCount, 0); |
- var sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount; |
- var keepNatives = !!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get(); |
- var root = nodes[0]; |
- /** @type {!Map<number, number>} */ |
- var idMap = new Map([[root.id, root.id]]); |
- var resultRoot = new WebInspector.CPUProfileNode(root, sampleTime); |
- var parentNodeStack = root.children.map(() => resultRoot); |
- var sourceNodeStack = root.children.map(id => nodeByIdMap.get(id)); |
- while (sourceNodeStack.length) { |
- var parentNode = parentNodeStack.pop(); |
- var sourceNode = sourceNodeStack.pop(); |
- if (!sourceNode.children) |
- sourceNode.children = []; |
- var targetNode = new WebInspector.CPUProfileNode(sourceNode, sampleTime); |
- if (keepNatives || !isNativeNode(sourceNode)) { |
- parentNode.children.push(targetNode); |
- parentNode = targetNode; |
- } else { |
- parentNode.self += targetNode.self; |
- } |
- idMap.set(sourceNode.id, parentNode.id); |
- parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode)); |
- sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(id => nodeByIdMap.get(id))); |
- } |
- if (this.samples) |
- this.samples = this.samples.map(id => idMap.get(id)); |
- return resultRoot; |
- }, |
- |
- _sortSamples: function() |
- { |
- var timestamps = this.timestamps; |
- if (!timestamps) |
- return; |
- var samples = this.samples; |
- var indices = timestamps.map((x, index) => index); |
- indices.sort((a, b) => timestamps[a] - timestamps[b]); |
- for (var i = 0; i < timestamps.length; ++i) { |
- var index = indices[i]; |
- if (index === i) |
- continue; |
- // Move items in a cycle. |
- var savedTimestamp = timestamps[i]; |
- var savedSample = samples[i]; |
- var currentIndex = i; |
- while (index !== i) { |
- samples[currentIndex] = samples[index]; |
- timestamps[currentIndex] = timestamps[index]; |
- currentIndex = index; |
- index = indices[index]; |
- indices[currentIndex] = currentIndex; |
- } |
- samples[currentIndex] = savedSample; |
- timestamps[currentIndex] = savedTimestamp; |
- } |
- }, |
- |
- _normalizeTimestamps: function() |
- { |
- var timestamps = this.timestamps; |
- if (!timestamps) { |
- // Support loading old CPU profiles that are missing timestamps. |
- // Derive timestamps from profile start and stop times. |
- var profileStartTime = this.profileStartTime; |
- var interval = (this.profileEndTime - profileStartTime) / this.samples.length; |
- timestamps = new Float64Array(this.samples.length + 1); |
- for (var i = 0; i < timestamps.length; ++i) |
- timestamps[i] = profileStartTime + i * interval; |
- this.timestamps = timestamps; |
- return; |
- } |
+ function buildChildrenFromParents(nodes) { |
+ if (nodes[0].children) |
+ return; |
+ nodes[0].children = []; |
+ for (var i = 1; i < nodes.length; ++i) { |
+ var node = nodes[i]; |
+ var parentNode = nodeByIdMap.get(node.parent); |
+ if (parentNode.children) |
+ parentNode.children.push(node.id); |
+ else |
+ parentNode.children = [node.id]; |
+ } |
+ } |
+ /** @type {!Map<number, !ProfilerAgent.ProfileNode>} */ |
+ var nodeByIdMap = new Map(); |
+ for (var i = 0; i < nodes.length; ++i) { |
+ var node = nodes[i]; |
+ nodeByIdMap.set(node.id, node); |
+ } |
+ buildChildrenFromParents(nodes); |
+ this.totalHitCount = nodes.reduce((acc, node) => acc + node.hitCount, 0); |
+ var sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount; |
+ var keepNatives = !!WebInspector.moduleSetting('showNativeFunctionsInJSProfile').get(); |
+ var root = nodes[0]; |
+ /** @type {!Map<number, number>} */ |
+ var idMap = new Map([[root.id, root.id]]); |
+ var resultRoot = new WebInspector.CPUProfileNode(root, sampleTime); |
+ var parentNodeStack = root.children.map(() => resultRoot); |
+ var sourceNodeStack = root.children.map(id => nodeByIdMap.get(id)); |
+ while (sourceNodeStack.length) { |
+ var parentNode = parentNodeStack.pop(); |
+ var sourceNode = sourceNodeStack.pop(); |
+ if (!sourceNode.children) |
+ sourceNode.children = []; |
+ var targetNode = new WebInspector.CPUProfileNode(sourceNode, sampleTime); |
+ if (keepNatives || !isNativeNode(sourceNode)) { |
+ parentNode.children.push(targetNode); |
+ parentNode = targetNode; |
+ } else { |
+ parentNode.self += targetNode.self; |
+ } |
+ idMap.set(sourceNode.id, parentNode.id); |
+ parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode)); |
+ sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(id => nodeByIdMap.get(id))); |
+ } |
+ if (this.samples) |
+ this.samples = this.samples.map(id => idMap.get(id)); |
+ return resultRoot; |
+ } |
- // Convert samples from usec to msec |
- for (var i = 0; i < timestamps.length; ++i) |
- timestamps[i] /= 1000; |
- var averageSample = (timestamps.peekLast() - timestamps[0]) / (timestamps.length - 1); |
- // Add an extra timestamp used to calculate the last sample duration. |
- this.timestamps.push(timestamps.peekLast() + averageSample); |
- this.profileStartTime = timestamps[0]; |
- this.profileEndTime = timestamps.peekLast(); |
- }, |
+ _sortSamples() { |
+ var timestamps = this.timestamps; |
+ if (!timestamps) |
+ return; |
+ var samples = this.samples; |
+ var indices = timestamps.map((x, index) => index); |
+ indices.sort((a, b) => timestamps[a] - timestamps[b]); |
+ for (var i = 0; i < timestamps.length; ++i) { |
+ var index = indices[i]; |
+ if (index === i) |
+ continue; |
+ // Move items in a cycle. |
+ var savedTimestamp = timestamps[i]; |
+ var savedSample = samples[i]; |
+ var currentIndex = i; |
+ while (index !== i) { |
+ samples[currentIndex] = samples[index]; |
+ timestamps[currentIndex] = timestamps[index]; |
+ currentIndex = index; |
+ index = indices[index]; |
+ indices[currentIndex] = currentIndex; |
+ } |
+ samples[currentIndex] = savedSample; |
+ timestamps[currentIndex] = savedTimestamp; |
+ } |
+ } |
- _buildIdToNodeMap: function() |
- { |
- /** @type {!Map<number, !WebInspector.CPUProfileNode>} */ |
- this._idToNode = new Map(); |
- var idToNode = this._idToNode; |
- var stack = [this.profileHead]; |
- while (stack.length) { |
- var node = stack.pop(); |
- idToNode.set(node.id, node); |
- stack.push.apply(stack, node.children); |
- } |
- }, |
+ _normalizeTimestamps() { |
+ var timestamps = this.timestamps; |
+ if (!timestamps) { |
+ // Support loading old CPU profiles that are missing timestamps. |
+ // Derive timestamps from profile start and stop times. |
+ var profileStartTime = this.profileStartTime; |
+ var interval = (this.profileEndTime - profileStartTime) / this.samples.length; |
+ timestamps = new Float64Array(this.samples.length + 1); |
+ for (var i = 0; i < timestamps.length; ++i) |
+ timestamps[i] = profileStartTime + i * interval; |
+ this.timestamps = timestamps; |
+ return; |
+ } |
- _extractMetaNodes: function() |
- { |
- var topLevelNodes = this.profileHead.children; |
- for (var i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) { |
- var node = topLevelNodes[i]; |
- if (node.functionName === "(garbage collector)") |
- this.gcNode = node; |
- else if (node.functionName === "(program)") |
- this.programNode = node; |
- else if (node.functionName === "(idle)") |
- this.idleNode = node; |
- } |
- }, |
+ // Convert samples from usec to msec |
+ for (var i = 0; i < timestamps.length; ++i) |
+ timestamps[i] /= 1000; |
+ var averageSample = (timestamps.peekLast() - timestamps[0]) / (timestamps.length - 1); |
+ // Add an extra timestamp used to calculate the last sample duration. |
+ this.timestamps.push(timestamps.peekLast() + averageSample); |
+ this.profileStartTime = timestamps[0]; |
+ this.profileEndTime = timestamps.peekLast(); |
+ } |
- /** |
- * @param {function(number, !WebInspector.CPUProfileNode, number)} openFrameCallback |
- * @param {function(number, !WebInspector.CPUProfileNode, number, number, number)} closeFrameCallback |
- * @param {number=} startTime |
- * @param {number=} stopTime |
- */ |
- forEachFrame: function(openFrameCallback, closeFrameCallback, startTime, stopTime) |
- { |
- if (!this.profileHead || !this.samples) |
- return; |
+ _buildIdToNodeMap() { |
+ /** @type {!Map<number, !WebInspector.CPUProfileNode>} */ |
+ this._idToNode = new Map(); |
+ var idToNode = this._idToNode; |
+ var stack = [this.profileHead]; |
+ while (stack.length) { |
+ var node = stack.pop(); |
+ idToNode.set(node.id, node); |
+ stack.push.apply(stack, node.children); |
+ } |
+ } |
- startTime = startTime || 0; |
- stopTime = stopTime || Infinity; |
- var samples = this.samples; |
- var timestamps = this.timestamps; |
- var idToNode = this._idToNode; |
- var gcNode = this.gcNode; |
- var samplesCount = samples.length; |
- var startIndex = timestamps.lowerBound(startTime); |
- var stackTop = 0; |
- var stackNodes = []; |
- var prevId = this.profileHead.id; |
- var sampleTime = timestamps[samplesCount]; |
- var gcParentNode = null; |
+ _extractMetaNodes() { |
+ var topLevelNodes = this.profileHead.children; |
+ for (var i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) { |
+ var node = topLevelNodes[i]; |
+ if (node.functionName === '(garbage collector)') |
+ this.gcNode = node; |
+ else if (node.functionName === '(program)') |
+ this.programNode = node; |
+ else if (node.functionName === '(idle)') |
+ this.idleNode = node; |
+ } |
+ } |
- if (!this._stackStartTimes) |
- this._stackStartTimes = new Float64Array(this.maxDepth + 2); |
- var stackStartTimes = this._stackStartTimes; |
- if (!this._stackChildrenDuration) |
- this._stackChildrenDuration = new Float64Array(this.maxDepth + 2); |
- var stackChildrenDuration = this._stackChildrenDuration; |
+ /** |
+ * @param {function(number, !WebInspector.CPUProfileNode, number)} openFrameCallback |
+ * @param {function(number, !WebInspector.CPUProfileNode, number, number, number)} closeFrameCallback |
+ * @param {number=} startTime |
+ * @param {number=} stopTime |
+ */ |
+ forEachFrame(openFrameCallback, closeFrameCallback, startTime, stopTime) { |
+ if (!this.profileHead || !this.samples) |
+ return; |
- for (var sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) { |
- sampleTime = timestamps[sampleIndex]; |
- if (sampleTime >= stopTime) |
- break; |
- var id = samples[sampleIndex]; |
- if (id === prevId) |
- continue; |
- var node = idToNode.get(id); |
- var prevNode = idToNode.get(prevId); |
+ startTime = startTime || 0; |
+ stopTime = stopTime || Infinity; |
+ var samples = this.samples; |
+ var timestamps = this.timestamps; |
+ var idToNode = this._idToNode; |
+ var gcNode = this.gcNode; |
+ var samplesCount = samples.length; |
+ var startIndex = timestamps.lowerBound(startTime); |
+ var stackTop = 0; |
+ var stackNodes = []; |
+ var prevId = this.profileHead.id; |
+ var sampleTime = timestamps[samplesCount]; |
+ var gcParentNode = null; |
- if (node === gcNode) { |
- // GC samples have no stack, so we just put GC node on top of the last recorded sample. |
- gcParentNode = prevNode; |
- openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime); |
- stackStartTimes[++stackTop] = sampleTime; |
- stackChildrenDuration[stackTop] = 0; |
- prevId = id; |
- continue; |
- } |
- if (prevNode === gcNode) { |
- // end of GC frame |
- var start = stackStartTimes[stackTop]; |
- var duration = sampleTime - start; |
- stackChildrenDuration[stackTop - 1] += duration; |
- closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]); |
- --stackTop; |
- prevNode = gcParentNode; |
- prevId = prevNode.id; |
- gcParentNode = null; |
- } |
+ if (!this._stackStartTimes) |
+ this._stackStartTimes = new Float64Array(this.maxDepth + 2); |
+ var stackStartTimes = this._stackStartTimes; |
+ if (!this._stackChildrenDuration) |
+ this._stackChildrenDuration = new Float64Array(this.maxDepth + 2); |
+ var stackChildrenDuration = this._stackChildrenDuration; |
- while (node.depth > prevNode.depth) { |
- stackNodes.push(node); |
- node = node.parent; |
- } |
+ for (var sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) { |
+ sampleTime = timestamps[sampleIndex]; |
+ if (sampleTime >= stopTime) |
+ break; |
+ var id = samples[sampleIndex]; |
+ if (id === prevId) |
+ continue; |
+ var node = idToNode.get(id); |
+ var prevNode = idToNode.get(prevId); |
- // Go down to the LCA and close current intervals. |
- while (prevNode !== node) { |
- var start = stackStartTimes[stackTop]; |
- var duration = sampleTime - start; |
- stackChildrenDuration[stackTop - 1] += duration; |
- closeFrameCallback(prevNode.depth, /** @type {!WebInspector.CPUProfileNode} */(prevNode), start, duration, duration - stackChildrenDuration[stackTop]); |
- --stackTop; |
- if (node.depth === prevNode.depth) { |
- stackNodes.push(node); |
- node = node.parent; |
- } |
- prevNode = prevNode.parent; |
- } |
+ if (node === gcNode) { |
+ // GC samples have no stack, so we just put GC node on top of the last recorded sample. |
+ gcParentNode = prevNode; |
+ openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime); |
+ stackStartTimes[++stackTop] = sampleTime; |
+ stackChildrenDuration[stackTop] = 0; |
+ prevId = id; |
+ continue; |
+ } |
+ if (prevNode === gcNode) { |
+ // end of GC frame |
+ var start = stackStartTimes[stackTop]; |
+ var duration = sampleTime - start; |
+ stackChildrenDuration[stackTop - 1] += duration; |
+ closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]); |
+ --stackTop; |
+ prevNode = gcParentNode; |
+ prevId = prevNode.id; |
+ gcParentNode = null; |
+ } |
- // Go up the nodes stack and open new intervals. |
- while (stackNodes.length) { |
- node = stackNodes.pop(); |
- openFrameCallback(node.depth, node, sampleTime); |
- stackStartTimes[++stackTop] = sampleTime; |
- stackChildrenDuration[stackTop] = 0; |
- } |
+ while (node.depth > prevNode.depth) { |
+ stackNodes.push(node); |
+ node = node.parent; |
+ } |
- prevId = id; |
+ // Go down to the LCA and close current intervals. |
+ while (prevNode !== node) { |
+ var start = stackStartTimes[stackTop]; |
+ var duration = sampleTime - start; |
+ stackChildrenDuration[stackTop - 1] += duration; |
+ closeFrameCallback( |
+ prevNode.depth, /** @type {!WebInspector.CPUProfileNode} */ (prevNode), start, duration, |
+ duration - stackChildrenDuration[stackTop]); |
+ --stackTop; |
+ if (node.depth === prevNode.depth) { |
+ stackNodes.push(node); |
+ node = node.parent; |
} |
+ prevNode = prevNode.parent; |
+ } |
- if (idToNode.get(prevId) === gcNode) { |
- var start = stackStartTimes[stackTop]; |
- var duration = sampleTime - start; |
- stackChildrenDuration[stackTop - 1] += duration; |
- closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]); |
- --stackTop; |
- } |
+ // Go up the nodes stack and open new intervals. |
+ while (stackNodes.length) { |
+ node = stackNodes.pop(); |
+ openFrameCallback(node.depth, node, sampleTime); |
+ stackStartTimes[++stackTop] = sampleTime; |
+ stackChildrenDuration[stackTop] = 0; |
+ } |
- for (var node = idToNode.get(prevId); node.parent; node = node.parent) { |
- var start = stackStartTimes[stackTop]; |
- var duration = sampleTime - start; |
- stackChildrenDuration[stackTop - 1] += duration; |
- closeFrameCallback(node.depth, /** @type {!WebInspector.CPUProfileNode} */(node), start, duration, duration - stackChildrenDuration[stackTop]); |
- --stackTop; |
- } |
- }, |
+ prevId = id; |
+ } |
- /** |
- * @param {number} index |
- * @return {?WebInspector.CPUProfileNode} |
- */ |
- nodeByIndex: function(index) |
- { |
- return this._idToNode.get(this.samples[index]) || null; |
- }, |
+ if (idToNode.get(prevId) === gcNode) { |
+ var start = stackStartTimes[stackTop]; |
+ var duration = sampleTime - start; |
+ stackChildrenDuration[stackTop - 1] += duration; |
+ closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]); |
+ --stackTop; |
+ } |
+ |
+ for (var node = idToNode.get(prevId); node.parent; node = node.parent) { |
+ var start = stackStartTimes[stackTop]; |
+ var duration = sampleTime - start; |
+ stackChildrenDuration[stackTop - 1] += duration; |
+ closeFrameCallback( |
+ node.depth, /** @type {!WebInspector.CPUProfileNode} */ (node), start, duration, |
+ duration - stackChildrenDuration[stackTop]); |
+ --stackTop; |
+ } |
+ } |
- __proto__: WebInspector.ProfileTreeModel.prototype |
+ /** |
+ * @param {number} index |
+ * @return {?WebInspector.CPUProfileNode} |
+ */ |
+ nodeByIndex(index) { |
+ return this._idToNode.get(this.samples[index]) || null; |
+ } |
}; |