OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 /** | |
6 * @constructor | |
7 * @implements {WebInspector.Searchable} | 5 * @implements {WebInspector.Searchable} |
8 * @extends {WebInspector.ProfileView} | 6 * @unrestricted |
9 * @param {!WebInspector.SamplingHeapProfileHeader} profileHeader | 7 */ |
10 */ | 8 WebInspector.HeapProfileView = class extends WebInspector.ProfileView { |
11 WebInspector.HeapProfileView = function(profileHeader) | 9 /** |
12 { | 10 * @param {!WebInspector.SamplingHeapProfileHeader} profileHeader |
13 WebInspector.ProfileView.call(this); | 11 */ |
| 12 constructor(profileHeader) { |
| 13 super(); |
14 this._profileHeader = profileHeader; | 14 this._profileHeader = profileHeader; |
15 this.profile = new WebInspector.SamplingHeapProfileModel(profileHeader._prof
ile || profileHeader.protocolProfile()); | 15 this.profile = new WebInspector.SamplingHeapProfileModel(profileHeader._prof
ile || profileHeader.protocolProfile()); |
16 this.adjustedTotal = this.profile.total; | 16 this.adjustedTotal = this.profile.total; |
17 var views = [ | 17 var views = [ |
18 WebInspector.ProfileView.ViewTypes.Flame, | 18 WebInspector.ProfileView.ViewTypes.Flame, WebInspector.ProfileView.ViewTyp
es.Heavy, |
19 WebInspector.ProfileView.ViewTypes.Heavy, | 19 WebInspector.ProfileView.ViewTypes.Tree |
20 WebInspector.ProfileView.ViewTypes.Tree | |
21 ]; | 20 ]; |
22 this.initialize(new WebInspector.HeapProfileView.NodeFormatter(this), views)
; | 21 this.initialize(new WebInspector.HeapProfileView.NodeFormatter(this), views)
; |
23 }; | 22 } |
24 | 23 |
25 WebInspector.HeapProfileView.prototype = { | 24 /** |
26 /** | 25 * @override |
27 * @override | 26 * @param {string} columnId |
28 * @param {string} columnId | 27 * @return {string} |
29 * @return {string} | 28 */ |
30 */ | 29 columnHeader(columnId) { |
31 columnHeader: function(columnId) | 30 switch (columnId) { |
32 { | 31 case 'self': |
33 switch (columnId) { | 32 return WebInspector.UIString('Self Size (bytes)'); |
34 case "self": return WebInspector.UIString("Self Size (bytes)"); | 33 case 'total': |
35 case "total": return WebInspector.UIString("Total Size (bytes)"); | 34 return WebInspector.UIString('Total Size (bytes)'); |
36 } | 35 } |
37 return ""; | 36 return ''; |
38 }, | 37 } |
39 | 38 |
40 /** | 39 /** |
41 * @override | 40 * @override |
42 * @return {!WebInspector.FlameChartDataProvider} | 41 * @return {!WebInspector.FlameChartDataProvider} |
43 */ | 42 */ |
44 createFlameChartDataProvider: function() | 43 createFlameChartDataProvider() { |
45 { | 44 return new WebInspector.HeapFlameChartDataProvider(this.profile, this._profi
leHeader.target()); |
46 return new WebInspector.HeapFlameChartDataProvider(this.profile, this._p
rofileHeader.target()); | 45 } |
47 }, | 46 }; |
48 | 47 |
49 __proto__: WebInspector.ProfileView.prototype | 48 /** |
50 }; | 49 * @unrestricted |
51 | 50 */ |
52 /** | 51 WebInspector.SamplingHeapProfileType = class extends WebInspector.ProfileType { |
53 * @constructor | 52 constructor() { |
54 * @extends {WebInspector.ProfileType} | 53 super(WebInspector.SamplingHeapProfileType.TypeId, WebInspector.UIString('Re
cord Allocation Profile')); |
55 */ | |
56 WebInspector.SamplingHeapProfileType = function() | |
57 { | |
58 WebInspector.ProfileType.call(this, WebInspector.SamplingHeapProfileType.Typ
eId, WebInspector.UIString("Record Allocation Profile")); | |
59 this._recording = false; | 54 this._recording = false; |
60 WebInspector.SamplingHeapProfileType.instance = this; | 55 WebInspector.SamplingHeapProfileType.instance = this; |
61 }; | 56 } |
62 | 57 |
63 WebInspector.SamplingHeapProfileType.TypeId = "SamplingHeap"; | 58 /** |
64 | 59 * @override |
65 WebInspector.SamplingHeapProfileType.prototype = { | 60 * @return {string} |
66 /** | 61 */ |
67 * @override | 62 typeName() { |
68 * @return {string} | 63 return 'Heap'; |
69 */ | 64 } |
70 typeName: function() | 65 |
71 { | 66 /** |
72 return "Heap"; | 67 * @override |
73 }, | 68 * @return {string} |
74 | 69 */ |
75 /** | 70 fileExtension() { |
76 * @override | 71 return '.heapprofile'; |
77 * @return {string} | 72 } |
78 */ | 73 |
79 fileExtension: function() | 74 get buttonTooltip() { |
80 { | 75 return this._recording ? WebInspector.UIString('Stop heap profiling') : |
81 return ".heapprofile"; | 76 WebInspector.UIString('Start heap profiling'); |
82 }, | 77 } |
83 | 78 |
84 get buttonTooltip() | 79 /** |
85 { | 80 * @override |
86 return this._recording ? WebInspector.UIString("Stop heap profiling") :
WebInspector.UIString("Start heap profiling"); | 81 * @return {boolean} |
87 }, | 82 */ |
88 | 83 buttonClicked() { |
89 /** | 84 var wasRecording = this._recording; |
90 * @override | 85 if (wasRecording) |
91 * @return {boolean} | 86 this.stopRecordingProfile(); |
92 */ | 87 else |
93 buttonClicked: function() | 88 this.startRecordingProfile(); |
94 { | 89 return !wasRecording; |
95 var wasRecording = this._recording; | 90 } |
96 if (wasRecording) | 91 |
97 this.stopRecordingProfile(); | 92 get treeItemTitle() { |
98 else | 93 return WebInspector.UIString('ALLOCATION PROFILES'); |
99 this.startRecordingProfile(); | 94 } |
100 return !wasRecording; | 95 |
101 }, | 96 get description() { |
102 | 97 return WebInspector.UIString('Allocation profiles show memory allocations fr
om your JavaScript functions.'); |
103 get treeItemTitle() | 98 } |
104 { | 99 |
105 return WebInspector.UIString("ALLOCATION PROFILES"); | 100 startRecordingProfile() { |
106 }, | 101 var target = WebInspector.context.flavor(WebInspector.Target); |
107 | 102 if (this._profileBeingRecorded || !target) |
108 get description() | 103 return; |
109 { | 104 var profile = new WebInspector.SamplingHeapProfileHeader(target, this); |
110 return WebInspector.UIString("Allocation profiles show memory allocation
s from your JavaScript functions."); | 105 this.setProfileBeingRecorded(profile); |
111 }, | 106 WebInspector.targetManager.suspendAllTargets(); |
112 | 107 this.addProfile(profile); |
113 startRecordingProfile: function() | 108 profile.updateStatus(WebInspector.UIString('Recording\u2026')); |
114 { | 109 this._recording = true; |
115 var target = WebInspector.context.flavor(WebInspector.Target); | 110 target.heapProfilerModel.startSampling(); |
116 if (this._profileBeingRecorded || !target) | 111 } |
117 return; | 112 |
118 var profile = new WebInspector.SamplingHeapProfileHeader(target, this); | 113 stopRecordingProfile() { |
119 this.setProfileBeingRecorded(profile); | 114 this._recording = false; |
120 WebInspector.targetManager.suspendAllTargets(); | 115 if (!this._profileBeingRecorded || !this._profileBeingRecorded.target()) |
121 this.addProfile(profile); | 116 return; |
122 profile.updateStatus(WebInspector.UIString("Recording\u2026")); | 117 |
123 this._recording = true; | 118 var recordedProfile; |
124 target.heapProfilerModel.startSampling(); | 119 |
125 }, | 120 /** |
126 | 121 * @param {?HeapProfilerAgent.SamplingHeapProfile} profile |
127 stopRecordingProfile: function() | 122 * @this {WebInspector.SamplingHeapProfileType} |
128 { | 123 */ |
129 this._recording = false; | 124 function didStopProfiling(profile) { |
130 if (!this._profileBeingRecorded || !this._profileBeingRecorded.target()) | 125 if (!this._profileBeingRecorded) |
131 return; | 126 return; |
132 | 127 console.assert(profile); |
133 var recordedProfile; | 128 this._profileBeingRecorded.setProtocolProfile(profile); |
134 | 129 this._profileBeingRecorded.updateStatus(''); |
135 /** | 130 recordedProfile = this._profileBeingRecorded; |
136 * @param {?HeapProfilerAgent.SamplingHeapProfile} profile | 131 this.setProfileBeingRecorded(null); |
137 * @this {WebInspector.SamplingHeapProfileType} | 132 } |
138 */ | 133 |
139 function didStopProfiling(profile) | 134 /** |
140 { | 135 * @this {WebInspector.SamplingHeapProfileType} |
141 if (!this._profileBeingRecorded) | 136 */ |
142 return; | 137 function fireEvent() { |
143 console.assert(profile); | 138 this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileCompl
ete, recordedProfile); |
144 this._profileBeingRecorded.setProtocolProfile(profile); | 139 } |
145 this._profileBeingRecorded.updateStatus(""); | 140 |
146 recordedProfile = this._profileBeingRecorded; | 141 this._profileBeingRecorded.target() |
147 this.setProfileBeingRecorded(null); | 142 .heapProfilerModel.stopSampling() |
148 } | 143 .then(didStopProfiling.bind(this)) |
149 | 144 .then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targ
etManager)) |
150 /** | 145 .then(fireEvent.bind(this)); |
151 * @this {WebInspector.SamplingHeapProfileType} | 146 } |
152 */ | 147 |
153 function fireEvent() | 148 /** |
154 { | 149 * @override |
155 this.dispatchEventToListeners(WebInspector.ProfileType.Events.Profil
eComplete, recordedProfile); | 150 * @param {string} title |
156 } | 151 * @return {!WebInspector.ProfileHeader} |
157 | 152 */ |
158 this._profileBeingRecorded.target().heapProfilerModel.stopSampling() | 153 createProfileLoadedFromFile(title) { |
159 .then(didStopProfiling.bind(this)) | 154 return new WebInspector.SamplingHeapProfileHeader(null, this, title); |
160 .then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.
targetManager)) | 155 } |
161 .then(fireEvent.bind(this)); | 156 |
162 }, | 157 /** |
163 | 158 * @override |
164 /** | 159 */ |
165 * @override | 160 profileBeingRecordedRemoved() { |
166 * @param {string} title | 161 this.stopRecordingProfile(); |
167 * @return {!WebInspector.ProfileHeader} | 162 } |
168 */ | 163 }; |
169 createProfileLoadedFromFile: function(title) | 164 |
170 { | 165 WebInspector.SamplingHeapProfileType.TypeId = 'SamplingHeap'; |
171 return new WebInspector.SamplingHeapProfileHeader(null, this, title); | 166 |
172 }, | 167 /** |
173 | 168 * @unrestricted |
174 /** | 169 */ |
175 * @override | 170 WebInspector.SamplingHeapProfileHeader = class extends WebInspector.WritableProf
ileHeader { |
176 */ | 171 /** |
177 profileBeingRecordedRemoved: function() | 172 * @param {?WebInspector.Target} target |
178 { | 173 * @param {!WebInspector.SamplingHeapProfileType} type |
179 this.stopRecordingProfile(); | 174 * @param {string=} title |
180 }, | 175 */ |
181 | 176 constructor(target, type, title) { |
182 __proto__: WebInspector.ProfileType.prototype | 177 super(target, type, title || WebInspector.UIString('Profile %d', type.nextPr
ofileUid())); |
183 }; | 178 } |
184 | 179 |
185 /** | 180 /** |
186 * @constructor | 181 * @override |
187 * @extends {WebInspector.WritableProfileHeader} | 182 * @return {!WebInspector.ProfileView} |
188 * @param {?WebInspector.Target} target | 183 */ |
189 * @param {!WebInspector.SamplingHeapProfileType} type | 184 createView() { |
190 * @param {string=} title | 185 return new WebInspector.HeapProfileView(this); |
191 */ | 186 } |
192 WebInspector.SamplingHeapProfileHeader = function(target, type, title) | 187 |
193 { | 188 /** |
194 WebInspector.WritableProfileHeader.call(this, target, type, title || WebInsp
ector.UIString("Profile %d", type.nextProfileUid())); | 189 * @return {!HeapProfilerAgent.SamplingHeapProfile} |
195 }; | 190 */ |
196 | 191 protocolProfile() { |
197 WebInspector.SamplingHeapProfileHeader.prototype = { | 192 return this._protocolProfile; |
198 /** | 193 } |
199 * @override | 194 }; |
200 * @return {!WebInspector.ProfileView} | 195 |
201 */ | 196 /** |
202 createView: function() | 197 * @unrestricted |
203 { | 198 */ |
204 return new WebInspector.HeapProfileView(this); | 199 WebInspector.SamplingHeapProfileNode = class extends WebInspector.ProfileNode { |
205 }, | 200 /** |
206 | 201 * @param {!HeapProfilerAgent.SamplingHeapProfileNode} node |
207 /** | 202 */ |
208 * @return {!HeapProfilerAgent.SamplingHeapProfile} | 203 constructor(node) { |
209 */ | |
210 protocolProfile: function() | |
211 { | |
212 return this._protocolProfile; | |
213 }, | |
214 | |
215 __proto__: WebInspector.WritableProfileHeader.prototype | |
216 }; | |
217 | |
218 /** | |
219 * @constructor | |
220 * @extends {WebInspector.ProfileNode} | |
221 * @param {!HeapProfilerAgent.SamplingHeapProfileNode} node | |
222 */ | |
223 WebInspector.SamplingHeapProfileNode = function(node) | |
224 { | |
225 var callFrame = node.callFrame || /** @type {!RuntimeAgent.CallFrame} */ ({ | 204 var callFrame = node.callFrame || /** @type {!RuntimeAgent.CallFrame} */ ({ |
226 // Backward compatibility for old CpuProfileNode format. | 205 // Backward compatibility for old CpuProfileNode format. |
227 functionName: node["functionName"], | 206 functionName: node['functionName'], |
228 scriptId: node["scriptId"], | 207 scriptId: node['scriptId'], |
229 url: node["url"], | 208 url: node['url'], |
230 lineNumber: node["lineNumber"] - 1, | 209 lineNumber: node['lineNumber'] - 1, |
231 columnNumber: node["columnNumber"] - 1 | 210 columnNumber: node['columnNumber'] - 1 |
232 }); | 211 }); |
233 WebInspector.ProfileNode.call(this, callFrame); | 212 super(callFrame); |
234 this.self = node.selfSize; | 213 this.self = node.selfSize; |
235 }; | 214 } |
236 | 215 }; |
237 WebInspector.SamplingHeapProfileNode.prototype = { | 216 |
238 __proto__: WebInspector.ProfileNode.prototype | 217 /** |
239 }; | 218 * @unrestricted |
240 | 219 */ |
241 /** | 220 WebInspector.SamplingHeapProfileModel = class extends WebInspector.ProfileTreeMo
del { |
242 * @constructor | 221 /** |
243 * @extends {WebInspector.ProfileTreeModel} | 222 * @param {!HeapProfilerAgent.SamplingHeapProfile} profile |
244 * @param {!HeapProfilerAgent.SamplingHeapProfile} profile | 223 */ |
245 */ | 224 constructor(profile) { |
246 WebInspector.SamplingHeapProfileModel = function(profile) | 225 super(); |
247 { | |
248 WebInspector.ProfileTreeModel.call(this); | |
249 this.initialize(translateProfileTree(profile.head)); | 226 this.initialize(translateProfileTree(profile.head)); |
250 | 227 |
251 /** | 228 /** |
252 * @param {!HeapProfilerAgent.SamplingHeapProfileNode} root | 229 * @param {!HeapProfilerAgent.SamplingHeapProfileNode} root |
253 * @return {!WebInspector.SamplingHeapProfileNode} | 230 * @return {!WebInspector.SamplingHeapProfileNode} |
254 */ | 231 */ |
255 function translateProfileTree(root) | 232 function translateProfileTree(root) { |
256 { | 233 var resultRoot = new WebInspector.SamplingHeapProfileNode(root); |
257 var resultRoot = new WebInspector.SamplingHeapProfileNode(root); | 234 var targetNodeStack = [resultRoot]; |
258 var targetNodeStack = [resultRoot]; | 235 var sourceNodeStack = [root]; |
259 var sourceNodeStack = [root]; | 236 while (sourceNodeStack.length) { |
260 while (sourceNodeStack.length) { | 237 var sourceNode = sourceNodeStack.pop(); |
261 var sourceNode = sourceNodeStack.pop(); | 238 var parentNode = targetNodeStack.pop(); |
262 var parentNode = targetNodeStack.pop(); | 239 parentNode.children = sourceNode.children.map(child => new WebInspector.
SamplingHeapProfileNode(child)); |
263 parentNode.children = sourceNode.children.map(child => new WebInspec
tor.SamplingHeapProfileNode(child)); | 240 sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children); |
264 sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children); | 241 targetNodeStack.push.apply(targetNodeStack, parentNode.children); |
265 targetNodeStack.push.apply(targetNodeStack, parentNode.children); | 242 } |
266 } | 243 return resultRoot; |
267 return resultRoot; | 244 } |
268 } | 245 } |
269 }; | 246 }; |
270 | 247 |
271 WebInspector.SamplingHeapProfileModel.prototype = { | 248 /** |
272 | |
273 __proto__: WebInspector.ProfileTreeModel.prototype | |
274 }; | |
275 | |
276 /** | |
277 * @constructor | |
278 * @implements {WebInspector.ProfileDataGridNode.Formatter} | 249 * @implements {WebInspector.ProfileDataGridNode.Formatter} |
279 * @param {!WebInspector.ProfileView} profileView | 250 * @unrestricted |
280 */ | 251 */ |
281 WebInspector.HeapProfileView.NodeFormatter = function(profileView) | 252 WebInspector.HeapProfileView.NodeFormatter = class { |
282 { | 253 /** |
| 254 * @param {!WebInspector.ProfileView} profileView |
| 255 */ |
| 256 constructor(profileView) { |
283 this._profileView = profileView; | 257 this._profileView = profileView; |
284 }; | 258 } |
285 | 259 |
286 WebInspector.HeapProfileView.NodeFormatter.prototype = { | 260 /** |
287 /** | 261 * @override |
288 * @override | 262 * @param {number} value |
289 * @param {number} value | 263 * @return {string} |
290 * @return {string} | 264 */ |
291 */ | 265 formatValue(value) { |
292 formatValue: function(value) | 266 return Number.withThousandsSeparator(value); |
293 { | 267 } |
294 return Number.withThousandsSeparator(value); | 268 |
295 }, | 269 /** |
296 | 270 * @override |
297 /** | 271 * @param {number} value |
298 * @override | 272 * @param {!WebInspector.ProfileDataGridNode} node |
299 * @param {number} value | 273 * @return {string} |
300 * @param {!WebInspector.ProfileDataGridNode} node | 274 */ |
301 * @return {string} | 275 formatPercent(value, node) { |
302 */ | 276 return WebInspector.UIString('%.2f\u2009%%', value); |
303 formatPercent: function(value, node) | 277 } |
304 { | 278 |
305 return WebInspector.UIString("%.2f\u2009%%", value); | 279 /** |
306 }, | 280 * @override |
307 | 281 * @param {!WebInspector.ProfileDataGridNode} node |
308 /** | 282 * @return {?Element} |
309 * @override | 283 */ |
310 * @param {!WebInspector.ProfileDataGridNode} node | 284 linkifyNode(node) { |
311 * @return {?Element} | 285 return this._profileView.linkifier().maybeLinkifyConsoleCallFrame( |
312 */ | 286 this._profileView.target(), node.profileNode.callFrame, 'profile-node-fi
le'); |
313 linkifyNode: function(node) | 287 } |
314 { | 288 }; |
315 return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(this._
profileView.target(), node.profileNode.callFrame, "profile-node-file"); | 289 |
316 } | 290 /** |
317 }; | 291 * @unrestricted |
318 | 292 */ |
319 /** | 293 WebInspector.HeapFlameChartDataProvider = class extends WebInspector.ProfileFlam
eChartDataProvider { |
320 * @constructor | 294 /** |
321 * @extends {WebInspector.ProfileFlameChartDataProvider} | 295 * @param {!WebInspector.ProfileTreeModel} profile |
322 * @param {!WebInspector.ProfileTreeModel} profile | 296 * @param {?WebInspector.Target} target |
323 * @param {?WebInspector.Target} target | 297 */ |
324 */ | 298 constructor(profile, target) { |
325 WebInspector.HeapFlameChartDataProvider = function(profile, target) | 299 super(target); |
326 { | |
327 WebInspector.ProfileFlameChartDataProvider.call(this, target); | |
328 this._profile = profile; | 300 this._profile = profile; |
329 }; | 301 } |
330 | 302 |
331 WebInspector.HeapFlameChartDataProvider.prototype = { | 303 /** |
332 /** | 304 * @override |
333 * @override | 305 * @return {number} |
| 306 */ |
| 307 minimumBoundary() { |
| 308 return 0; |
| 309 } |
| 310 |
| 311 /** |
| 312 * @override |
| 313 * @return {number} |
| 314 */ |
| 315 totalTime() { |
| 316 return this._profile.root.total; |
| 317 } |
| 318 |
| 319 /** |
| 320 * @override |
| 321 * @param {number} value |
| 322 * @param {number=} precision |
| 323 * @return {string} |
| 324 */ |
| 325 formatValue(value, precision) { |
| 326 return WebInspector.UIString('%s\u2009KB', Number.withThousandsSeparator(val
ue / 1e3)); |
| 327 } |
| 328 |
| 329 /** |
| 330 * @override |
| 331 * @return {!WebInspector.FlameChart.TimelineData} |
| 332 */ |
| 333 _calculateTimelineData() { |
| 334 /** |
| 335 * @param {!WebInspector.ProfileNode} node |
334 * @return {number} | 336 * @return {number} |
335 */ | 337 */ |
336 minimumBoundary: function() | 338 function nodesCount(node) { |
337 { | 339 return node.children.reduce((count, node) => count + nodesCount(node), 1); |
338 return 0; | 340 } |
339 }, | 341 var count = nodesCount(this._profile.root); |
340 | 342 /** @type {!Array<!WebInspector.ProfileNode>} */ |
341 /** | 343 var entryNodes = new Array(count); |
342 * @override | 344 var entryLevels = new Uint16Array(count); |
343 * @return {number} | 345 var entryTotalTimes = new Float32Array(count); |
344 */ | 346 var entryStartTimes = new Float64Array(count); |
345 totalTime: function() | 347 var depth = 0; |
346 { | 348 var maxDepth = 0; |
347 return this._profile.root.total; | 349 var position = 0; |
348 }, | 350 var index = 0; |
349 | 351 |
350 /** | 352 /** |
351 * @override | 353 * @param {!WebInspector.ProfileNode} node |
352 * @param {number} value | 354 */ |
353 * @param {number=} precision | 355 function addNode(node) { |
354 * @return {string} | 356 var start = position; |
355 */ | 357 entryNodes[index] = node; |
356 formatValue: function(value, precision) | 358 entryLevels[index] = depth; |
357 { | 359 entryTotalTimes[index] = node.total; |
358 return WebInspector.UIString("%s\u2009KB", Number.withThousandsSeparator
(value / 1e3)); | 360 entryStartTimes[index] = position; |
359 }, | 361 ++index; |
360 | 362 ++depth; |
361 /** | 363 node.children.forEach(addNode); |
362 * @override | 364 --depth; |
363 * @return {!WebInspector.FlameChart.TimelineData} | 365 maxDepth = Math.max(maxDepth, depth); |
364 */ | 366 position = start + node.total; |
365 _calculateTimelineData: function() | 367 } |
366 { | 368 addNode(this._profile.root); |
367 /** | 369 |
368 * @param {!WebInspector.ProfileNode} node | 370 this._maxStackDepth = maxDepth + 1; |
369 * @return {number} | 371 this._entryNodes = entryNodes; |
370 */ | 372 this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevels, e
ntryTotalTimes, entryStartTimes, null); |
371 function nodesCount(node) | 373 |
372 { | 374 return this._timelineData; |
373 return node.children.reduce((count, node) => count + nodesCount(node
), 1); | 375 } |
374 } | 376 |
375 var count = nodesCount(this._profile.root); | 377 /** |
376 /** @type {!Array<!WebInspector.ProfileNode>} */ | 378 * @override |
377 var entryNodes = new Array(count); | 379 * @param {number} entryIndex |
378 var entryLevels = new Uint16Array(count); | 380 * @return {?Element} |
379 var entryTotalTimes = new Float32Array(count); | 381 */ |
380 var entryStartTimes = new Float64Array(count); | 382 prepareHighlightedEntryInfo(entryIndex) { |
381 var depth = 0; | 383 var node = this._entryNodes[entryIndex]; |
382 var maxDepth = 0; | 384 if (!node) |
383 var position = 0; | 385 return null; |
384 var index = 0; | 386 var entryInfo = []; |
385 | 387 /** |
386 /** | 388 * @param {string} title |
387 * @param {!WebInspector.ProfileNode} node | 389 * @param {string} value |
388 */ | 390 */ |
389 function addNode(node) | 391 function pushEntryInfoRow(title, value) { |
390 { | 392 entryInfo.push({title: title, value: value}); |
391 var start = position; | 393 } |
392 entryNodes[index] = node; | 394 pushEntryInfoRow(WebInspector.UIString('Name'), WebInspector.beautifyFunctio
nName(node.functionName)); |
393 entryLevels[index] = depth; | 395 pushEntryInfoRow(WebInspector.UIString('Self size'), Number.bytesToString(no
de.self)); |
394 entryTotalTimes[index] = node.total; | 396 pushEntryInfoRow(WebInspector.UIString('Total size'), Number.bytesToString(n
ode.total)); |
395 entryStartTimes[index] = position; | 397 var linkifier = new WebInspector.Linkifier(); |
396 ++index; | 398 var link = linkifier.maybeLinkifyConsoleCallFrame(this._target, node.callFra
me); |
397 ++depth; | 399 if (link) |
398 node.children.forEach(addNode); | 400 pushEntryInfoRow(WebInspector.UIString('URL'), link.textContent); |
399 --depth; | 401 linkifier.dispose(); |
400 maxDepth = Math.max(maxDepth, depth); | 402 return WebInspector.ProfileView.buildPopoverTable(entryInfo); |
401 position = start + node.total; | 403 } |
402 } | 404 }; |
403 addNode(this._profile.root); | |
404 | |
405 this._maxStackDepth = maxDepth + 1; | |
406 this._entryNodes = entryNodes; | |
407 this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevel
s, entryTotalTimes, entryStartTimes, null); | |
408 | |
409 return this._timelineData; | |
410 }, | |
411 | |
412 /** | |
413 * @override | |
414 * @param {number} entryIndex | |
415 * @return {?Element} | |
416 */ | |
417 prepareHighlightedEntryInfo: function(entryIndex) | |
418 { | |
419 var node = this._entryNodes[entryIndex]; | |
420 if (!node) | |
421 return null; | |
422 var entryInfo = []; | |
423 /** | |
424 * @param {string} title | |
425 * @param {string} value | |
426 */ | |
427 function pushEntryInfoRow(title, value) | |
428 { | |
429 entryInfo.push({ title: title, value: value }); | |
430 } | |
431 pushEntryInfoRow(WebInspector.UIString("Name"), WebInspector.beautifyFun
ctionName(node.functionName)); | |
432 pushEntryInfoRow(WebInspector.UIString("Self size"), Number.bytesToStrin
g(node.self)); | |
433 pushEntryInfoRow(WebInspector.UIString("Total size"), Number.bytesToStri
ng(node.total)); | |
434 var linkifier = new WebInspector.Linkifier(); | |
435 var link = linkifier.maybeLinkifyConsoleCallFrame(this._target, node.cal
lFrame); | |
436 if (link) | |
437 pushEntryInfoRow(WebInspector.UIString("URL"), link.textContent); | |
438 linkifier.dispose(); | |
439 return WebInspector.ProfileView.buildPopoverTable(entryInfo); | |
440 }, | |
441 | |
442 __proto__: WebInspector.ProfileFlameChartDataProvider.prototype | |
443 }; | |
OLD | NEW |