Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1379)

Unified Diff: third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js

Issue 1873973002: DevTools: extract CPU profile independent part of CPUProfileNode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 d51f72d510a9e418ce1b0e3a7dbfae8743f22f34..4362d22239f611c22c830ae35590d00415260024 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileDataModel.js
@@ -2,72 +2,84 @@
// 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.CPUProfileNode} sourceNode
+ * @param {number} sampleTime
+ */
+WebInspector.CPUProfileNode = function(sourceNode, sampleTime)
+{
+ WebInspector.ProfileNode.call(this);
+ this.functionName = sourceNode.functionName;
+ this.scriptId = sourceNode.scriptId;
+ this.url = sourceNode.url;
+ this.lineNumber = sourceNode.lineNumber;
+ this.columnNumber = sourceNode.columnNumber;
+ this.id = sourceNode.id;
+ this.self = sourceNode.hitCount * sampleTime;
+ this.callUID = sourceNode.callUID;
+ this.positionTicks = sourceNode.positionTicks;
+ this.deoptReason = sourceNode.deoptReason;
caseq 2016/04/13 17:21:12 Why do we have to do this? Having to copy all fiel
alph 2016/04/13 19:05:07 This is done just once for the tree. I want to hav
+ // TODO: Remove the following field in favor of this.self
+ this.selfTime = this.self;
+}
+
+WebInspector.CPUProfileNode.prototype = {
+ __proto__: WebInspector.ProfileNode.prototype
+}
/**
* @constructor
+ * @extends {WebInspector.ProfileTreeModel}
* @param {!ProfilerAgent.CPUProfile} profile
*/
WebInspector.CPUProfileDataModel = function(profile)
{
- this.profileHead = profile.head;
this.samples = profile.samples;
this.timestamps = profile.timestamps;
+ // Convert times from sec to msec.
this.profileStartTime = profile.startTime * 1000;
this.profileEndTime = profile.endTime * 1000;
- this._assignParentsInProfile();
+ if (!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get())
+ this._filterNativeFrames(profile.head);
+ this.profileHead = this._translateProfileTree(profile.head);
+ WebInspector.ProfileTreeModel.call(this, this.profileHead, this.profileStartTime, this.profileEndTime);
+ this._extractMetaNodes();
if (this.samples) {
+ this._buildIdToNodeMap();
this._sortSamples();
this._normalizeTimestamps();
- this._buildIdToNodeMap();
this._fixMissingSamples();
}
- if (!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get())
- this._filterNativeFrames();
- this._assignDepthsInProfile();
- this._calculateTimes(profile);
+ this._assignTotalTimes(this.profileHead);
}
WebInspector.CPUProfileDataModel.prototype = {
/**
- * @param {!ProfilerAgent.CPUProfile} profile
+ * @param {!ProfilerAgent.CPUProfileNode} head
*/
- _calculateTimes: function(profile)
- {
- function totalHitCount(node) {
- var result = node.hitCount;
- for (var i = 0; i < node.children.length; i++)
- result += totalHitCount(node.children[i]);
- return result;
- }
- profile.totalHitCount = totalHitCount(profile.head);
- this.totalHitCount = profile.totalHitCount;
-
- var duration = this.profileEndTime - this.profileStartTime;
- var samplingInterval = duration / profile.totalHitCount;
- this.samplingInterval = samplingInterval;
-
- function calculateTimesForNode(node) {
- node.selfTime = node.hitCount * samplingInterval;
- var totalHitCount = node.hitCount;
- for (var i = 0; i < node.children.length; i++)
- totalHitCount += calculateTimesForNode(node.children[i]);
- node.totalTime = totalHitCount * samplingInterval;
- return totalHitCount;
- }
- calculateTimesForNode(profile.head);
- },
-
- _filterNativeFrames: function()
+ _filterNativeFrames: function(head)
{
if (this.samples) {
+ var idToNode = {};
caseq 2016/04/13 17:21:12 use Map()?
alph 2016/04/13 19:05:07 Done.
+ var stack = [head];
+ while (stack.length) {
caseq 2016/04/13 17:21:12 can this be combined with tree traversal we perfor
alph 2016/04/13 19:05:07 Yes, building the tree along with filtering should
+ var node = stack.pop();
+ idToNode[node.id] = node;
+ for (var i = 0; i < node.children.length; i++) {
+ node.children[i].parent = node;
+ stack.push(node.children[i]);
+ }
+ }
for (var i = 0; i < this.samples.length; ++i) {
- var node = this.nodeByIndex(i);
+ var node = idToNode[this.samples[i]];
while (isNativeNode(node))
node = node.parent;
caseq 2016/04/13 17:21:12 so we actually care to know nearest non-native par
alph 2016/04/13 19:05:07 I'm going to get rid of this function later. Added
this.samples[i] = node.id;
}
}
- processSubtree(this.profileHead);
+ processSubtree(head);
/**
* @param {!ProfilerAgent.CPUProfileNode} node
@@ -118,44 +130,47 @@ WebInspector.CPUProfileDataModel.prototype = {
}
},
- _assignParentsInProfile: function()
+ /**
+ * @param {!ProfilerAgent.CPUProfileNode} head
+ * @return {!WebInspector.CPUProfileNode}
+ */
+ _translateProfileTree: function(head)
{
- var head = this.profileHead;
- head.parent = null;
- var nodesToTraverse = [ head ];
+ /**
+ * @param {!ProfilerAgent.CPUProfileNode} node
+ * @return {number}
+ */
+ function treeHitCount(node)
caseq 2016/04/13 17:21:12 nit: computeHitCountForSubtree()
alph 2016/04/13 19:05:07 Done.
+ {
+ return node.children.reduce((acc, node) => acc + treeHitCount(node), node.hitCount);
+ }
+ this.totalHitCount = treeHitCount(head);
+ var sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount;
+ var root = new WebInspector.CPUProfileNode(head, sampleTime);
+ // The stack contains pairs: (parentNode, sourceNode.children)
caseq 2016/04/13 17:21:12 Please make it an array of objects, this way it's
alph 2016/04/13 19:05:07 Done.
+ var nodesToTraverse = [ root, head.children ];
while (nodesToTraverse.length) {
- var parent = nodesToTraverse.pop();
- var children = parent.children;
- var length = children.length;
- for (var i = 0; i < length; ++i) {
- var child = children[i];
- child.parent = parent;
- if (child.children.length)
- nodesToTraverse.push(child);
+ var children = nodesToTraverse.pop();
+ var parentNode = nodesToTraverse.pop();
+ for (var i = 0; i < children.length; ++i) {
+ var sourceNode = children[i];
+ var node = new WebInspector.CPUProfileNode(sourceNode, sampleTime);
+ parentNode.children.push(node);
+ if (sourceNode.children.length)
+ nodesToTraverse.push(node, sourceNode.children);
}
}
+ return root;
},
- _assignDepthsInProfile: function()
+ /**
+ * @param {!WebInspector.ProfileNode} node
+ */
+ _assignTotalTimes: function(node)
{
- var head = this.profileHead;
- head.depth = -1;
- this.maxDepth = 0;
- var nodesToTraverse = [ head ];
- while (nodesToTraverse.length) {
- var parent = nodesToTraverse.pop();
- var depth = parent.depth + 1;
- if (depth > this.maxDepth)
- this.maxDepth = depth;
- var children = parent.children;
- var length = children.length;
- for (var i = 0; i < length; ++i) {
- var child = children[i];
- child.depth = depth;
- if (child.children.length)
- nodesToTraverse.push(child);
- }
- }
+ // TODO: get rid of this field in favor of this.total
+ node.totalTime = node.total;
+ node.children.forEach(this._assignTotalTimes, this);
},
_sortSamples: function()
@@ -213,7 +228,7 @@ WebInspector.CPUProfileDataModel.prototype = {
_buildIdToNodeMap: function()
{
- /** @type {!Object.<number, !ProfilerAgent.CPUProfileNode>} */
+ /** @type {!Object<number, !WebInspector.CPUProfileNode>} */
this._idToNode = {};
var idToNode = this._idToNode;
var stack = [this.profileHead];
@@ -223,7 +238,10 @@ WebInspector.CPUProfileDataModel.prototype = {
for (var i = 0; i < node.children.length; i++)
stack.push(node.children[i]);
}
+ },
+ _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];
@@ -265,8 +283,8 @@ WebInspector.CPUProfileDataModel.prototype = {
}
/**
- * @param {!ProfilerAgent.CPUProfileNode} node
- * @return {!ProfilerAgent.CPUProfileNode}
+ * @param {!WebInspector.ProfileNode} node
+ * @return {!WebInspector.ProfileNode}
*/
function bottomNode(node)
{
@@ -286,8 +304,8 @@ WebInspector.CPUProfileDataModel.prototype = {
},
/**
- * @param {function(number, !ProfilerAgent.CPUProfileNode, number)} openFrameCallback
- * @param {function(number, !ProfilerAgent.CPUProfileNode, number, number, number)} closeFrameCallback
+ * @param {function(number, !WebInspector.CPUProfileNode, number)} openFrameCallback
+ * @param {function(number, !WebInspector.CPUProfileNode, number, number, number)} closeFrameCallback
* @param {number=} startTime
* @param {number=} stopTime
*/
@@ -358,7 +376,7 @@ WebInspector.CPUProfileDataModel.prototype = {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
- closeFrameCallback(prevNode.depth, prevNode, start, duration, duration - stackChildrenDuration[stackTop]);
+ closeFrameCallback(prevNode.depth, /** @type {!WebInspector.CPUProfileNode} */(prevNode), start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
if (node.depth === prevNode.depth) {
stackNodes.push(node);
@@ -390,18 +408,19 @@ WebInspector.CPUProfileDataModel.prototype = {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
- closeFrameCallback(node.depth, node, start, duration, duration - stackChildrenDuration[stackTop]);
+ closeFrameCallback(node.depth, /** @type {!WebInspector.CPUProfileNode} */(node), start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
}
},
/**
* @param {number} index
- * @return {!ProfilerAgent.CPUProfileNode}
+ * @return {!WebInspector.CPUProfileNode}
*/
nodeByIndex: function(index)
{
return this._idToNode[this.samples[index]];
- }
+ },
+ __proto__: WebInspector.ProfileTreeModel.prototype
}

Powered by Google App Engine
This is Rietveld 408576698