Commit bc379acc authored by alph@chromium.org's avatar alph@chromium.org

DevTools: Support timeline JS sampling for all threads.

BUG=363976

Review URL: https://codereview.chromium.org/622843002

git-svn-id: svn://svn.chromium.org/blink/trunk@185121 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 0495e0ad
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
WebInspector.TimelineJSProfileProcessor = { }; WebInspector.TimelineJSProfileProcessor = { };
/** /**
* @param {!WebInspector.TracingTimelineModel} timelineModel
* @param {!ProfilerAgent.CPUProfile} jsProfile * @param {!ProfilerAgent.CPUProfile} jsProfile
* @param {!WebInspector.TracingModel.Thread} thread
* @return {!Array.<!WebInspector.TracingModel.Event>} * @return {!Array.<!WebInspector.TracingModel.Event>}
*/ */
WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(timelineModel, jsProfile) WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(jsProfile, thread)
{ {
if (!jsProfile.samples) if (!jsProfile.samples)
return []; return [];
...@@ -21,7 +21,6 @@ WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = fu ...@@ -21,7 +21,6 @@ WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = fu
var samples = jsProfileModel.samples; var samples = jsProfileModel.samples;
var timestamps = jsProfileModel.timestamps; var timestamps = jsProfileModel.timestamps;
var jsEvents = []; var jsEvents = [];
var mainThread = timelineModel.mainThreadEvents()[0].thread;
for (var i = 0; i < samples.length; ++i) { for (var i = 0; i < samples.length; ++i) {
var node = jsProfileModel.nodeByIndex(i); var node = jsProfileModel.nodeByIndex(i);
if (node === programNode || node === gcNode || node === idleNode) if (node === programNode || node === gcNode || node === idleNode)
...@@ -34,7 +33,7 @@ WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = fu ...@@ -34,7 +33,7 @@ WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = fu
stackTrace[j++] = /** @type {!ConsoleAgent.CallFrame} */ (node); stackTrace[j++] = /** @type {!ConsoleAgent.CallFrame} */ (node);
} }
var jsEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory, WebInspector.TracingTimelineModel.RecordType.JSSample, var jsEvent = new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsMetadataEventCategory, WebInspector.TracingTimelineModel.RecordType.JSSample,
WebInspector.TracingModel.Phase.Instant, timestamps[i], mainThread); WebInspector.TracingModel.Phase.Instant, timestamps[i], thread);
jsEvent.stackTrace = stackTrace; jsEvent.stackTrace = stackTrace;
jsEvents.push(jsEvent); jsEvents.push(jsEvent);
} }
......
...@@ -808,7 +808,10 @@ WebInspector.TracingModel.Thread.prototype = { ...@@ -808,7 +808,10 @@ WebInspector.TracingModel.Thread.prototype = {
target: function() target: function()
{ {
//FIXME: correctly specify target //FIXME: correctly specify target
return WebInspector.targetManager.targets()[0] || null; if (this.name() === "CrRendererMain")
return WebInspector.targetManager.targets()[0] || null;
else
return null;
}, },
/** /**
......
...@@ -145,12 +145,8 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -145,12 +145,8 @@ WebInspector.TracingTimelineModel.prototype = {
]; ];
if (captureCauses || enableJSSampling) if (captureCauses || enableJSSampling)
categoriesArray.push(disabledByDefault("devtools.timeline.stack")); categoriesArray.push(disabledByDefault("devtools.timeline.stack"));
if (enableJSSampling) { if (enableJSSampling)
this._jsProfilerStarted = true; this._startCpuProfilingOnAllTargets();
this._currentTarget = WebInspector.context.flavor(WebInspector.Target);
this._configureCpuProfilerSamplingInterval();
this._currentTarget.profilerAgent().start();
}
if (captureCauses && Runtime.experiments.isEnabled("timelineInvalidationTracking")) if (captureCauses && Runtime.experiments.isEnabled("timelineInvalidationTracking"))
categoriesArray.push(disabledByDefault("devtools.timeline.invalidationTracking")); categoriesArray.push(disabledByDefault("devtools.timeline.invalidationTracking"));
if (capturePictures) { if (capturePictures) {
...@@ -165,11 +161,8 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -165,11 +161,8 @@ WebInspector.TracingTimelineModel.prototype = {
stopRecording: function() stopRecording: function()
{ {
if (this._jsProfilerStarted) { this._stopCallbackBarrier = new CallbackBarrier();
this._stopCallbackBarrier = new CallbackBarrier(); this._stopProfilingOnAllTargets();
this._currentTarget.profilerAgent().stop(this._stopCallbackBarrier.createCallback(this._didStopRecordingJSSamples.bind(this)));
this._jsProfilerStarted = false;
}
this._tracingManager.stop(); this._tracingManager.stop();
}, },
...@@ -183,10 +176,34 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -183,10 +176,34 @@ WebInspector.TracingTimelineModel.prototype = {
this._onTracingComplete(); this._onTracingComplete();
}, },
_configureCpuProfilerSamplingInterval: function() _startCpuProfilingOnAllTargets: function()
{
this._profilingTargets = WebInspector.targetManager.targets();
for (var i = 0; i < this._profilingTargets.length; ++i) {
var target = this._profilingTargets[i];
this._configureCpuProfilerSamplingInterval(target);
target.profilerAgent().start();
}
},
_stopProfilingOnAllTargets: function()
{
if (!this._profilingTargets)
return;
for (var i = 0; i < this._profilingTargets.length; ++i) {
var target = this._profilingTargets[i];
target.profilerAgent().stop(this._stopCallbackBarrier.createCallback(this._didStopRecordingJSSamples.bind(this, target)));
}
this._profilingTargets = null;
},
/**
* @param {!WebInspector.Target} target
*/
_configureCpuProfilerSamplingInterval: function(target)
{ {
var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000; var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000;
this._currentTarget.profilerAgent().setSamplingInterval(intervalUs, didChangeInterval); target.profilerAgent().setSamplingInterval(intervalUs, didChangeInterval);
function didChangeInterval(error) function didChangeInterval(error)
{ {
...@@ -229,31 +246,30 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -229,31 +246,30 @@ WebInspector.TracingTimelineModel.prototype = {
_onTracingComplete: function() _onTracingComplete: function()
{ {
if (this._stopCallbackBarrier) if (this._stopCallbackBarrier) {
this._stopCallbackBarrier.callWhenDone(this._didStopRecordingTraceEvents.bind(this)); this._stopCallbackBarrier.callWhenDone(this._didStopRecordingTraceEvents.bind(this));
else this._stopCallbackBarrier = null;
} else {
this._didStopRecordingTraceEvents(); this._didStopRecordingTraceEvents();
}
}, },
/** /**
* @param {!WebInspector.Target} target
* @param {?Protocol.Error} error * @param {?Protocol.Error} error
* @param {?ProfilerAgent.CPUProfile} cpuProfile * @param {?ProfilerAgent.CPUProfile} cpuProfile
*/ */
_didStopRecordingJSSamples: function(error, cpuProfile) _didStopRecordingJSSamples: function(target, error, cpuProfile)
{ {
if (error) if (error)
WebInspector.console.error(error); WebInspector.console.error(error);
this._recordedCpuProfile = cpuProfile; if (!this._cpuProfiles)
this._cpuProfiles = {};
this._cpuProfiles[target.id()] = cpuProfile;
}, },
_didStopRecordingTraceEvents: function() _didStopRecordingTraceEvents: function()
{ {
this._stopCallbackBarrier = null;
if (this._recordedCpuProfile) {
this._injectCpuProfileEvent(this._recordedCpuProfile);
this._recordedCpuProfile = null;
}
this._tracingModel.tracingComplete(); this._tracingModel.tracingComplete();
var events = this._tracingModel.devtoolsPageMetadataEvents(); var events = this._tracingModel.devtoolsPageMetadataEvents();
...@@ -272,7 +288,7 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -272,7 +288,7 @@ WebInspector.TracingTimelineModel.prototype = {
var threads = process.sortedThreads(); var threads = process.sortedThreads();
for (var j = 0; j < threads.length; j++) { for (var j = 0; j < threads.length; j++) {
var thread = threads[j]; var thread = threads[j];
if (thread.name() === "WebCore: Worker" && !workerMetadataEvents.some(function(e) { return e.args["data"]["workerThreadId"] === thread.id(); })) if (thread.name() === "WebCore: Worker" && workerMetadataEvents.every(function(e) { return e.args["data"]["workerThreadId"] !== thread.id(); }))
continue; continue;
this._processThreadEvents(startTime, endTime, event.thread, thread); this._processThreadEvents(startTime, endTime, event.thread, thread);
} }
...@@ -281,10 +297,8 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -281,10 +297,8 @@ WebInspector.TracingTimelineModel.prototype = {
this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime); this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
if (this._cpuProfile) { this._cpuProfiles = null;
this._processCpuProfile(this._cpuProfile);
this._cpuProfile = null;
}
this._buildTimelineRecords(); this._buildTimelineRecords();
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped); this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
}, },
...@@ -309,19 +323,6 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -309,19 +323,6 @@ WebInspector.TracingTimelineModel.prototype = {
this._tracingModel.addEvents([cpuProfileEvent]); this._tracingModel.addEvents([cpuProfileEvent]);
}, },
/**
* @param {!ProfilerAgent.CPUProfile} cpuProfile
*/
_processCpuProfile: function(cpuProfile)
{
var jsSamples = WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(this, cpuProfile);
this._inspectedTargetEvents = this._inspectedTargetEvents.mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime);
this._setMainThreadEvents(this.mainThreadEvents().mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime));
var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(this.mainThreadEvents());
this._setMainThreadEvents(jsFrameEvents.mergeOrdered(this.mainThreadEvents(), WebInspector.TracingModel.Event.orderedCompareStartTime));
this._inspectedTargetEvents = jsFrameEvents.mergeOrdered(this._inspectedTargetEvents, WebInspector.TracingModel.Event.orderedCompareStartTime);
},
/** /**
* @return {number} * @return {number}
*/ */
...@@ -511,11 +512,12 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -511,11 +512,12 @@ WebInspector.TracingTimelineModel.prototype = {
var i = events.lowerBound(startTime, function (time, event) { return time - event.startTime }); var i = events.lowerBound(startTime, function (time, event) { return time - event.startTime });
var threadEvents; var threadEvents;
var virtualThread = null;
if (thread === mainThread) { if (thread === mainThread) {
threadEvents = this._mainThreadEvents; threadEvents = this._mainThreadEvents;
this._mainThreadAsyncEvents = this._mainThreadAsyncEvents.concat(thread.asyncEvents()); this._mainThreadAsyncEvents = this._mainThreadAsyncEvents.concat(thread.asyncEvents());
} else { } else {
var virtualThread = new WebInspector.TracingTimelineModel.VirtualThread(thread.name()); virtualThread = new WebInspector.TracingTimelineModel.VirtualThread(thread.name());
threadEvents = virtualThread.events; threadEvents = virtualThread.events;
virtualThread.asyncEvents = virtualThread.asyncEvents.concat(thread.asyncEvents()); virtualThread.asyncEvents = virtualThread.asyncEvents.concat(thread.asyncEvents());
this._virtualThreads.push(virtualThread); this._virtualThreads.push(virtualThread);
...@@ -530,6 +532,21 @@ WebInspector.TracingTimelineModel.prototype = { ...@@ -530,6 +532,21 @@ WebInspector.TracingTimelineModel.prototype = {
threadEvents.push(event); threadEvents.push(event);
this._inspectedTargetEvents.push(event); this._inspectedTargetEvents.push(event);
} }
if (this._cpuProfiles && thread.target()) {
var cpuProfile = this._cpuProfiles[thread.target().id()];
if (cpuProfile) {
var jsSamples = WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(cpuProfile, thread);
var mergedEvents = threadEvents.mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime);
var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(mergedEvents);
mergedEvents = jsFrameEvents.mergeOrdered(mergedEvents, WebInspector.TracingModel.Event.orderedCompareStartTime);
if (virtualThread)
virtualThread.events = mergedEvents;
else
this._mainThreadEvents = mergedEvents;
this._inspectedTargetEvents = this._inspectedTargetEvents.concat(jsSamples, jsFrameEvents);
}
}
}, },
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment