Skip to content

Commit

Permalink
Revert of DevTools: extract CPU profile independent part of CPUProfil…
Browse files Browse the repository at this point in the history
…eNode. (patchset #3 id:40001 of https://codereview.chromium.org/1873973002/ )

Reason for revert:
This broke at least two timeline tests with Cannot read property 'parent' of null

BUG=603767

Original issue's description:
> DevTools: extract CPU profile independent part of CPUProfileNode.
>
> This is a prerequisite to make the profile node class reused for sampling heap profiler.
>
> BUG=586613
>
> Committed: https://crrev.com/1c33b9ee4940826b3a972c093cbc3f8e1f1b3f50
> Cr-Commit-Position: refs/heads/master@{#387249}

[email protected]
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=586613

Review URL: https://codereview.chromium.org/1889963003

Cr-Commit-Position: refs/heads/master@{#387716}
  • Loading branch information
caseq authored and Commit bot committed Apr 15, 2016
1 parent decf4d4 commit c0fed8a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 217 deletions.
1 change: 0 additions & 1 deletion devtools.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@
'front_end/sdk/NetworkManager.js',
'front_end/sdk/NetworkRequest.js',
'front_end/sdk/PaintProfiler.js',
'front_end/sdk/ProfileTreeModel.js',
'front_end/sdk/RemoteObject.js',
'front_end/sdk/Resource.js',
'front_end/sdk/ResourceTreeModel.js',
Expand Down
171 changes: 79 additions & 92 deletions front_end/sdk/CPUProfileDataModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,72 @@
// 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, sourceNode.functionName, sourceNode.scriptId, sourceNode.url, sourceNode.lineNumber, sourceNode.columnNumber);
this.id = sourceNode.id;
this.self = sourceNode.hitCount * sampleTime;
this.callUID = sourceNode.callUID;
this.positionTicks = sourceNode.positionTicks;
this.deoptReason = sourceNode.deoptReason;
// 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.totalHitCount = 0;
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();
this._assignParentsInProfile();
if (this.samples) {
this._buildIdToNodeMap();
this._sortSamples();
this._normalizeTimestamps();
this._buildIdToNodeMap();
this._fixMissingSamples();
}
this._assignTotalTimes(this.profileHead);
if (!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get())
this._filterNativeFrames();
this._assignDepthsInProfile();
this._calculateTimes(profile);
}

WebInspector.CPUProfileDataModel.prototype = {
/**
* @param {!ProfilerAgent.CPUProfileNode} root
* @param {!ProfilerAgent.CPUProfile} profile
*/
_filterNativeFrames: function(root)
_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()
{
// TODO: get rid of this function and do the filtering while _translateProfileTree
if (this.samples) {
/** @type {!Map<number, !ProfilerAgent.CPUProfileNode>} */
var idToNode = new Map();
var stack = [root];
while (stack.length) {
var node = stack.pop();
idToNode.set(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 = idToNode.get(this.samples[i]);
var node = this.nodeByIndex(i);
while (isNativeNode(node))
node = node.parent;
this.samples[i] = node.id;
}
}
processSubtree(root);
processSubtree(this.profileHead);

/**
* @param {!ProfilerAgent.CPUProfileNode} node
Expand Down Expand Up @@ -128,43 +118,44 @@ WebInspector.CPUProfileDataModel.prototype = {
}
},

/**
* @param {!ProfilerAgent.CPUProfileNode} root
* @return {!WebInspector.CPUProfileNode}
*/
_translateProfileTree: function(root)
_assignParentsInProfile: function()
{
/**
* @param {!ProfilerAgent.CPUProfileNode} node
* @return {number}
*/
function computeHitCountForSubtree(node)
{
return node.children.reduce((acc, node) => acc + computeHitCountForSubtree(node), node.hitCount);
}
this.totalHitCount = computeHitCountForSubtree(root);
var sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount;
var resultRoot = new WebInspector.CPUProfileNode(root, sampleTime);
var targetNodeStack = [resultRoot];
var sourceNodeStack = [root];
while (sourceNodeStack.length) {
var sourceNode = sourceNodeStack.pop();
var parentNode = targetNodeStack.pop();
parentNode.children = sourceNode.children.map(child => new WebInspector.CPUProfileNode(child, sampleTime));
sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children);
targetNodeStack.push.apply(targetNodeStack, parentNode.children);
var head = this.profileHead;
head.parent = null;
var nodesToTraverse = [ head ];
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);
}
}
return resultRoot;
},

/**
* @param {!WebInspector.ProfileNode} node
*/
_assignTotalTimes: function(node)
_assignDepthsInProfile: function()
{
// TODO: get rid of this field in favor of this.total
node.totalTime = node.total;
node.children.forEach(this._assignTotalTimes, this);
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);
}
}
},

_sortSamples: function()
Expand Down Expand Up @@ -222,7 +213,7 @@ WebInspector.CPUProfileDataModel.prototype = {

_buildIdToNodeMap: function()
{
/** @type {!Object<number, !WebInspector.CPUProfileNode>} */
/** @type {!Object.<number, !ProfilerAgent.CPUProfileNode>} */
this._idToNode = {};
var idToNode = this._idToNode;
var stack = [this.profileHead];
Expand All @@ -232,10 +223,7 @@ 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];
Expand Down Expand Up @@ -277,8 +265,8 @@ WebInspector.CPUProfileDataModel.prototype = {
}

/**
* @param {!WebInspector.ProfileNode} node
* @return {!WebInspector.ProfileNode}
* @param {!ProfilerAgent.CPUProfileNode} node
* @return {!ProfilerAgent.CPUProfileNode}
*/
function bottomNode(node)
{
Expand All @@ -298,8 +286,8 @@ WebInspector.CPUProfileDataModel.prototype = {
},

/**
* @param {function(number, !WebInspector.CPUProfileNode, number)} openFrameCallback
* @param {function(number, !WebInspector.CPUProfileNode, number, number, number)} closeFrameCallback
* @param {function(number, !ProfilerAgent.CPUProfileNode, number)} openFrameCallback
* @param {function(number, !ProfilerAgent.CPUProfileNode, number, number, number)} closeFrameCallback
* @param {number=} startTime
* @param {number=} stopTime
*/
Expand Down Expand Up @@ -370,7 +358,7 @@ WebInspector.CPUProfileDataModel.prototype = {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
closeFrameCallback(prevNode.depth, /** @type {!WebInspector.CPUProfileNode} */(prevNode), start, duration, duration - stackChildrenDuration[stackTop]);
closeFrameCallback(prevNode.depth, prevNode, start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
if (node.depth === prevNode.depth) {
stackNodes.push(node);
Expand Down Expand Up @@ -402,19 +390,18 @@ WebInspector.CPUProfileDataModel.prototype = {
var start = stackStartTimes[stackTop];
var duration = sampleTime - start;
stackChildrenDuration[stackTop - 1] += duration;
closeFrameCallback(node.depth, /** @type {!WebInspector.CPUProfileNode} */(node), start, duration, duration - stackChildrenDuration[stackTop]);
closeFrameCallback(node.depth, node, start, duration, duration - stackChildrenDuration[stackTop]);
--stackTop;
}
},

/**
* @param {number} index
* @return {!WebInspector.CPUProfileNode}
* @return {!ProfilerAgent.CPUProfileNode}
*/
nodeByIndex: function(index)
{
return this._idToNode[this.samples[index]];
},
}

__proto__: WebInspector.ProfileTreeModel.prototype
}
Loading

0 comments on commit c0fed8a

Please sign in to comment.