Index: Source/devtools/front_end/timeline/TracingTimelineModel.js |
diff --git a/Source/devtools/front_end/timeline/TracingTimelineModel.js b/Source/devtools/front_end/timeline/TracingTimelineModel.js |
index 3c7ea60f1462ca538491541b5ff4355ffdcea668..933bb04345e92c325ae84f1fa93fc01f35ff576f 100644 |
--- a/Source/devtools/front_end/timeline/TracingTimelineModel.js |
+++ b/Source/devtools/front_end/timeline/TracingTimelineModel.js |
@@ -69,6 +69,7 @@ WebInspector.TracingTimelineModel.RecordType = { |
FunctionCall: "FunctionCall", |
GCEvent: "GCEvent", |
JSFrame: "JSFrame", |
+ JSSample: "JSSample", |
UpdateCounters: "UpdateCounters", |
@@ -110,8 +111,15 @@ WebInspector.TracingTimelineModel.prototype = { |
return "disabled-by-default-" + category; |
} |
var categoriesArray = ["-*", disabledByDefault("devtools.timeline"), disabledByDefault("devtools.timeline.frame")]; |
- if (captureStacks) |
+ if (captureStacks) { |
categoriesArray.push(disabledByDefault("devtools.timeline.stack")); |
+ if (WebInspector.experimentsSettings.timelineJSCPUProfile.isEnabled()) { |
+ this._jsProfilerStarted = true; |
+ this._currentTarget = WebInspector.context.flavor(WebInspector.Target); |
+ this._configureCpuProfilerSamplingInterval(); |
+ this._currentTarget.profilerAgent().start(); |
+ } |
+ } |
if (capturePictures) { |
categoriesArray = categoriesArray.concat([ |
disabledByDefault("devtools.timeline.layers"), |
@@ -124,6 +132,11 @@ WebInspector.TracingTimelineModel.prototype = { |
stopRecording: function() |
{ |
+ this._stopCallbackBarrier = new CallbackBarrier(); |
+ if (this._jsProfilerStarted) { |
+ this._currentTarget.profilerAgent().stop(this._stopCallbackBarrier.createCallback(this._didStopRecordingJSSamples.bind(this))); |
+ this._jsProfilerStarted = false; |
+ } |
this._tracingModel.stop(); |
}, |
@@ -138,6 +151,18 @@ WebInspector.TracingTimelineModel.prototype = { |
this._onTracingComplete(); |
}, |
+ _configureCpuProfilerSamplingInterval: function() |
+ { |
+ var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000; |
+ this._currentTarget.profilerAgent().setSamplingInterval(intervalUs, didChangeInterval); |
+ |
+ function didChangeInterval(error) |
+ { |
+ if (error) |
+ WebInspector.console.error(error); |
+ } |
+ }, |
+ |
/** |
* @param {string} categories |
*/ |
@@ -155,6 +180,26 @@ WebInspector.TracingTimelineModel.prototype = { |
_onTracingComplete: function() |
{ |
+ if (this._stopCallbackBarrier) |
+ this._stopCallbackBarrier.callWhenDone(this._didStopRecordingTraceEvents.bind(this)); |
+ else |
+ this._didStopRecordingTraceEvents(); |
+ }, |
+ |
+ /** |
+ * @param {?Protocol.Error} error |
+ * @param {?ProfilerAgent.CPUProfile} cpuProfile |
+ */ |
+ _didStopRecordingJSSamples: function(error, cpuProfile) |
+ { |
+ if (error) |
+ WebInspector.console.error(error); |
+ this._cpuProfile = cpuProfile; |
+ }, |
+ |
+ _didStopRecordingTraceEvents: function() |
+ { |
+ this._stopCallbackBarrier = null; |
var events = this._tracingModel.devtoolsMetadataEvents(); |
events.sort(WebInspector.TracingModel.Event.compareStartTime); |
@@ -174,6 +219,13 @@ WebInspector.TracingTimelineModel.prototype = { |
this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime); |
+ if (this._cpuProfile) { |
+ var jsSamples = WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(this, this._cpuProfile); |
+ this._inspectedTargetEvents = this._inspectedTargetEvents.mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime); |
+ this._setMainThreadEvents(this.mainThreadEvents().mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime)); |
+ this._cpuProfile = null; |
+ } |
+ |
this._buildTimelineRecords(); |
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped); |
}, |
@@ -211,6 +263,14 @@ WebInspector.TracingTimelineModel.prototype = { |
}, |
/** |
+ * @param {!Array.<!WebInspector.TracingModel.Event>} events |
+ */ |
+ _setMainThreadEvents: function(events) |
+ { |
+ this._virtualThreads[WebInspector.TimelineModel.MainThreadName] = events; |
+ }, |
+ |
+ /** |
* @return {!Object.<string, !Array.<!WebInspector.TracingModel.Event>>} |
*/ |
virtualThreads: function() |