| 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 * @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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |