OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @constructor | 6 * @constructor |
7 * @extends {WebInspector.ProfileNode} | 7 * @extends {WebInspector.ProfileNode} |
8 * @param {!ProfilerAgent.CPUProfileNode} node | 8 * @param {!ProfilerAgent.CPUProfileNode} node |
9 * @param {number} sampleTime | 9 * @param {number} sampleTime |
10 */ | 10 */ |
(...skipping 24 matching lines...) Expand all Loading... |
35 * @param {!ProfilerAgent.CPUProfile} profile | 35 * @param {!ProfilerAgent.CPUProfile} profile |
36 */ | 36 */ |
37 WebInspector.CPUProfileDataModel = function(profile) | 37 WebInspector.CPUProfileDataModel = function(profile) |
38 { | 38 { |
39 this.samples = profile.samples; | 39 this.samples = profile.samples; |
40 this.timestamps = profile.timestamps; | 40 this.timestamps = profile.timestamps; |
41 // Convert times from sec to msec. | 41 // Convert times from sec to msec. |
42 this.profileStartTime = profile.startTime * 1000; | 42 this.profileStartTime = profile.startTime * 1000; |
43 this.profileEndTime = profile.endTime * 1000; | 43 this.profileEndTime = profile.endTime * 1000; |
44 this.totalHitCount = 0; | 44 this.totalHitCount = 0; |
45 this.profileHead = this._translateProfileTree(profile.head); | 45 this.profileHead = this._translateProfileTree(profile.nodes); |
46 WebInspector.ProfileTreeModel.call(this, this.profileHead); | 46 WebInspector.ProfileTreeModel.call(this, this.profileHead); |
47 this._extractMetaNodes(); | 47 this._extractMetaNodes(); |
48 if (this.samples) { | 48 if (this.samples) { |
49 this._buildIdToNodeMap(); | 49 this._buildIdToNodeMap(); |
50 this._sortSamples(); | 50 this._sortSamples(); |
51 this._normalizeTimestamps(); | 51 this._normalizeTimestamps(); |
52 } | 52 } |
53 } | 53 } |
54 | 54 |
55 WebInspector.CPUProfileDataModel.prototype = { | 55 WebInspector.CPUProfileDataModel.prototype = { |
56 /** | 56 /** |
57 * @param {!ProfilerAgent.CPUProfileNode} root | 57 * @param {!Array<!ProfilerAgent.CPUProfileNode>} nodes |
58 * @return {!WebInspector.CPUProfileNode} | 58 * @return {!WebInspector.CPUProfileNode} |
59 */ | 59 */ |
60 _translateProfileTree: function(root) | 60 _translateProfileTree: function(nodes) |
61 { | 61 { |
62 /** | 62 /** |
63 * @param {!ProfilerAgent.CPUProfileNode} node | |
64 * @return {number} | |
65 */ | |
66 function computeHitCountForSubtree(node) | |
67 { | |
68 return node.children.reduce((acc, node) => acc + computeHitCountForS
ubtree(node), node.hitCount); | |
69 } | |
70 /** | |
71 * @param {!ProfilerAgent.CPUProfileNode} node | 63 * @param {!ProfilerAgent.CPUProfileNode} node |
72 * @return {boolean} | 64 * @return {boolean} |
73 */ | 65 */ |
74 function isNativeNode(node) | 66 function isNativeNode(node) |
75 { | 67 { |
76 if (node.callFrame) | 68 if (node.callFrame) |
77 return !!node.callFrame.url && node.callFrame.url.startsWith("na
tive "); | 69 return !!node.callFrame.url && node.callFrame.url.startsWith("na
tive "); |
78 return !!node.url && node.url.startsWith("native "); | 70 return !!node.url && node.url.startsWith("native "); |
79 } | 71 } |
80 this.totalHitCount = computeHitCountForSubtree(root); | 72 /** @type {!Map<number, !ProfilerAgent.CPUProfileNode>} */ |
| 73 var nodeByIdMap = new Map(); |
| 74 for (var i = 0; i < nodes.length; ++i) { |
| 75 var node = nodes[i]; |
| 76 nodeByIdMap.set(node.id, node); |
| 77 } |
| 78 this.totalHitCount = nodes.reduce((acc, node) => acc + node.hitCount, 0)
; |
81 var sampleTime = (this.profileEndTime - this.profileStartTime) / this.to
talHitCount; | 79 var sampleTime = (this.profileEndTime - this.profileStartTime) / this.to
talHitCount; |
82 var keepNatives = !!WebInspector.moduleSetting("showNativeFunctionsInJSP
rofile").get(); | 80 var keepNatives = !!WebInspector.moduleSetting("showNativeFunctionsInJSP
rofile").get(); |
| 81 var root = nodes[0]; |
83 /** @type {!Map<number, number>} */ | 82 /** @type {!Map<number, number>} */ |
84 var idMap = new Map([[root.id, root.id]]); | 83 var idMap = new Map([[root.id, root.id]]); |
85 var resultRoot = new WebInspector.CPUProfileNode(root, sampleTime); | 84 var resultRoot = new WebInspector.CPUProfileNode(root, sampleTime); |
86 var parentNodeStack = root.children.map(() => resultRoot); | 85 var parentNodeStack = root.children.map(() => resultRoot); |
87 var sourceNodeStack = root.children; | 86 var sourceNodeStack = root.children.map(id => nodeByIdMap.get(id)); |
88 while (sourceNodeStack.length) { | 87 while (sourceNodeStack.length) { |
89 var parentNode = parentNodeStack.pop(); | 88 var parentNode = parentNodeStack.pop(); |
90 var sourceNode = sourceNodeStack.pop(); | 89 var sourceNode = sourceNodeStack.pop(); |
91 var targetNode = new WebInspector.CPUProfileNode(sourceNode, sampleT
ime); | 90 var targetNode = new WebInspector.CPUProfileNode(sourceNode, sampleT
ime); |
92 if (keepNatives || !isNativeNode(sourceNode)) { | 91 if (keepNatives || !isNativeNode(sourceNode)) { |
93 parentNode.children.push(targetNode); | 92 parentNode.children.push(targetNode); |
94 parentNode = targetNode; | 93 parentNode = targetNode; |
95 } else { | 94 } else { |
96 parentNode.self += targetNode.self; | 95 parentNode.self += targetNode.self; |
97 } | 96 } |
98 idMap.set(sourceNode.id, parentNode.id); | 97 idMap.set(sourceNode.id, parentNode.id); |
99 parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(
() => parentNode)); | 98 parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(
() => parentNode)); |
100 sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children); | 99 sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(
id => nodeByIdMap.get(id))); |
101 } | 100 } |
102 if (this.samples) | 101 if (this.samples) |
103 this.samples = this.samples.map(id => idMap.get(id)); | 102 this.samples = this.samples.map(id => idMap.get(id)); |
104 return resultRoot; | 103 return resultRoot; |
105 }, | 104 }, |
106 | 105 |
107 _sortSamples: function() | 106 _sortSamples: function() |
108 { | 107 { |
109 var timestamps = this.timestamps; | 108 var timestamps = this.timestamps; |
110 if (!timestamps) | 109 if (!timestamps) |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 * @param {number} index | 297 * @param {number} index |
299 * @return {?WebInspector.CPUProfileNode} | 298 * @return {?WebInspector.CPUProfileNode} |
300 */ | 299 */ |
301 nodeByIndex: function(index) | 300 nodeByIndex: function(index) |
302 { | 301 { |
303 return this._idToNode.get(this.samples[index]) || null; | 302 return this._idToNode.get(this.samples[index]) || null; |
304 }, | 303 }, |
305 | 304 |
306 __proto__: WebInspector.ProfileTreeModel.prototype | 305 __proto__: WebInspector.ProfileTreeModel.prototype |
307 } | 306 } |
OLD | NEW |