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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25 /**
26 /**
27 * @constructor
28 * @implements {WebInspector.Searchable} 26 * @implements {WebInspector.Searchable}
29 * @extends {WebInspector.ProfileView} 27 * @unrestricted
30 * @param {!WebInspector.CPUProfileHeader} profileHeader 28 */
31 */ 29 WebInspector.CPUProfileView = class extends WebInspector.ProfileView {
32 WebInspector.CPUProfileView = function(profileHeader) 30 /**
33 { 31 * @param {!WebInspector.CPUProfileHeader} profileHeader
34 WebInspector.ProfileView.call(this); 32 */
33 constructor(profileHeader) {
34 super();
35 this._profileHeader = profileHeader; 35 this._profileHeader = profileHeader;
36 this.profile = new WebInspector.CPUProfileDataModel(profileHeader._profile | | profileHeader.protocolProfile()); 36 this.profile = new WebInspector.CPUProfileDataModel(profileHeader._profile | | profileHeader.protocolProfile());
37 this.adjustedTotal = this.profile.profileHead.total; 37 this.adjustedTotal = this.profile.profileHead.total;
38 this.adjustedTotal -= this.profile.idleNode ? this.profile.idleNode.total : 0; 38 this.adjustedTotal -= this.profile.idleNode ? this.profile.idleNode.total : 0;
39 this.initialize(new WebInspector.CPUProfileView.NodeFormatter(this)); 39 this.initialize(new WebInspector.CPUProfileView.NodeFormatter(this));
40 }; 40 }
41 41
42 WebInspector.CPUProfileView.prototype = { 42 /**
43 * @override
44 */
45 wasShown() {
46 super.wasShown();
47 var lineLevelProfile = WebInspector.LineLevelProfile.instance();
48 lineLevelProfile.reset();
49 lineLevelProfile.appendCPUProfile(this.profile);
50 }
51
52 /**
53 * @override
54 * @param {string} columnId
55 * @return {string}
56 */
57 columnHeader(columnId) {
58 switch (columnId) {
59 case 'self':
60 return WebInspector.UIString('Self Time');
61 case 'total':
62 return WebInspector.UIString('Total Time');
63 }
64 return '';
65 }
66
67 /**
68 * @override
69 * @return {!WebInspector.FlameChartDataProvider}
70 */
71 createFlameChartDataProvider() {
72 return new WebInspector.CPUFlameChartDataProvider(this.profile, this._profil eHeader.target());
73 }
74 };
75
76 /**
77 * @unrestricted
78 */
79 WebInspector.CPUProfileType = class extends WebInspector.ProfileType {
80 constructor() {
81 super(WebInspector.CPUProfileType.TypeId, WebInspector.UIString('Record Java Script CPU Profile'));
82 this._recording = false;
83
84 this._nextAnonymousConsoleProfileNumber = 1;
85 this._anonymousConsoleProfileIdToTitle = {};
86
87 WebInspector.CPUProfileType.instance = this;
88 WebInspector.targetManager.addModelListener(
89 WebInspector.CPUProfilerModel, WebInspector.CPUProfilerModel.Events.Cons oleProfileStarted,
90 this._consoleProfileStarted, this);
91 WebInspector.targetManager.addModelListener(
92 WebInspector.CPUProfilerModel, WebInspector.CPUProfilerModel.Events.Cons oleProfileFinished,
93 this._consoleProfileFinished, this);
94 }
95
96 /**
97 * @override
98 * @return {string}
99 */
100 typeName() {
101 return 'CPU';
102 }
103
104 /**
105 * @override
106 * @return {string}
107 */
108 fileExtension() {
109 return '.cpuprofile';
110 }
111
112 get buttonTooltip() {
113 return this._recording ? WebInspector.UIString('Stop CPU profiling') : WebIn spector.UIString('Start CPU profiling');
114 }
115
116 /**
117 * @override
118 * @return {boolean}
119 */
120 buttonClicked() {
121 if (this._recording) {
122 this.stopRecordingProfile();
123 return false;
124 } else {
125 this.startRecordingProfile();
126 return true;
127 }
128 }
129
130 get treeItemTitle() {
131 return WebInspector.UIString('CPU PROFILES');
132 }
133
134 get description() {
135 return WebInspector.UIString(
136 'CPU profiles show where the execution time is spent in your page\'s Jav aScript functions.');
137 }
138
139 /**
140 * @param {!WebInspector.Event} event
141 */
142 _consoleProfileStarted(event) {
143 var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ (event.da ta);
144 var resolvedTitle = data.title;
145 if (!resolvedTitle) {
146 resolvedTitle = WebInspector.UIString('Profile %s', this._nextAnonymousCon soleProfileNumber++);
147 this._anonymousConsoleProfileIdToTitle[data.id] = resolvedTitle;
148 }
149 this._addMessageToConsole(
150 WebInspector.ConsoleMessage.MessageType.Profile, data.scriptLocation,
151 WebInspector.UIString('Profile \'%s\' started.', resolvedTitle));
152 }
153
154 /**
155 * @param {!WebInspector.Event} event
156 */
157 _consoleProfileFinished(event) {
158 var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ (event.da ta);
159 var cpuProfile = /** @type {!ProfilerAgent.Profile} */ (data.cpuProfile);
160 var resolvedTitle = data.title;
161 if (typeof resolvedTitle === 'undefined') {
162 resolvedTitle = this._anonymousConsoleProfileIdToTitle[data.id];
163 delete this._anonymousConsoleProfileIdToTitle[data.id];
164 }
165 var profile = new WebInspector.CPUProfileHeader(data.scriptLocation.target() , this, resolvedTitle);
166 profile.setProtocolProfile(cpuProfile);
167 this.addProfile(profile);
168 this._addMessageToConsole(
169 WebInspector.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation,
170 WebInspector.UIString('Profile \'%s\' finished.', resolvedTitle));
171 }
172
173 /**
174 * @param {string} type
175 * @param {!WebInspector.DebuggerModel.Location} scriptLocation
176 * @param {string} messageText
177 */
178 _addMessageToConsole(type, scriptLocation, messageText) {
179 var script = scriptLocation.script();
180 var target = scriptLocation.target();
181 var message = new WebInspector.ConsoleMessage(
182 target, WebInspector.ConsoleMessage.MessageSource.ConsoleAPI, WebInspect or.ConsoleMessage.MessageLevel.Debug,
183 messageText, type, undefined, undefined, undefined, undefined, [{
184 functionName: '',
185 scriptId: scriptLocation.scriptId,
186 url: script ? script.contentURL() : '',
187 lineNumber: scriptLocation.lineNumber,
188 columnNumber: scriptLocation.columnNumber || 0
189 }]);
190
191 target.consoleModel.addMessage(message);
192 }
193
194 startRecordingProfile() {
195 var target = WebInspector.context.flavor(WebInspector.Target);
196 if (this._profileBeingRecorded || !target)
197 return;
198 var profile = new WebInspector.CPUProfileHeader(target, this);
199 this.setProfileBeingRecorded(profile);
200 WebInspector.targetManager.suspendAllTargets();
201 this.addProfile(profile);
202 profile.updateStatus(WebInspector.UIString('Recording\u2026'));
203 this._recording = true;
204 target.cpuProfilerModel.startRecording();
205 }
206
207 stopRecordingProfile() {
208 this._recording = false;
209 if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
210 return;
211
212 var recordedProfile;
213
43 /** 214 /**
44 * @override 215 * @param {?ProfilerAgent.Profile} profile
216 * @this {WebInspector.CPUProfileType}
45 */ 217 */
46 wasShown: function() 218 function didStopProfiling(profile) {
47 { 219 if (!this._profileBeingRecorded)
48 WebInspector.ProfileView.prototype.wasShown.call(this); 220 return;
49 var lineLevelProfile = WebInspector.LineLevelProfile.instance(); 221 console.assert(profile);
50 lineLevelProfile.reset(); 222 this._profileBeingRecorded.setProtocolProfile(profile);
51 lineLevelProfile.appendCPUProfile(this.profile); 223 this._profileBeingRecorded.updateStatus('');
52 }, 224 recordedProfile = this._profileBeingRecorded;
225 this.setProfileBeingRecorded(null);
226 }
53 227
54 /** 228 /**
55 * @override 229 * @this {WebInspector.CPUProfileType}
56 * @param {string} columnId 230 */
231 function fireEvent() {
232 this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileCompl ete, recordedProfile);
233 }
234
235 this._profileBeingRecorded.target()
236 .cpuProfilerModel.stopRecording()
237 .then(didStopProfiling.bind(this))
238 .then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targ etManager))
239 .then(fireEvent.bind(this));
240 }
241
242 /**
243 * @override
244 * @param {string} title
245 * @return {!WebInspector.ProfileHeader}
246 */
247 createProfileLoadedFromFile(title) {
248 return new WebInspector.CPUProfileHeader(null, this, title);
249 }
250
251 /**
252 * @override
253 */
254 profileBeingRecordedRemoved() {
255 this.stopRecordingProfile();
256 }
257 };
258
259 WebInspector.CPUProfileType.TypeId = 'CPU';
260
261 /**
262 * @unrestricted
263 */
264 WebInspector.CPUProfileHeader = class extends WebInspector.WritableProfileHeader {
265 /**
266 * @param {?WebInspector.Target} target
267 * @param {!WebInspector.CPUProfileType} type
268 * @param {string=} title
269 */
270 constructor(target, type, title) {
271 super(target, type, title);
272 }
273
274 /**
275 * @override
276 * @return {!WebInspector.ProfileView}
277 */
278 createView() {
279 return new WebInspector.CPUProfileView(this);
280 }
281
282 /**
283 * @return {!ProfilerAgent.Profile}
284 */
285 protocolProfile() {
286 return this._protocolProfile;
287 }
288 };
289
290 /**
291 * @implements {WebInspector.ProfileDataGridNode.Formatter}
292 * @unrestricted
293 */
294 WebInspector.CPUProfileView.NodeFormatter = class {
295 constructor(profileView) {
296 this._profileView = profileView;
297 }
298
299 /**
300 * @override
301 * @param {number} value
302 * @return {string}
303 */
304 formatValue(value) {
305 return WebInspector.UIString('%.1f\u2009ms', value);
306 }
307
308 /**
309 * @override
310 * @param {number} value
311 * @param {!WebInspector.ProfileDataGridNode} node
312 * @return {string}
313 */
314 formatPercent(value, node) {
315 return node.profileNode === this._profileView.profile.idleNode ? '' : WebIns pector.UIString('%.2f\u2009%%', value);
316 }
317
318 /**
319 * @override
320 * @param {!WebInspector.ProfileDataGridNode} node
321 * @return {?Element}
322 */
323 linkifyNode(node) {
324 return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(
325 this._profileView.target(), node.profileNode.callFrame, 'profile-node-fi le');
326 }
327 };
328
329 /**
330 * @unrestricted
331 */
332 WebInspector.CPUFlameChartDataProvider = class extends WebInspector.ProfileFlame ChartDataProvider {
333 /**
334 * @param {!WebInspector.CPUProfileDataModel} cpuProfile
335 * @param {?WebInspector.Target} target
336 */
337 constructor(cpuProfile, target) {
338 super(target);
339 this._cpuProfile = cpuProfile;
340 }
341
342 /**
343 * @override
344 * @return {!WebInspector.FlameChart.TimelineData}
345 */
346 _calculateTimelineData() {
347 /** @type {!Array.<?WebInspector.CPUFlameChartDataProvider.ChartEntry>} */
348 var entries = [];
349 /** @type {!Array.<number>} */
350 var stack = [];
351 var maxDepth = 5;
352
353 function onOpenFrame() {
354 stack.push(entries.length);
355 // Reserve space for the entry, as they have to be ordered by startTime.
356 // The entry itself will be put there in onCloseFrame.
357 entries.push(null);
358 }
359 /**
360 * @param {number} depth
361 * @param {!WebInspector.CPUProfileNode} node
362 * @param {number} startTime
363 * @param {number} totalTime
364 * @param {number} selfTime
365 */
366 function onCloseFrame(depth, node, startTime, totalTime, selfTime) {
367 var index = stack.pop();
368 entries[index] =
369 new WebInspector.CPUFlameChartDataProvider.ChartEntry(depth, totalTime , startTime, selfTime, node);
370 maxDepth = Math.max(maxDepth, depth);
371 }
372 this._cpuProfile.forEachFrame(onOpenFrame, onCloseFrame);
373
374 /** @type {!Array<!WebInspector.CPUProfileNode>} */
375 var entryNodes = new Array(entries.length);
376 var entryLevels = new Uint16Array(entries.length);
377 var entryTotalTimes = new Float32Array(entries.length);
378 var entrySelfTimes = new Float32Array(entries.length);
379 var entryStartTimes = new Float64Array(entries.length);
380 var minimumBoundary = this.minimumBoundary();
381
382 for (var i = 0; i < entries.length; ++i) {
383 var entry = entries[i];
384 entryNodes[i] = entry.node;
385 entryLevels[i] = entry.depth;
386 entryTotalTimes[i] = entry.duration;
387 entryStartTimes[i] = entry.startTime;
388 entrySelfTimes[i] = entry.selfTime;
389 }
390
391 this._maxStackDepth = maxDepth;
392
393 this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevels, e ntryTotalTimes, entryStartTimes, null);
394
395 /** @type {!Array<!WebInspector.CPUProfileNode>} */
396 this._entryNodes = entryNodes;
397 this._entrySelfTimes = entrySelfTimes;
398
399 return this._timelineData;
400 }
401
402 /**
403 * @override
404 * @param {number} entryIndex
405 * @return {?Element}
406 */
407 prepareHighlightedEntryInfo(entryIndex) {
408 var timelineData = this._timelineData;
409 var node = this._entryNodes[entryIndex];
410 if (!node)
411 return null;
412
413 var entryInfo = [];
414 /**
415 * @param {string} title
416 * @param {string} value
417 */
418 function pushEntryInfoRow(title, value) {
419 entryInfo.push({title: title, value: value});
420 }
421 /**
422 * @param {number} ms
57 * @return {string} 423 * @return {string}
58 */ 424 */
59 columnHeader: function(columnId) 425 function millisecondsToString(ms) {
60 { 426 if (ms === 0)
61 switch (columnId) { 427 return '0';
62 case "self": return WebInspector.UIString("Self Time"); 428 if (ms < 1000)
63 case "total": return WebInspector.UIString("Total Time"); 429 return WebInspector.UIString('%.1f\u2009ms', ms);
64 } 430 return Number.secondsToString(ms / 1000, true);
65 return ""; 431 }
66 }, 432 var name = WebInspector.beautifyFunctionName(node.functionName);
67 433 pushEntryInfoRow(WebInspector.UIString('Name'), name);
68 /** 434 var selfTime = millisecondsToString(this._entrySelfTimes[entryIndex]);
69 * @override 435 var totalTime = millisecondsToString(timelineData.entryTotalTimes[entryIndex ]);
70 * @return {!WebInspector.FlameChartDataProvider} 436 pushEntryInfoRow(WebInspector.UIString('Self time'), selfTime);
71 */ 437 pushEntryInfoRow(WebInspector.UIString('Total time'), totalTime);
72 createFlameChartDataProvider: function() 438 var linkifier = new WebInspector.Linkifier();
73 { 439 var link = linkifier.maybeLinkifyConsoleCallFrame(this._target, node.callFra me);
74 return new WebInspector.CPUFlameChartDataProvider(this.profile, this._pr ofileHeader.target()); 440 if (link)
75 }, 441 pushEntryInfoRow(WebInspector.UIString('URL'), link.textContent);
76 442 linkifier.dispose();
77 __proto__: WebInspector.ProfileView.prototype 443 pushEntryInfoRow(WebInspector.UIString('Aggregated self time'), Number.secon dsToString(node.self / 1000, true));
78 }; 444 pushEntryInfoRow(WebInspector.UIString('Aggregated total time'), Number.seco ndsToString(node.total / 1000, true));
79 445 if (node.deoptReason)
80 /** 446 pushEntryInfoRow(WebInspector.UIString('Not optimized'), node.deoptReason) ;
81 * @constructor 447
82 * @extends {WebInspector.ProfileType} 448 return WebInspector.ProfileView.buildPopoverTable(entryInfo);
83 */ 449 }
84 WebInspector.CPUProfileType = function() 450 };
85 { 451
86 WebInspector.ProfileType.call(this, WebInspector.CPUProfileType.TypeId, WebI nspector.UIString("Record JavaScript CPU Profile")); 452 /**
87 this._recording = false; 453 * @unrestricted
88 454 */
89 this._nextAnonymousConsoleProfileNumber = 1; 455 WebInspector.CPUFlameChartDataProvider.ChartEntry = class {
90 this._anonymousConsoleProfileIdToTitle = {}; 456 /**
91 457 * @param {number} depth
92 WebInspector.CPUProfileType.instance = this; 458 * @param {number} duration
93 WebInspector.targetManager.addModelListener(WebInspector.CPUProfilerModel, W ebInspector.CPUProfilerModel.Events.ConsoleProfileStarted, this._consoleProfileS tarted, this); 459 * @param {number} startTime
94 WebInspector.targetManager.addModelListener(WebInspector.CPUProfilerModel, W ebInspector.CPUProfilerModel.Events.ConsoleProfileFinished, this._consoleProfile Finished, this); 460 * @param {number} selfTime
95 }; 461 * @param {!WebInspector.CPUProfileNode} node
96 462 */
97 WebInspector.CPUProfileType.TypeId = "CPU"; 463 constructor(depth, duration, startTime, selfTime, node) {
98 464 this.depth = depth;
99 WebInspector.CPUProfileType.prototype = { 465 this.duration = duration;
100 /** 466 this.startTime = startTime;
101 * @override 467 this.selfTime = selfTime;
102 * @return {string} 468 this.node = node;
103 */ 469 }
104 typeName: function() 470 };
105 {
106 return "CPU";
107 },
108
109 /**
110 * @override
111 * @return {string}
112 */
113 fileExtension: function()
114 {
115 return ".cpuprofile";
116 },
117
118 get buttonTooltip()
119 {
120 return this._recording ? WebInspector.UIString("Stop CPU profiling") : W ebInspector.UIString("Start CPU profiling");
121 },
122
123 /**
124 * @override
125 * @return {boolean}
126 */
127 buttonClicked: function()
128 {
129 if (this._recording) {
130 this.stopRecordingProfile();
131 return false;
132 } else {
133 this.startRecordingProfile();
134 return true;
135 }
136 },
137
138 get treeItemTitle()
139 {
140 return WebInspector.UIString("CPU PROFILES");
141 },
142
143 get description()
144 {
145 return WebInspector.UIString("CPU profiles show where the execution time is spent in your page's JavaScript functions.");
146 },
147
148 /**
149 * @param {!WebInspector.Event} event
150 */
151 _consoleProfileStarted: function(event)
152 {
153 var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ (even t.data);
154 var resolvedTitle = data.title;
155 if (!resolvedTitle) {
156 resolvedTitle = WebInspector.UIString("Profile %s", this._nextAnonym ousConsoleProfileNumber++);
157 this._anonymousConsoleProfileIdToTitle[data.id] = resolvedTitle;
158 }
159 this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.Profil e, data.scriptLocation, WebInspector.UIString("Profile '%s' started.", resolvedT itle));
160 },
161
162 /**
163 * @param {!WebInspector.Event} event
164 */
165 _consoleProfileFinished: function(event)
166 {
167 var data = /** @type {!WebInspector.CPUProfilerModel.EventData} */ (even t.data);
168 var cpuProfile = /** @type {!ProfilerAgent.Profile} */ (data.cpuProfile) ;
169 var resolvedTitle = data.title;
170 if (typeof resolvedTitle === "undefined") {
171 resolvedTitle = this._anonymousConsoleProfileIdToTitle[data.id];
172 delete this._anonymousConsoleProfileIdToTitle[data.id];
173 }
174 var profile = new WebInspector.CPUProfileHeader(data.scriptLocation.targ et(), this, resolvedTitle);
175 profile.setProtocolProfile(cpuProfile);
176 this.addProfile(profile);
177 this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.Profil eEnd, data.scriptLocation, WebInspector.UIString("Profile '%s' finished.", resol vedTitle));
178 },
179
180 /**
181 * @param {string} type
182 * @param {!WebInspector.DebuggerModel.Location} scriptLocation
183 * @param {string} messageText
184 */
185 _addMessageToConsole: function(type, scriptLocation, messageText)
186 {
187 var script = scriptLocation.script();
188 var target = scriptLocation.target();
189 var message = new WebInspector.ConsoleMessage(
190 target,
191 WebInspector.ConsoleMessage.MessageSource.ConsoleAPI,
192 WebInspector.ConsoleMessage.MessageLevel.Debug,
193 messageText,
194 type,
195 undefined,
196 undefined,
197 undefined,
198 undefined,
199 [{
200 functionName: "",
201 scriptId: scriptLocation.scriptId,
202 url: script ? script.contentURL() : "",
203 lineNumber: scriptLocation.lineNumber,
204 columnNumber: scriptLocation.columnNumber || 0
205 }]);
206
207 target.consoleModel.addMessage(message);
208 },
209
210 startRecordingProfile: function()
211 {
212 var target = WebInspector.context.flavor(WebInspector.Target);
213 if (this._profileBeingRecorded || !target)
214 return;
215 var profile = new WebInspector.CPUProfileHeader(target, this);
216 this.setProfileBeingRecorded(profile);
217 WebInspector.targetManager.suspendAllTargets();
218 this.addProfile(profile);
219 profile.updateStatus(WebInspector.UIString("Recording\u2026"));
220 this._recording = true;
221 target.cpuProfilerModel.startRecording();
222 },
223
224 stopRecordingProfile: function()
225 {
226 this._recording = false;
227 if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
228 return;
229
230 var recordedProfile;
231
232 /**
233 * @param {?ProfilerAgent.Profile} profile
234 * @this {WebInspector.CPUProfileType}
235 */
236 function didStopProfiling(profile)
237 {
238 if (!this._profileBeingRecorded)
239 return;
240 console.assert(profile);
241 this._profileBeingRecorded.setProtocolProfile(profile);
242 this._profileBeingRecorded.updateStatus("");
243 recordedProfile = this._profileBeingRecorded;
244 this.setProfileBeingRecorded(null);
245 }
246
247 /**
248 * @this {WebInspector.CPUProfileType}
249 */
250 function fireEvent()
251 {
252 this.dispatchEventToListeners(WebInspector.ProfileType.Events.Profil eComplete, recordedProfile);
253 }
254
255 this._profileBeingRecorded.target().cpuProfilerModel.stopRecording()
256 .then(didStopProfiling.bind(this))
257 .then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector. targetManager))
258 .then(fireEvent.bind(this));
259 },
260
261 /**
262 * @override
263 * @param {string} title
264 * @return {!WebInspector.ProfileHeader}
265 */
266 createProfileLoadedFromFile: function(title)
267 {
268 return new WebInspector.CPUProfileHeader(null, this, title);
269 },
270
271 /**
272 * @override
273 */
274 profileBeingRecordedRemoved: function()
275 {
276 this.stopRecordingProfile();
277 },
278
279 __proto__: WebInspector.ProfileType.prototype
280 };
281
282 /**
283 * @constructor
284 * @extends {WebInspector.WritableProfileHeader}
285 * @param {?WebInspector.Target} target
286 * @param {!WebInspector.CPUProfileType} type
287 * @param {string=} title
288 */
289 WebInspector.CPUProfileHeader = function(target, type, title)
290 {
291 WebInspector.WritableProfileHeader.call(this, target, type, title);
292 };
293
294 WebInspector.CPUProfileHeader.prototype = {
295 /**
296 * @override
297 * @return {!WebInspector.ProfileView}
298 */
299 createView: function()
300 {
301 return new WebInspector.CPUProfileView(this);
302 },
303
304 /**
305 * @return {!ProfilerAgent.Profile}
306 */
307 protocolProfile: function()
308 {
309 return this._protocolProfile;
310 },
311
312 __proto__: WebInspector.WritableProfileHeader.prototype
313 };
314
315 /**
316 * @implements {WebInspector.ProfileDataGridNode.Formatter}
317 * @constructor
318 */
319 WebInspector.CPUProfileView.NodeFormatter = function(profileView)
320 {
321 this._profileView = profileView;
322 };
323
324 WebInspector.CPUProfileView.NodeFormatter.prototype = {
325 /**
326 * @override
327 * @param {number} value
328 * @return {string}
329 */
330 formatValue: function(value)
331 {
332 return WebInspector.UIString("%.1f\u2009ms", value);
333 },
334
335 /**
336 * @override
337 * @param {number} value
338 * @param {!WebInspector.ProfileDataGridNode} node
339 * @return {string}
340 */
341 formatPercent: function(value, node)
342 {
343 return node.profileNode === this._profileView.profile.idleNode ? "" : We bInspector.UIString("%.2f\u2009%%", value);
344 },
345
346 /**
347 * @override
348 * @param {!WebInspector.ProfileDataGridNode} node
349 * @return {?Element}
350 */
351 linkifyNode: function(node)
352 {
353 return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(this._ profileView.target(), node.profileNode.callFrame, "profile-node-file");
354 }
355 };
356
357 /**
358 * @constructor
359 * @extends {WebInspector.ProfileFlameChartDataProvider}
360 * @param {!WebInspector.CPUProfileDataModel} cpuProfile
361 * @param {?WebInspector.Target} target
362 */
363 WebInspector.CPUFlameChartDataProvider = function(cpuProfile, target)
364 {
365 WebInspector.ProfileFlameChartDataProvider.call(this, target);
366 this._cpuProfile = cpuProfile;
367 };
368
369 WebInspector.CPUFlameChartDataProvider.prototype = {
370 /**
371 * @override
372 * @return {!WebInspector.FlameChart.TimelineData}
373 */
374 _calculateTimelineData: function()
375 {
376 /**
377 * @constructor
378 * @param {number} depth
379 * @param {number} duration
380 * @param {number} startTime
381 * @param {number} selfTime
382 * @param {!WebInspector.CPUProfileNode} node
383 */
384 function ChartEntry(depth, duration, startTime, selfTime, node)
385 {
386 this.depth = depth;
387 this.duration = duration;
388 this.startTime = startTime;
389 this.selfTime = selfTime;
390 this.node = node;
391 }
392
393 /** @type {!Array.<?ChartEntry>} */
394 var entries = [];
395 /** @type {!Array.<number>} */
396 var stack = [];
397 var maxDepth = 5;
398
399 function onOpenFrame()
400 {
401 stack.push(entries.length);
402 // Reserve space for the entry, as they have to be ordered by startT ime.
403 // The entry itself will be put there in onCloseFrame.
404 entries.push(null);
405 }
406 /**
407 * @param {number} depth
408 * @param {!WebInspector.CPUProfileNode} node
409 * @param {number} startTime
410 * @param {number} totalTime
411 * @param {number} selfTime
412 */
413 function onCloseFrame(depth, node, startTime, totalTime, selfTime)
414 {
415 var index = stack.pop();
416 entries[index] = new ChartEntry(depth, totalTime, startTime, selfTim e, node);
417 maxDepth = Math.max(maxDepth, depth);
418 }
419 this._cpuProfile.forEachFrame(onOpenFrame, onCloseFrame);
420
421 /** @type {!Array<!WebInspector.CPUProfileNode>} */
422 var entryNodes = new Array(entries.length);
423 var entryLevels = new Uint16Array(entries.length);
424 var entryTotalTimes = new Float32Array(entries.length);
425 var entrySelfTimes = new Float32Array(entries.length);
426 var entryStartTimes = new Float64Array(entries.length);
427 var minimumBoundary = this.minimumBoundary();
428
429 for (var i = 0; i < entries.length; ++i) {
430 var entry = entries[i];
431 entryNodes[i] = entry.node;
432 entryLevels[i] = entry.depth;
433 entryTotalTimes[i] = entry.duration;
434 entryStartTimes[i] = entry.startTime;
435 entrySelfTimes[i] = entry.selfTime;
436 }
437
438 this._maxStackDepth = maxDepth;
439
440 this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevel s, entryTotalTimes, entryStartTimes, null);
441
442 /** @type {!Array<!WebInspector.CPUProfileNode>} */
443 this._entryNodes = entryNodes;
444 this._entrySelfTimes = entrySelfTimes;
445
446 return this._timelineData;
447 },
448
449 /**
450 * @override
451 * @param {number} entryIndex
452 * @return {?Element}
453 */
454 prepareHighlightedEntryInfo: function(entryIndex)
455 {
456 var timelineData = this._timelineData;
457 var node = this._entryNodes[entryIndex];
458 if (!node)
459 return null;
460
461 var entryInfo = [];
462 /**
463 * @param {string} title
464 * @param {string} value
465 */
466 function pushEntryInfoRow(title, value)
467 {
468 entryInfo.push({ title: title, value: value });
469 }
470 /**
471 * @param {number} ms
472 * @return {string}
473 */
474 function millisecondsToString(ms)
475 {
476 if (ms === 0)
477 return "0";
478 if (ms < 1000)
479 return WebInspector.UIString("%.1f\u2009ms", ms);
480 return Number.secondsToString(ms / 1000, true);
481 }
482 var name = WebInspector.beautifyFunctionName(node.functionName);
483 pushEntryInfoRow(WebInspector.UIString("Name"), name);
484 var selfTime = millisecondsToString(this._entrySelfTimes[entryIndex]);
485 var totalTime = millisecondsToString(timelineData.entryTotalTimes[entryI ndex]);
486 pushEntryInfoRow(WebInspector.UIString("Self time"), selfTime);
487 pushEntryInfoRow(WebInspector.UIString("Total time"), totalTime);
488 var linkifier = new WebInspector.Linkifier();
489 var link = linkifier.maybeLinkifyConsoleCallFrame(this._target, node.cal lFrame);
490 if (link)
491 pushEntryInfoRow(WebInspector.UIString("URL"), link.textContent);
492 linkifier.dispose();
493 pushEntryInfoRow(WebInspector.UIString("Aggregated self time"), Number.s econdsToString(node.self / 1000, true));
494 pushEntryInfoRow(WebInspector.UIString("Aggregated total time"), Number. secondsToString(node.total / 1000, true));
495 if (node.deoptReason)
496 pushEntryInfoRow(WebInspector.UIString("Not optimized"), node.deoptR eason);
497
498 return WebInspector.ProfileView.buildPopoverTable(entryInfo);
499 },
500
501 __proto__: WebInspector.ProfileFlameChartDataProvider.prototype
502 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698