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

Side by Side Diff: Source/devtools/front_end/timeline/TracingTimelineModel.js

Issue 622843002: DevTools: Support timeline JS sampling for all threads. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: tweak Created 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/devtools/front_end/timeline/TracingModel.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 * @param {!WebInspector.TracingManager} tracingManager 7 * @param {!WebInspector.TracingManager} tracingManager
8 * @param {!WebInspector.TracingModel} tracingModel 8 * @param {!WebInspector.TracingModel} tracingModel
9 * @param {!WebInspector.TimelineModel.Filter} recordFilter 9 * @param {!WebInspector.TimelineModel.Filter} recordFilter
10 * @extends {WebInspector.TimelineModel} 10 * @extends {WebInspector.TimelineModel}
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 return "disabled-by-default-" + category; 138 return "disabled-by-default-" + category;
139 } 139 }
140 var categoriesArray = [ 140 var categoriesArray = [
141 "-*", 141 "-*",
142 disabledByDefault("devtools.timeline"), 142 disabledByDefault("devtools.timeline"),
143 disabledByDefault("devtools.timeline.frame"), 143 disabledByDefault("devtools.timeline.frame"),
144 WebInspector.TracingModel.ConsoleEventCategory 144 WebInspector.TracingModel.ConsoleEventCategory
145 ]; 145 ];
146 if (captureCauses || enableJSSampling) 146 if (captureCauses || enableJSSampling)
147 categoriesArray.push(disabledByDefault("devtools.timeline.stack")); 147 categoriesArray.push(disabledByDefault("devtools.timeline.stack"));
148 if (enableJSSampling) { 148 if (enableJSSampling)
149 this._jsProfilerStarted = true; 149 this._startCpuProfilingOnAllTargets();
150 this._currentTarget = WebInspector.context.flavor(WebInspector.Targe t);
151 this._configureCpuProfilerSamplingInterval();
152 this._currentTarget.profilerAgent().start();
153 }
154 if (captureCauses && Runtime.experiments.isEnabled("timelineInvalidation Tracking")) 150 if (captureCauses && Runtime.experiments.isEnabled("timelineInvalidation Tracking"))
155 categoriesArray.push(disabledByDefault("devtools.timeline.invalidati onTracking")); 151 categoriesArray.push(disabledByDefault("devtools.timeline.invalidati onTracking"));
156 if (capturePictures) { 152 if (capturePictures) {
157 categoriesArray = categoriesArray.concat([ 153 categoriesArray = categoriesArray.concat([
158 disabledByDefault("devtools.timeline.layers"), 154 disabledByDefault("devtools.timeline.layers"),
159 disabledByDefault("devtools.timeline.picture"), 155 disabledByDefault("devtools.timeline.picture"),
160 disabledByDefault("blink.graphics_context_annotations")]); 156 disabledByDefault("blink.graphics_context_annotations")]);
161 } 157 }
162 var categories = categoriesArray.join(","); 158 var categories = categoriesArray.join(",");
163 this._startRecordingWithCategories(categories); 159 this._startRecordingWithCategories(categories);
164 }, 160 },
165 161
166 stopRecording: function() 162 stopRecording: function()
167 { 163 {
168 if (this._jsProfilerStarted) { 164 this._stopCallbackBarrier = new CallbackBarrier();
169 this._stopCallbackBarrier = new CallbackBarrier(); 165 this._stopProfilingOnAllTargets();
170 this._currentTarget.profilerAgent().stop(this._stopCallbackBarrier.c reateCallback(this._didStopRecordingJSSamples.bind(this)));
171 this._jsProfilerStarted = false;
172 }
173 this._tracingManager.stop(); 166 this._tracingManager.stop();
174 }, 167 },
175 168
176 /** 169 /**
177 * @param {!Array.<!WebInspector.TracingManager.EventPayload>} events 170 * @param {!Array.<!WebInspector.TracingManager.EventPayload>} events
178 */ 171 */
179 setEventsForTest: function(events) 172 setEventsForTest: function(events)
180 { 173 {
181 this._startCollectingTraceEvents(false); 174 this._startCollectingTraceEvents(false);
182 this._tracingModel.addEvents(events); 175 this._tracingModel.addEvents(events);
183 this._onTracingComplete(); 176 this._onTracingComplete();
184 }, 177 },
185 178
186 _configureCpuProfilerSamplingInterval: function() 179 _startCpuProfilingOnAllTargets: function()
180 {
181 this._profilingTargets = WebInspector.targetManager.targets();
182 for (var i = 0; i < this._profilingTargets.length; ++i) {
183 var target = this._profilingTargets[i];
184 this._configureCpuProfilerSamplingInterval(target);
185 target.profilerAgent().start();
186 }
187 },
188
189 _stopProfilingOnAllTargets: function()
190 {
191 if (!this._profilingTargets)
192 return;
193 for (var i = 0; i < this._profilingTargets.length; ++i) {
194 var target = this._profilingTargets[i];
195 target.profilerAgent().stop(this._stopCallbackBarrier.createCallback (this._didStopRecordingJSSamples.bind(this, target)));
196 }
197 this._profilingTargets = null;
198 },
199
200 /**
201 * @param {!WebInspector.Target} target
202 */
203 _configureCpuProfilerSamplingInterval: function(target)
187 { 204 {
188 var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000; 205 var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000;
189 this._currentTarget.profilerAgent().setSamplingInterval(intervalUs, didC hangeInterval); 206 target.profilerAgent().setSamplingInterval(intervalUs, didChangeInterval );
190 207
191 function didChangeInterval(error) 208 function didChangeInterval(error)
192 { 209 {
193 if (error) 210 if (error)
194 WebInspector.console.error(error); 211 WebInspector.console.error(error);
195 } 212 }
196 }, 213 },
197 214
198 /** 215 /**
199 * @param {string} categories 216 * @param {string} categories
(...skipping 22 matching lines...) Expand all
222 * @param {!WebInspector.Event} event 239 * @param {!WebInspector.Event} event
223 */ 240 */
224 _onEventsCollected: function(event) 241 _onEventsCollected: function(event)
225 { 242 {
226 var traceEvents = /** @type {!Array.<!WebInspector.TracingManager.EventP ayload>} */ (event.data); 243 var traceEvents = /** @type {!Array.<!WebInspector.TracingManager.EventP ayload>} */ (event.data);
227 this._tracingModel.addEvents(traceEvents); 244 this._tracingModel.addEvents(traceEvents);
228 }, 245 },
229 246
230 _onTracingComplete: function() 247 _onTracingComplete: function()
231 { 248 {
232 if (this._stopCallbackBarrier) 249 if (this._stopCallbackBarrier) {
233 this._stopCallbackBarrier.callWhenDone(this._didStopRecordingTraceEv ents.bind(this)); 250 this._stopCallbackBarrier.callWhenDone(this._didStopRecordingTraceEv ents.bind(this));
234 else 251 this._stopCallbackBarrier = null;
252 } else {
235 this._didStopRecordingTraceEvents(); 253 this._didStopRecordingTraceEvents();
254 }
236 }, 255 },
237 256
238 /** 257 /**
258 * @param {!WebInspector.Target} target
239 * @param {?Protocol.Error} error 259 * @param {?Protocol.Error} error
240 * @param {?ProfilerAgent.CPUProfile} cpuProfile 260 * @param {?ProfilerAgent.CPUProfile} cpuProfile
241 */ 261 */
242 _didStopRecordingJSSamples: function(error, cpuProfile) 262 _didStopRecordingJSSamples: function(target, error, cpuProfile)
243 { 263 {
244 if (error) 264 if (error)
245 WebInspector.console.error(error); 265 WebInspector.console.error(error);
246 this._recordedCpuProfile = cpuProfile; 266 if (!this._cpuProfiles)
267 this._cpuProfiles = {};
268 this._cpuProfiles[target.id()] = cpuProfile;
247 }, 269 },
248 270
249 _didStopRecordingTraceEvents: function() 271 _didStopRecordingTraceEvents: function()
250 { 272 {
251 this._stopCallbackBarrier = null;
252
253 if (this._recordedCpuProfile) {
254 this._injectCpuProfileEvent(this._recordedCpuProfile);
255 this._recordedCpuProfile = null;
256 }
257 this._tracingModel.tracingComplete(); 273 this._tracingModel.tracingComplete();
258 274
259 var events = this._tracingModel.devtoolsPageMetadataEvents(); 275 var events = this._tracingModel.devtoolsPageMetadataEvents();
260 var workerMetadataEvents = this._tracingModel.devtoolsWorkerMetadataEven ts(); 276 var workerMetadataEvents = this._tracingModel.devtoolsWorkerMetadataEven ts();
261 277
262 this._resetProcessingState(); 278 this._resetProcessingState();
263 for (var i = 0, length = events.length; i < length; i++) { 279 for (var i = 0, length = events.length; i < length; i++) {
264 var event = events[i]; 280 var event = events[i];
265 var process = event.thread.process(); 281 var process = event.thread.process();
266 var startTime = event.startTime; 282 var startTime = event.startTime;
267 283
268 var endTime = Infinity; 284 var endTime = Infinity;
269 if (i + 1 < length) 285 if (i + 1 < length)
270 endTime = events[i + 1].startTime; 286 endTime = events[i + 1].startTime;
271 287
272 var threads = process.sortedThreads(); 288 var threads = process.sortedThreads();
273 for (var j = 0; j < threads.length; j++) { 289 for (var j = 0; j < threads.length; j++) {
274 var thread = threads[j]; 290 var thread = threads[j];
275 if (thread.name() === "WebCore: Worker" && !workerMetadataEvents .some(function(e) { return e.args["data"]["workerThreadId"] === thread.id(); })) 291 if (thread.name() === "WebCore: Worker" && workerMetadataEvents. every(function(e) { return e.args["data"]["workerThreadId"] !== thread.id(); }))
276 continue; 292 continue;
277 this._processThreadEvents(startTime, endTime, event.thread, thre ad); 293 this._processThreadEvents(startTime, endTime, event.thread, thre ad);
278 } 294 }
279 } 295 }
280 this._resetProcessingState(); 296 this._resetProcessingState();
281 297
282 this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compare StartTime); 298 this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compare StartTime);
283 299
284 if (this._cpuProfile) { 300 this._cpuProfiles = null;
285 this._processCpuProfile(this._cpuProfile); 301
286 this._cpuProfile = null;
287 }
288 this._buildTimelineRecords(); 302 this._buildTimelineRecords();
289 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin gStopped); 303 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin gStopped);
290 }, 304 },
291 305
292 /** 306 /**
293 * @param {!ProfilerAgent.CPUProfile} cpuProfile 307 * @param {!ProfilerAgent.CPUProfile} cpuProfile
294 */ 308 */
295 _injectCpuProfileEvent: function(cpuProfile) 309 _injectCpuProfileEvent: function(cpuProfile)
296 { 310 {
297 var metaEvent = this._tracingModel.devtoolsPageMetadataEvents().peekLast (); 311 var metaEvent = this._tracingModel.devtoolsPageMetadataEvents().peekLast ();
298 if (!metaEvent) 312 if (!metaEvent)
299 return; 313 return;
300 var cpuProfileEvent = /** @type {!WebInspector.TracingManager.EventPaylo ad} */ ({ 314 var cpuProfileEvent = /** @type {!WebInspector.TracingManager.EventPaylo ad} */ ({
301 cat: WebInspector.TracingModel.DevToolsMetadataEventCategory, 315 cat: WebInspector.TracingModel.DevToolsMetadataEventCategory,
302 ph: WebInspector.TracingModel.Phase.Instant, 316 ph: WebInspector.TracingModel.Phase.Instant,
303 ts: this._tracingModel.maximumRecordTime() * 1000, 317 ts: this._tracingModel.maximumRecordTime() * 1000,
304 pid: metaEvent.thread.process().id(), 318 pid: metaEvent.thread.process().id(),
305 tid: metaEvent.thread.id(), 319 tid: metaEvent.thread.id(),
306 name: WebInspector.TracingTimelineModel.RecordType.CpuProfile, 320 name: WebInspector.TracingTimelineModel.RecordType.CpuProfile,
307 args: { data: { cpuProfile: cpuProfile } } 321 args: { data: { cpuProfile: cpuProfile } }
308 }); 322 });
309 this._tracingModel.addEvents([cpuProfileEvent]); 323 this._tracingModel.addEvents([cpuProfileEvent]);
310 }, 324 },
311 325
312 /** 326 /**
313 * @param {!ProfilerAgent.CPUProfile} cpuProfile
314 */
315 _processCpuProfile: function(cpuProfile)
316 {
317 var jsSamples = WebInspector.TimelineJSProfileProcessor.generateTracingE ventsFromCpuProfile(this, cpuProfile);
318 this._inspectedTargetEvents = this._inspectedTargetEvents.mergeOrdered(j sSamples, WebInspector.TracingModel.Event.orderedCompareStartTime);
319 this._setMainThreadEvents(this.mainThreadEvents().mergeOrdered(jsSamples , WebInspector.TracingModel.Event.orderedCompareStartTime));
320 var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFr ameEvents(this.mainThreadEvents());
321 this._setMainThreadEvents(jsFrameEvents.mergeOrdered(this.mainThreadEven ts(), WebInspector.TracingModel.Event.orderedCompareStartTime));
322 this._inspectedTargetEvents = jsFrameEvents.mergeOrdered(this._inspected TargetEvents, WebInspector.TracingModel.Event.orderedCompareStartTime);
323 },
324
325 /**
326 * @return {number} 327 * @return {number}
327 */ 328 */
328 minimumRecordTime: function() 329 minimumRecordTime: function()
329 { 330 {
330 return this._tracingModel.minimumRecordTime(); 331 return this._tracingModel.minimumRecordTime();
331 }, 332 },
332 333
333 /** 334 /**
334 * @return {number} 335 * @return {number}
335 */ 336 */
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 * @param {!WebInspector.TracingModel.Thread} mainThread 505 * @param {!WebInspector.TracingModel.Thread} mainThread
505 * @param {!WebInspector.TracingModel.Thread} thread 506 * @param {!WebInspector.TracingModel.Thread} thread
506 */ 507 */
507 _processThreadEvents: function(startTime, endTime, mainThread, thread) 508 _processThreadEvents: function(startTime, endTime, mainThread, thread)
508 { 509 {
509 var events = thread.events(); 510 var events = thread.events();
510 var length = events.length; 511 var length = events.length;
511 var i = events.lowerBound(startTime, function (time, event) { return tim e - event.startTime }); 512 var i = events.lowerBound(startTime, function (time, event) { return tim e - event.startTime });
512 513
513 var threadEvents; 514 var threadEvents;
515 var virtualThread = null;
514 if (thread === mainThread) { 516 if (thread === mainThread) {
515 threadEvents = this._mainThreadEvents; 517 threadEvents = this._mainThreadEvents;
516 this._mainThreadAsyncEvents = this._mainThreadAsyncEvents.concat(thr ead.asyncEvents()); 518 this._mainThreadAsyncEvents = this._mainThreadAsyncEvents.concat(thr ead.asyncEvents());
517 } else { 519 } else {
518 var virtualThread = new WebInspector.TracingTimelineModel.VirtualThr ead(thread.name()); 520 virtualThread = new WebInspector.TracingTimelineModel.VirtualThread( thread.name());
519 threadEvents = virtualThread.events; 521 threadEvents = virtualThread.events;
520 virtualThread.asyncEvents = virtualThread.asyncEvents.concat(thread. asyncEvents()); 522 virtualThread.asyncEvents = virtualThread.asyncEvents.concat(thread. asyncEvents());
521 this._virtualThreads.push(virtualThread); 523 this._virtualThreads.push(virtualThread);
522 } 524 }
523 525
524 this._eventStack = []; 526 this._eventStack = [];
525 for (; i < length; i++) { 527 for (; i < length; i++) {
526 var event = events[i]; 528 var event = events[i];
527 if (endTime && event.startTime >= endTime) 529 if (endTime && event.startTime >= endTime)
528 break; 530 break;
529 this._processEvent(event); 531 this._processEvent(event);
530 threadEvents.push(event); 532 threadEvents.push(event);
531 this._inspectedTargetEvents.push(event); 533 this._inspectedTargetEvents.push(event);
532 } 534 }
535
536 if (this._cpuProfiles && thread.target()) {
537 var cpuProfile = this._cpuProfiles[thread.target().id()];
538 if (cpuProfile) {
539 var jsSamples = WebInspector.TimelineJSProfileProcessor.generate TracingEventsFromCpuProfile(cpuProfile, thread);
540 var mergedEvents = threadEvents.mergeOrdered(jsSamples, WebInspe ctor.TracingModel.Event.orderedCompareStartTime);
541 var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.gene rateJSFrameEvents(mergedEvents);
542 mergedEvents = jsFrameEvents.mergeOrdered(mergedEvents, WebInspe ctor.TracingModel.Event.orderedCompareStartTime);
543 if (virtualThread)
544 virtualThread.events = mergedEvents;
545 else
546 this._mainThreadEvents = mergedEvents;
547 this._inspectedTargetEvents = this._inspectedTargetEvents.concat (jsSamples, jsFrameEvents);
548 }
549 }
533 }, 550 },
534 551
535 /** 552 /**
536 * @param {!WebInspector.TracingModel.Event} event 553 * @param {!WebInspector.TracingModel.Event} event
537 */ 554 */
538 _processEvent: function(event) 555 _processEvent: function(event)
539 { 556 {
540 var recordTypes = WebInspector.TracingTimelineModel.RecordType; 557 var recordTypes = WebInspector.TracingTimelineModel.RecordType;
541 558
542 var eventStack = this._eventStack; 559 var eventStack = this._eventStack;
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 _initializePerFrameState: function() 1293 _initializePerFrameState: function()
1277 { 1294 {
1278 /** @type {!Array.<!WebInspector.InvalidationTrackingEvent>} */ 1295 /** @type {!Array.<!WebInspector.InvalidationTrackingEvent>} */
1279 this._invalidationEvents = []; 1296 this._invalidationEvents = [];
1280 this._lastStyleRecalcEventIndex = 0; 1297 this._lastStyleRecalcEventIndex = 0;
1281 this._lastLayoutEventIndex = 0; 1298 this._lastLayoutEventIndex = 0;
1282 this._lastPaintWithLayer = undefined; 1299 this._lastPaintWithLayer = undefined;
1283 this._didPaint = false; 1300 this._didPaint = false;
1284 } 1301 }
1285 } 1302 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/timeline/TracingModel.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698