<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[202234] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/202234">202234</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2016-06-20 12:12:42 -0700 (Mon, 20 Jun 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: console.profile should use the new Sampling Profiler
https://bugs.webkit.org/show_bug.cgi?id=153499
<rdar://problem/24352431>
Reviewed by Timothy Hatcher.
Source/JavaScriptCore:
Currently console.profile/profileEnd behave slightly differently
between JSContext and Web inspection. Unifying will be part of:
<https://webkit.org/b/158753> Generalize the concept of Instruments on the backend
Both JSContext and Web inspection keep track of active
profiles started and stopped via console.profile/profileEnd.
JSContext inspection sends its programmatic start/stop
via the ScriptProfiler domain.
Web inspection sends its programmatic start/stop
via the Timeline domain, and also will start/stop backend
list of Instruments.
The functional differences between these is that for JSContext
inspection, console.profile only starts/stops the ScriptProfiler
domain, and does not auto-start other instruments. This isn't really
a problem right now given the instruments available for JSContext
inspection; but it will be nice to unify as we add more instruments.
Also, JSContext inspection won't have "Profile (name)" records in
its Events view, since those are currently generated only by the
Web's Timeline domain.
* inspector/protocol/ScriptProfiler.json:
* inspector/protocol/Timeline.json:
Events to inform the frontend of programmatic start/stop.
* debugger/Debugger.h:
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::breakpointsActive):
(Inspector::InspectorDebuggerAgent::isPaused):
* inspector/agents/InspectorDebuggerAgent.h:
Expose breakpoints active state, since programmatic recording
will temporarily disabled breakpoints if needed.
* inspector/JSGlobalObjectConsoleClient.cpp:
(Inspector::JSGlobalObjectConsoleClient::JSGlobalObjectConsoleClient):
(Inspector::JSGlobalObjectConsoleClient::profile):
(Inspector::JSGlobalObjectConsoleClient::profileEnd):
(Inspector::JSGlobalObjectConsoleClient::startConsoleProfile):
(Inspector::JSGlobalObjectConsoleClient::stopConsoleProfile):
* inspector/JSGlobalObjectConsoleClient.h:
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
* inspector/agents/InspectorScriptProfilerAgent.cpp:
(Inspector::InspectorScriptProfilerAgent::programmaticCaptureStarted):
(Inspector::InspectorScriptProfilerAgent::programmaticCaptureStopped):
* inspector/agents/InspectorScriptProfilerAgent.h:
JSContext implementation of console.profile/profileEnd.
Source/WebCore:
Test: inspector/timeline/setInstruments-programmatic-capture.html
* inspector/InspectorTimelineAgent.cpp:
(WebCore::InspectorTimelineAgent::startFromConsole):
(WebCore::InspectorTimelineAgent::stopFromConsole):
(WebCore::InspectorTimelineAgent::mainFrameStartedLoading):
(WebCore::InspectorTimelineAgent::startProgrammaticCapture):
(WebCore::InspectorTimelineAgent::stopProgrammaticCapture):
(WebCore::InspectorTimelineAgent::toggleInstruments):
(WebCore::InspectorTimelineAgent::toggleScriptProfilerInstrument):
(WebCore::InspectorTimelineAgent::toggleHeapInstrument):
(WebCore::InspectorTimelineAgent::toggleMemoryInstrument):
(WebCore::InspectorTimelineAgent::toggleTimelineInstrument):
* inspector/InspectorTimelineAgent.h:
Web implementation of console.profile/profileEnd.
Make helpers for startings / stopping instruments.
Source/WebInspectorUI:
* UserInterface/Controllers/TimelineManager.js:
(WebInspector.TimelineManager.prototype.programmaticCaptureStarted):
(WebInspector.TimelineManager.prototype.programmaticCaptureStopped):
(WebInspector.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStarted):
(WebInspector.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStopped):
For programmatic captures, automatically show the Script Timeline, since
that is guarenteed to have been started by the backend. Start capturing
without creating a new recording.
* UserInterface/Models/TimelineRecording.js:
(WebInspector.TimelineRecording.prototype.stop):
(WebInspector.TimelineRecording.prototype.addScriptInstrumentForProgrammaticCapture):
When stopping for programmatic capture we don't need to disable
instruments, the backend would have already done this.
* UserInterface/Protocol/ScriptProfilerObserver.js:
(WebInspector.ScriptProfilerObserver.prototype.programmaticCaptureStarted):
(WebInspector.ScriptProfilerObserver.prototype.programmaticCaptureStopped):
(WebInspector.ScriptProfilerObserver):
* UserInterface/Protocol/TimelineObserver.js:
(WebInspector.TimelineObserver.prototype.programmaticCaptureStarted):
(WebInspector.TimelineObserver.prototype.programmaticCaptureStopped):
(WebInspector.TimelineObserver):
Pass through Web and JSContext programmatic capture events.
LayoutTests:
* inspector/timeline/setInstruments-programmatic-capture-expected.txt: Added.
* inspector/timeline/setInstruments-programmatic-capture.html: Added.
New test that the backend auto-starts instruments during programmatic capture.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacTestExpectations">trunk/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerh">trunk/Source/JavaScriptCore/debugger/Debugger.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectConsoleClientcpp">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectConsoleClienth">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolScriptProfilerjson">trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolTimelinejson">trunk/Source/JavaScriptCore/inspector/protocol/Timeline.json</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorTimelineAgentcpp">trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorTimelineAgenth">trunk/Source/WebCore/inspector/InspectorTimelineAgent.h</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsScriptInstrumentjs">trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordingjs">trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolScriptProfilerObserverjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolTimelineObserverjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectortimelinesetInstrumentsprogrammaticcaptureexpectedtxt">trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinesetInstrumentsprogrammaticcapturehtml">trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/LayoutTests/ChangeLog        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-06-20 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: console.profile should use the new Sampling Profiler
+ https://bugs.webkit.org/show_bug.cgi?id=153499
+ <rdar://problem/24352431>
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/timeline/setInstruments-programmatic-capture-expected.txt: Added.
+ * inspector/timeline/setInstruments-programmatic-capture.html: Added.
+ New test that the backend auto-starts instruments during programmatic capture.
+
</ins><span class="cx"> 2016-06-20 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><span class="cx"> Unreviewed, rebaseline test now that TouchEvent has a constructor.
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinesetInstrumentsprogrammaticcaptureexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture-expected.txt (0 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture-expected.txt         (rev 0)
+++ trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture-expected.txt        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+CONSOLE MESSAGE: line 8: Inside NoInstrumentsProgrammaticCapture profile
+CONSOLE MESSAGE: line 8: Inside MultipleInstrumentsProgrammaticCapture profile
+CONSOLE MESSAGE: line 8: Inside NoInstrumentsProgrammaticCaptureAgain profile
+Tests programmatic capture (console.profile/profileEnd) automatically starts instruments set via Timeline.setInstruments.
+
+
+== Running test suite: Timeline.setInstruments.programmatic-capture
+-- Running test case: NoInstrumentsProgrammaticCapture
+PASS: Should not be an error setting valid instruments.
+PASS: Timeline.programmaticCaptureStarted
+PASS: ScriptProfiler.startTracking
+PASS: Timeline.programmaticCaptureStopped
+
+-- Running test case: MultipleInstrumentsProgrammaticCapture
+PASS: Should not be an error setting valid instruments.
+PASS: Timeline.programmaticCaptureStarted
+PASS: ScriptProfiler.startTracking
+PASS: Heap.trackingStart
+PASS: Timeline.programmaticCaptureStopped
+
+-- Running test case: NoInstrumentsProgrammaticCaptureAgain
+PASS: Should not be an error setting valid instruments.
+PASS: Timeline.programmaticCaptureStarted
+PASS: ScriptProfiler.startTracking
+PASS: Timeline.programmaticCaptureStopped
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinesetInstrumentsprogrammaticcapturehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture.html (0 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture.html         (rev 0)
+++ trunk/LayoutTests/inspector/timeline/setInstruments-programmatic-capture.html        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
+<script>
+function triggerProgrammaticCapture(message) {
+ console.profile();
+ console.log(`Inside ${message} profile`);
+ console.profileEnd();
+}
+
+function test()
+{
+ let suite = ProtocolTest.createAsyncSuite("Timeline.setInstruments.programmatic-capture");
+
+ let heapExpected = false;
+ let programmaticCaptureStopped = null;
+
+ InspectorProtocol.eventHandler["Timeline.programmaticCaptureStarted"] = () => {
+ ProtocolTest.pass("Timeline.programmaticCaptureStarted");
+ };
+ InspectorProtocol.eventHandler["Timeline.programmaticCaptureStopped"] = () => {
+ ProtocolTest.pass("Timeline.programmaticCaptureStopped");
+ programmaticCaptureStopped();
+ };
+
+ InspectorProtocol.eventHandler["ScriptProfiler.trackingStart"] = () => {
+ ProtocolTest.pass("ScriptProfiler.startTracking");
+ };
+
+ InspectorProtocol.eventHandler["Heap.trackingStart"] = () => {
+ if (heapExpected)
+ ProtocolTest.pass("Heap.trackingStart");
+ else
+ ProtocolTest.fail("Unexpected Heap.trackingStart");
+ };
+
+ suite.addTestCase({
+ name: "NoInstrumentsProgrammaticCapture",
+ test: (resolve, reject) => {
+ heapExpected = false;
+ programmaticCaptureStopped = resolve;
+
+ InspectorProtocol.sendCommand("Timeline.setInstruments", {instruments: []}, (messageObject) => {
+ ProtocolTest.expectThat(!messageObject.error, "Should not be an error setting valid instruments.");
+ });
+ ProtocolTest.evaluateInPage("triggerProgrammaticCapture('NoInstrumentsProgrammaticCapture')");
+ }
+ });
+
+ suite.addTestCase({
+ name: "MultipleInstrumentsProgrammaticCapture",
+ test: (resolve, reject) => {
+ heapExpected = true;
+ programmaticCaptureStopped = resolve;
+
+ InspectorProtocol.sendCommand("Timeline.setInstruments", {instruments: ["ScriptProfiler", "Heap"]}, (messageObject) => {
+ ProtocolTest.expectThat(!messageObject.error, "Should not be an error setting valid instruments.");
+ });
+ ProtocolTest.evaluateInPage("triggerProgrammaticCapture('MultipleInstrumentsProgrammaticCapture')");
+ }
+ });
+
+ suite.addTestCase({
+ name: "NoInstrumentsProgrammaticCaptureAgain",
+ test: (resolve, reject) => {
+ heapExpected = true;
+ programmaticCaptureStopped = resolve;
+
+ InspectorProtocol.sendCommand("Timeline.setInstruments", {instruments: []}, (messageObject) => {
+ ProtocolTest.expectThat(!messageObject.error, "Should not be an error setting valid instruments.");
+ });
+ ProtocolTest.evaluateInPage("triggerProgrammaticCapture('NoInstrumentsProgrammaticCaptureAgain')");
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests programmatic capture (console.profile/profileEnd) automatically starts instruments set via Timeline.setInstruments.</p>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/TestExpectations (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/TestExpectations        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/LayoutTests/platform/mac/TestExpectations        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -1251,6 +1251,7 @@
</span><span class="cx"> webkit.org/b/156078 inspector/console/heapSnapshot.html [ Pass Timeout ]
</span><span class="cx"> webkit.org/b/158006 inspector/console/console-time.html [ Pass Timeout ]
</span><span class="cx"> webkit.org/b/156634 inspector/formatting/formatting-javascript.html [ Pass Timeout ]
</span><ins>+webkit.org/b/158948 inspector/timeline [ Pass Timeout ]
</ins><span class="cx">
</span><span class="cx"> # Colorspaces on CA OpenGL layers not available in Yosemite
</span><span class="cx"> [ Yosemite ] fast/canvas/webgl/match-page-color-space.html [ Skip ]
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -1,3 +1,61 @@
</span><ins>+2016-06-20 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: console.profile should use the new Sampling Profiler
+ https://bugs.webkit.org/show_bug.cgi?id=153499
+ <rdar://problem/24352431>
+
+ Reviewed by Timothy Hatcher.
+
+ Currently console.profile/profileEnd behave slightly differently
+ between JSContext and Web inspection. Unifying will be part of:
+ <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend
+
+ Both JSContext and Web inspection keep track of active
+ profiles started and stopped via console.profile/profileEnd.
+
+ JSContext inspection sends its programmatic start/stop
+ via the ScriptProfiler domain.
+
+ Web inspection sends its programmatic start/stop
+ via the Timeline domain, and also will start/stop backend
+ list of Instruments.
+
+ The functional differences between these is that for JSContext
+ inspection, console.profile only starts/stops the ScriptProfiler
+ domain, and does not auto-start other instruments. This isn't really
+ a problem right now given the instruments available for JSContext
+ inspection; but it will be nice to unify as we add more instruments.
+ Also, JSContext inspection won't have "Profile (name)" records in
+ its Events view, since those are currently generated only by the
+ Web's Timeline domain.
+
+ * inspector/protocol/ScriptProfiler.json:
+ * inspector/protocol/Timeline.json:
+ Events to inform the frontend of programmatic start/stop.
+
+ * debugger/Debugger.h:
+ * inspector/agents/InspectorDebuggerAgent.cpp:
+ (Inspector::InspectorDebuggerAgent::breakpointsActive):
+ (Inspector::InspectorDebuggerAgent::isPaused):
+ * inspector/agents/InspectorDebuggerAgent.h:
+ Expose breakpoints active state, since programmatic recording
+ will temporarily disabled breakpoints if needed.
+
+ * inspector/JSGlobalObjectConsoleClient.cpp:
+ (Inspector::JSGlobalObjectConsoleClient::JSGlobalObjectConsoleClient):
+ (Inspector::JSGlobalObjectConsoleClient::profile):
+ (Inspector::JSGlobalObjectConsoleClient::profileEnd):
+ (Inspector::JSGlobalObjectConsoleClient::startConsoleProfile):
+ (Inspector::JSGlobalObjectConsoleClient::stopConsoleProfile):
+ * inspector/JSGlobalObjectConsoleClient.h:
+ * inspector/JSGlobalObjectInspectorController.cpp:
+ (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+ * inspector/agents/InspectorScriptProfilerAgent.cpp:
+ (Inspector::InspectorScriptProfilerAgent::programmaticCaptureStarted):
+ (Inspector::InspectorScriptProfilerAgent::programmaticCaptureStopped):
+ * inspector/agents/InspectorScriptProfilerAgent.h:
+ JSContext implementation of console.profile/profileEnd.
+
</ins><span class="cx"> 2016-06-19 Saam Barati <sbarati@apple.com>
</span><span class="cx">
</span><span class="cx"> We should be able to generate more types of ICs inline
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/Debugger.h (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/Debugger.h        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/debugger/Debugger.h        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -78,6 +78,7 @@
</span><span class="cx"> void clearBreakpoints();
</span><span class="cx"> void activateBreakpoints() { setBreakpointsActivated(true); }
</span><span class="cx"> void deactivateBreakpoints() { setBreakpointsActivated(false); }
</span><ins>+ bool breakpointsActive() const { return m_breakpointsActivated; }
</ins><span class="cx">
</span><span class="cx"> enum PauseOnExceptionsState {
</span><span class="cx"> DontPauseOnExceptions,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectConsoleClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.cpp        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx">
</span><span class="cx"> #include "ConsoleMessage.h"
</span><span class="cx"> #include "InspectorConsoleAgent.h"
</span><ins>+#include "InspectorDebuggerAgent.h"
+#include "InspectorScriptProfilerAgent.h"
</ins><span class="cx"> #include "ScriptArguments.h"
</span><span class="cx"> #include "ScriptCallStack.h"
</span><span class="cx"> #include "ScriptCallStackFactory.h"
</span><span class="lines">@@ -52,9 +54,11 @@
</span><span class="cx"> sLogToSystemConsole = shouldLog;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-JSGlobalObjectConsoleClient::JSGlobalObjectConsoleClient(InspectorConsoleAgent* consoleAgent)
</del><ins>+JSGlobalObjectConsoleClient::JSGlobalObjectConsoleClient(InspectorConsoleAgent* consoleAgent, InspectorDebuggerAgent* debuggerAgent, InspectorScriptProfilerAgent* scriptProfilerAgent)
</ins><span class="cx"> : ConsoleClient()
</span><span class="cx"> , m_consoleAgent(consoleAgent)
</span><ins>+ , m_debuggerAgent(debuggerAgent)
+ , m_scriptProfilerAgent(scriptProfilerAgent)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -73,16 +77,73 @@
</span><span class="cx"> m_consoleAgent->count(exec, arguments);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void JSGlobalObjectConsoleClient::profile(JSC::ExecState*, const String&)
</del><ins>+void JSGlobalObjectConsoleClient::profile(JSC::ExecState*, const String& title)
</ins><span class="cx"> {
</span><del>- // FIXME: support |console.profile| for JSContexts. <https://webkit.org/b/136466>
</del><ins>+ if (!m_consoleAgent->enabled())
+ return;
+
+ // Allow duplicate unnamed profiles. Disallow duplicate named profiles.
+ if (!title.isEmpty()) {
+ for (auto& existingTitle : m_profiles) {
+ if (existingTitle == title) {
+ // FIXME: Send an enum to the frontend for localization?
+ String warning = title.isEmpty() ? ASCIILiteral("Unnamed Profile already exists") : makeString("Profile \"", title, "\" already exists");
+ m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Profile, MessageLevel::Warning, warning));
+ return;
+ }
+ }
+ }
+
+ m_profiles.append(title);
+ startConsoleProfile();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void JSGlobalObjectConsoleClient::profileEnd(JSC::ExecState*, const String&)
</del><ins>+void JSGlobalObjectConsoleClient::profileEnd(JSC::ExecState*, const String& title)
</ins><span class="cx"> {
</span><del>- // FIXME: support |console.profile| for JSContexts. <https://webkit.org/b/136466>
</del><ins>+ if (!m_consoleAgent->enabled())
+ return;
+
+ // Stop profiles in reverse order. If the title is empty, then stop the last profile.
+ // Otherwise, match the title of the profile to stop.
+ for (ptrdiff_t i = m_profiles.size() - 1; i >= 0; --i) {
+ if (title.isEmpty() || m_profiles[i] == title) {
+ m_profiles.remove(i);
+ if (m_profiles.isEmpty())
+ stopConsoleProfile();
+ return;
+ }
+ }
+
+ // FIXME: Send an enum to the frontend for localization?
+ String warning = title.isEmpty() ? ASCIILiteral("No profiles exist") : makeString("Profile \"", title, "\" does not exist");
+ m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::ProfileEnd, MessageLevel::Warning, warning));
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+void JSGlobalObjectConsoleClient::startConsoleProfile()
+{
+ // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+ m_scriptProfilerAgent->programmaticCaptureStarted();
+
+ m_profileRestoreBreakpointActiveValue = m_debuggerAgent->breakpointsActive();
+
+ ErrorString unused;
+ m_debuggerAgent->setBreakpointsActive(unused, false);
+
+ const bool includeSamples = true;
+ m_scriptProfilerAgent->startTracking(unused, &includeSamples);
+}
+
+void JSGlobalObjectConsoleClient::stopConsoleProfile()
+{
+ ErrorString unused;
+ m_scriptProfilerAgent->stopTracking(unused);
+
+ m_debuggerAgent->setBreakpointsActive(unused, m_profileRestoreBreakpointActiveValue);
+
+ // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+ m_scriptProfilerAgent->programmaticCaptureStopped();
+}
+
</ins><span class="cx"> void JSGlobalObjectConsoleClient::takeHeapSnapshot(JSC::ExecState*, const String& title)
</span><span class="cx"> {
</span><span class="cx"> m_consoleAgent->takeHeapSnapshot(title);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectConsoleClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -23,19 +23,22 @@
</span><span class="cx"> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><del>-#ifndef JSGlobalObjectConsoleClient_h
-#define JSGlobalObjectConsoleClient_h
</del><ins>+#pragma once
</ins><span class="cx">
</span><span class="cx"> #include "ConsoleClient.h"
</span><ins>+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
</ins><span class="cx">
</span><span class="cx"> namespace Inspector {
</span><span class="cx">
</span><span class="cx"> class InspectorConsoleAgent;
</span><ins>+class InspectorDebuggerAgent;
+class InspectorScriptProfilerAgent;
</ins><span class="cx">
</span><span class="cx"> class JSGlobalObjectConsoleClient final : public JSC::ConsoleClient {
</span><span class="cx"> WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>- explicit JSGlobalObjectConsoleClient(InspectorConsoleAgent*);
</del><ins>+ explicit JSGlobalObjectConsoleClient(InspectorConsoleAgent*, InspectorDebuggerAgent*, InspectorScriptProfilerAgent*);
</ins><span class="cx"> virtual ~JSGlobalObjectConsoleClient() { }
</span><span class="cx">
</span><span class="cx"> static bool logToSystemConsole();
</span><span class="lines">@@ -55,9 +58,14 @@
</span><span class="cx"> void warnUnimplemented(const String& method);
</span><span class="cx"> void internalAddMessage(MessageType, MessageLevel, JSC::ExecState*, RefPtr<ScriptArguments>&&);
</span><span class="cx">
</span><ins>+ void startConsoleProfile();
+ void stopConsoleProfile();
+
</ins><span class="cx"> InspectorConsoleAgent* m_consoleAgent;
</span><ins>+ InspectorDebuggerAgent* m_debuggerAgent;
+ InspectorScriptProfilerAgent* m_scriptProfilerAgent;
+ Vector<String> m_profiles;
+ bool m_profileRestoreBreakpointActiveValue { false };
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> }
</span><del>-
-#endif // !defined(JSGlobalObjectConsoleClient_h)
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -88,11 +88,12 @@
</span><span class="cx"> auto heapAgent = std::make_unique<InspectorHeapAgent>(context);
</span><span class="cx"> auto consoleAgent = std::make_unique<JSGlobalObjectConsoleAgent>(context, heapAgent.get());
</span><span class="cx"> auto debuggerAgent = std::make_unique<JSGlobalObjectDebuggerAgent>(context, consoleAgent.get());
</span><ins>+ auto scriptProfilerAgent = std::make_unique<InspectorScriptProfilerAgent>(context);
</ins><span class="cx">
</span><span class="cx"> m_inspectorAgent = inspectorAgent.get();
</span><span class="cx"> m_debuggerAgent = debuggerAgent.get();
</span><span class="cx"> m_consoleAgent = consoleAgent.get();
</span><del>- m_consoleClient = std::make_unique<JSGlobalObjectConsoleClient>(m_consoleAgent);
</del><ins>+ m_consoleClient = std::make_unique<JSGlobalObjectConsoleClient>(m_consoleAgent, m_debuggerAgent, scriptProfilerAgent.get());
</ins><span class="cx">
</span><span class="cx"> m_agents.append(WTFMove(inspectorAgent));
</span><span class="cx"> m_agents.append(WTFMove(runtimeAgent));
</span><span class="lines">@@ -99,7 +100,7 @@
</span><span class="cx"> m_agents.append(WTFMove(consoleAgent));
</span><span class="cx"> m_agents.append(WTFMove(debuggerAgent));
</span><span class="cx"> m_agents.append(WTFMove(heapAgent));
</span><del>- m_agents.append(std::make_unique<InspectorScriptProfilerAgent>(context));
</del><ins>+ m_agents.append(WTFMove(scriptProfilerAgent));
</ins><span class="cx">
</span><span class="cx"> m_executionStopwatch->start();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -125,6 +125,11 @@
</span><span class="cx"> disable(false);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool InspectorDebuggerAgent::breakpointsActive() const
+{
+ return m_scriptDebugServer.breakpointsActive();
+}
+
</ins><span class="cx"> void InspectorDebuggerAgent::setBreakpointsActive(ErrorString&, bool active)
</span><span class="cx"> {
</span><span class="cx"> if (active)
</span><span class="lines">@@ -133,7 +138,7 @@
</span><span class="cx"> m_scriptDebugServer.deactivateBreakpoints();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool InspectorDebuggerAgent::isPaused()
</del><ins>+bool InspectorDebuggerAgent::isPaused() const
</ins><span class="cx"> {
</span><span class="cx"> return m_scriptDebugServer.isPaused();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -83,7 +83,8 @@
</span><span class="cx"> void evaluateOnCallFrame(ErrorString&, const String& callFrameId, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex) final;
</span><span class="cx"> void setOverlayMessage(ErrorString&, const String*) override;
</span><span class="cx">
</span><del>- bool isPaused();
</del><ins>+ bool isPaused() const;
+ bool breakpointsActive() const;
</ins><span class="cx">
</span><span class="cx"> void setSuppressAllPauses(bool);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -216,4 +216,14 @@
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void InspectorScriptProfilerAgent::programmaticCaptureStarted()
+{
+ m_frontendDispatcher->programmaticCaptureStarted();
+}
+
+void InspectorScriptProfilerAgent::programmaticCaptureStopped()
+{
+ m_frontendDispatcher->programmaticCaptureStopped();
+}
+
</ins><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -53,6 +53,9 @@
</span><span class="cx"> void startTracking(ErrorString&, const bool* includeSamples) override;
</span><span class="cx"> void stopTracking(ErrorString&) override;
</span><span class="cx">
</span><ins>+ void programmaticCaptureStarted();
+ void programmaticCaptureStopped();
+
</ins><span class="cx"> // Debugger::ProfilingClient
</span><span class="cx"> bool isAlreadyProfiling() const override;
</span><span class="cx"> double willEvaluateScript() override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolScriptProfilerjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -86,6 +86,14 @@
</span><span class="cx"> "parameters": [
</span><span class="cx"> { "name": "samples", "$ref": "Samples", "optional": true, "description": "Stack traces." }
</span><span class="cx"> ]
</span><ins>+ },
+ {
+ "name": "programmaticCaptureStarted",
+ "description": "Fired when programmatic capture starts (console.profile). JSContext inspection only."
+ },
+ {
+ "name": "programmaticCaptureStopped",
+ "description": "Fired when programmatic capture stops (console.profileEnd). JSContext inspection only."
</ins><span class="cx"> }
</span><span class="cx"> ]
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolTimelinejson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/Timeline.json (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Timeline.json        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Timeline.json        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -105,6 +105,14 @@
</span><span class="cx"> {
</span><span class="cx"> "name": "autoCaptureStarted",
</span><span class="cx"> "description": "Fired when auto capture started."
</span><ins>+ },
+ {
+ "name": "programmaticCaptureStarted",
+ "description": "Fired when programmatic capture starts (console.profile)."
+ },
+ {
+ "name": "programmaticCaptureStopped",
+ "description": "Fired when programmatic capture stops (console.profileEnd)."
</ins><span class="cx"> }
</span><span class="cx"> ]
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebCore/ChangeLog        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2016-06-20 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: console.profile should use the new Sampling Profiler
+ https://bugs.webkit.org/show_bug.cgi?id=153499
+ <rdar://problem/24352431>
+
+ Reviewed by Timothy Hatcher.
+
+ Test: inspector/timeline/setInstruments-programmatic-capture.html
+
+ * inspector/InspectorTimelineAgent.cpp:
+ (WebCore::InspectorTimelineAgent::startFromConsole):
+ (WebCore::InspectorTimelineAgent::stopFromConsole):
+ (WebCore::InspectorTimelineAgent::mainFrameStartedLoading):
+ (WebCore::InspectorTimelineAgent::startProgrammaticCapture):
+ (WebCore::InspectorTimelineAgent::stopProgrammaticCapture):
+ (WebCore::InspectorTimelineAgent::toggleInstruments):
+ (WebCore::InspectorTimelineAgent::toggleScriptProfilerInstrument):
+ (WebCore::InspectorTimelineAgent::toggleHeapInstrument):
+ (WebCore::InspectorTimelineAgent::toggleMemoryInstrument):
+ (WebCore::InspectorTimelineAgent::toggleTimelineInstrument):
+ * inspector/InspectorTimelineAgent.h:
+ Web implementation of console.profile/profileEnd.
+ Make helpers for startings / stopping instruments.
+
</ins><span class="cx"> 2016-06-20 Andreas Kling <akling@apple.com>
</span><span class="cx">
</span><span class="cx"> When navigating, discard decoded image data that is only live due to page cache.
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -43,6 +43,8 @@
</span><span class="cx"> #include "RenderView.h"
</span><span class="cx"> #include "ScriptState.h"
</span><span class="cx"> #include "TimelineRecordFactory.h"
</span><ins>+#include "WebConsoleAgent.h"
+#include <inspector/ConsoleMessage.h>
</ins><span class="cx"> #include <inspector/ScriptBreakpoint.h>
</span><span class="cx"> #include <inspector/agents/InspectorDebuggerAgent.h>
</span><span class="cx"> #include <inspector/agents/InspectorHeapAgent.h>
</span><span class="lines">@@ -241,14 +243,55 @@
</span><span class="cx"> return m_environment.executionStopwatch()->elapsedTime();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void InspectorTimelineAgent::startFromConsole(JSC::ExecState*, const String&)
</del><ins>+void InspectorTimelineAgent::startFromConsole(JSC::ExecState* exec, const String& title)
</ins><span class="cx"> {
</span><del>- // FIXME: <https://webkit.org/b/153499> Web Inspector: console.profile should use the new Sampling Profiler
</del><ins>+ // Allow duplicate unnamed profiles. Disallow duplicate named profiles.
+ if (!title.isEmpty()) {
+ for (const TimelineRecordEntry& record : m_pendingConsoleProfileRecords) {
+ String recordTitle;
+ record.data->getString(ASCIILiteral("title"), recordTitle);
+ if (recordTitle == title) {
+ if (WebConsoleAgent* consoleAgent = m_instrumentingAgents.webConsoleAgent()) {
+ // FIXME: Send an enum to the frontend for localization?
+ String warning = title.isEmpty() ? ASCIILiteral("Unnamed Profile already exists") : makeString("Profile \"", title, "\" already exists");
+ consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Profile, MessageLevel::Warning, warning));
+ }
+ return;
+ }
+ }
+ }
+
+ if (!m_enabled && m_pendingConsoleProfileRecords.isEmpty())
+ startProgrammaticCapture();
+
+ m_pendingConsoleProfileRecords.append(createRecordEntry(TimelineRecordFactory::createConsoleProfileData(title), TimelineRecordType::ConsoleProfile, true, frameFromExecState(exec)));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void InspectorTimelineAgent::stopFromConsole(JSC::ExecState*, const String&)
</del><ins>+void InspectorTimelineAgent::stopFromConsole(JSC::ExecState*, const String& title)
</ins><span class="cx"> {
</span><del>- // FIXME: <https://webkit.org/b/153499> Web Inspector: console.profile should use the new Sampling Profiler
</del><ins>+ // Stop profiles in reverse order. If the title is empty, then stop the last profile.
+ // Otherwise, match the title of the profile to stop.
+ for (int i = m_pendingConsoleProfileRecords.size() - 1; i >= 0; --i) {
+ const TimelineRecordEntry& record = m_pendingConsoleProfileRecords[i];
+
+ String recordTitle;
+ record.data->getString(ASCIILiteral("title"), recordTitle);
+ if (title.isEmpty() || recordTitle == title) {
+ didCompleteRecordEntry(record);
+ m_pendingConsoleProfileRecords.remove(i);
+
+ if (!m_enabledFromFrontend && m_pendingConsoleProfileRecords.isEmpty())
+ stopProgrammaticCapture();
+
+ return;
+ }
+ }
+
+ if (WebConsoleAgent* consoleAgent = m_instrumentingAgents.webConsoleAgent()) {
+ // FIXME: Send an enum to the frontend for localization?
+ String warning = title.isEmpty() ? ASCIILiteral("No profiles exist") : makeString("Profile \"", title, "\" does not exist");
+ consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::ProfileEnd, MessageLevel::Warning, warning));
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine, Frame* frame)
</span><span class="lines">@@ -405,40 +448,119 @@
</span><span class="cx"> // Inform the frontend we started an auto capture. The frontend must stop capture.
</span><span class="cx"> m_frontendDispatcher->autoCaptureStarted();
</span><span class="cx">
</span><del>- // Enable instruments.
</del><ins>+ toggleInstruments(InstrumentState::Start);
+}
+
+void InspectorTimelineAgent::startProgrammaticCapture()
+{
+ ASSERT(!m_enabled);
+
+ // Disable breakpoints during programmatic capture.
+ if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) {
+ m_programmaticCaptureRestoreBreakpointActiveValue = debuggerAgent->breakpointsActive();
+ if (m_programmaticCaptureRestoreBreakpointActiveValue) {
+ ErrorString unused;
+ debuggerAgent->setBreakpointsActive(unused, false);
+ }
+ } else
+ m_programmaticCaptureRestoreBreakpointActiveValue = false;
+
+ m_frontendDispatcher->programmaticCaptureStarted();
+
+ toggleScriptProfilerInstrument(InstrumentState::Start); // Ensure JavaScript samping data.
+ toggleTimelineInstrument(InstrumentState::Start); // Ensure Console Profile event records.
+ toggleInstruments(InstrumentState::Start); // Any other instruments the frontend wants us to record.
+}
+
+void InspectorTimelineAgent::stopProgrammaticCapture()
+{
+ ASSERT(m_enabled);
+ ASSERT(!m_enabledFromFrontend);
+
+ toggleInstruments(InstrumentState::Stop);
+ toggleTimelineInstrument(InstrumentState::Stop);
+ toggleScriptProfilerInstrument(InstrumentState::Stop);
+
+ // Re-enable breakpoints if they were enabled.
+ if (m_programmaticCaptureRestoreBreakpointActiveValue) {
+ if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) {
+ ErrorString unused;
+ debuggerAgent->setBreakpointsActive(unused, true);
+ }
+ }
+
+ m_frontendDispatcher->programmaticCaptureStopped();
+}
+
+void InspectorTimelineAgent::toggleInstruments(InstrumentState state)
+{
</ins><span class="cx"> for (auto instrumentType : m_instruments) {
</span><span class="cx"> switch (instrumentType) {
</span><span class="cx"> case Inspector::Protocol::Timeline::Instrument::ScriptProfiler: {
</span><del>- if (m_scriptProfilerAgent) {
- ErrorString unused;
- const bool includeSamples = true;
- m_scriptProfilerAgent->startTracking(unused, &includeSamples);
- }
</del><ins>+ toggleScriptProfilerInstrument(state);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case Inspector::Protocol::Timeline::Instrument::Heap: {
</span><del>- if (m_heapAgent) {
- ErrorString unused;
- m_heapAgent->startTracking(unused);
- }
</del><ins>+ toggleHeapInstrument(state);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case Inspector::Protocol::Timeline::Instrument::Memory: {
</span><del>-#if ENABLE(RESOURCE_USAGE)
- if (InspectorMemoryAgent* memoryAgent = m_instrumentingAgents.inspectorMemoryAgent()) {
- ErrorString unused;
- memoryAgent->startTracking(unused);
- }
-#endif
</del><ins>+ toggleMemoryInstrument(state);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case Inspector::Protocol::Timeline::Instrument::Timeline:
</span><del>- internalStart();
</del><ins>+ toggleTimelineInstrument(state);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void InspectorTimelineAgent::toggleScriptProfilerInstrument(InstrumentState state)
+{
+ if (m_scriptProfilerAgent) {
+ ErrorString unused;
+ if (state == InstrumentState::Start) {
+ const bool includeSamples = true;
+ m_scriptProfilerAgent->startTracking(unused, &includeSamples);
+ } else
+ m_scriptProfilerAgent->stopTracking(unused);
+ }
+}
+
+void InspectorTimelineAgent::toggleHeapInstrument(InstrumentState state)
+{
+ if (m_heapAgent) {
+ ErrorString unused;
+ if (state == InstrumentState::Start)
+ m_heapAgent->startTracking(unused);
+ else
+ m_heapAgent->stopTracking(unused);
+ }
+}
+
+void InspectorTimelineAgent::toggleMemoryInstrument(InstrumentState state)
+{
+#if ENABLE(RESOURCE_USAGE)
+ if (InspectorMemoryAgent* memoryAgent = m_instrumentingAgents.inspectorMemoryAgent()) {
+ ErrorString unused;
+ if (state == InstrumentState::Start)
+ memoryAgent->startTracking(unused);
+ else
+ memoryAgent->stopTracking(unused);
+ }
+#else
+ UNUSED_PARAM(state);
+#endif
+}
+
+void InspectorTimelineAgent::toggleTimelineInstrument(InstrumentState state)
+{
+ if (state == InstrumentState::Start)
+ internalStart();
+ else
+ internalStop();
+}
+
</ins><span class="cx"> void InspectorTimelineAgent::didCommitLoad()
</span><span class="cx"> {
</span><span class="cx"> clearRecordStack();
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -153,6 +153,18 @@
</span><span class="cx"> void breakpointActionSound(int) final { }
</span><span class="cx"> void breakpointActionProbe(JSC::ExecState&, const Inspector::ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, JSC::JSValue result) final;
</span><span class="cx">
</span><ins>+ void startProgrammaticCapture();
+ void stopProgrammaticCapture();
+
+ enum class InstrumentState { Start, Stop };
+ void toggleInstruments(InstrumentState);
+ void toggleScriptProfilerInstrument(InstrumentState);
+ void toggleHeapInstrument(InstrumentState);
+ void toggleMemoryInstrument(InstrumentState);
+ void toggleTimelineInstrument(InstrumentState);
+ void disableBreakpoints();
+ void enableBreakpoints();
+
</ins><span class="cx"> friend class TimelineRecordStack;
</span><span class="cx">
</span><span class="cx"> struct TimelineRecordEntry {
</span><span class="lines">@@ -200,6 +212,7 @@
</span><span class="cx"> InspectorPageAgent* m_pageAgent;
</span><span class="cx">
</span><span class="cx"> Vector<TimelineRecordEntry> m_recordStack;
</span><ins>+ Vector<TimelineRecordEntry> m_pendingConsoleProfileRecords;
</ins><span class="cx">
</span><span class="cx"> int m_id { 1 };
</span><span class="cx"> int m_maxCallStackDepth { 5 };
</span><span class="lines">@@ -206,6 +219,7 @@
</span><span class="cx">
</span><span class="cx"> bool m_enabled { false };
</span><span class="cx"> bool m_enabledFromFrontend { false };
</span><ins>+ bool m_programmaticCaptureRestoreBreakpointActiveValue { false };
</ins><span class="cx">
</span><span class="cx"> bool m_autoCaptureEnabled { false };
</span><span class="cx"> Vector<Inspector::Protocol::Timeline::Instrument> m_instruments;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2016-06-20 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: console.profile should use the new Sampling Profiler
+ https://bugs.webkit.org/show_bug.cgi?id=153499
+ <rdar://problem/24352431>
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Controllers/TimelineManager.js:
+ (WebInspector.TimelineManager.prototype.programmaticCaptureStarted):
+ (WebInspector.TimelineManager.prototype.programmaticCaptureStopped):
+ (WebInspector.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStarted):
+ (WebInspector.TimelineManager.prototype.scriptProfilerProgrammaticCaptureStopped):
+ For programmatic captures, automatically show the Script Timeline, since
+ that is guarenteed to have been started by the backend. Start capturing
+ without creating a new recording.
+
+ * UserInterface/Models/TimelineRecording.js:
+ (WebInspector.TimelineRecording.prototype.stop):
+ (WebInspector.TimelineRecording.prototype.addScriptInstrumentForProgrammaticCapture):
+ When stopping for programmatic capture we don't need to disable
+ instruments, the backend would have already done this.
+
+ * UserInterface/Protocol/ScriptProfilerObserver.js:
+ (WebInspector.ScriptProfilerObserver.prototype.programmaticCaptureStarted):
+ (WebInspector.ScriptProfilerObserver.prototype.programmaticCaptureStopped):
+ (WebInspector.ScriptProfilerObserver):
+ * UserInterface/Protocol/TimelineObserver.js:
+ (WebInspector.TimelineObserver.prototype.programmaticCaptureStarted):
+ (WebInspector.TimelineObserver.prototype.programmaticCaptureStopped):
+ (WebInspector.TimelineObserver):
+ Pass through Web and JSContext programmatic capture events.
+
</ins><span class="cx"> 2016-06-19 Nikita Vasilyev <nvasilyev@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Remove Sidebar z-index:0 workaround for scrollbars and position:sticky section headers
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -262,7 +262,7 @@
</span><span class="cx"> this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingStopped, {endTime});
</span><span class="cx"> }
</span><span class="cx">
</span><del>- autoCaptureStarted(startTime)
</del><ins>+ autoCaptureStarted()
</ins><span class="cx"> {
</span><span class="cx"> // Called from WebInspector.TimelineObserver.
</span><span class="cx">
</span><span class="lines">@@ -272,12 +272,36 @@
</span><span class="cx"> // We may already have an fresh TimelineRecording created if autoCaptureStarted is received
</span><span class="cx"> // between sending the Timeline.start command and receiving Timeline.capturingStarted event.
</span><span class="cx"> // In that case, there is no need to call startCapturing again. Reuse the fresh recording.
</span><del>- if (!this._waitingForCapturingStartedEvent)
- this.startCapturing(true);
</del><ins>+ if (!this._waitingForCapturingStartedEvent) {
+ const createNewRecording = true;
+ this.startCapturing(createNewRecording);
+ }
</ins><span class="cx">
</span><span class="cx"> this._shouldSetAutoCapturingMainResource = true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ programmaticCaptureStarted()
+ {
+ // Called from WebInspector.TimelineObserver.
+
+ this._activeRecording.addScriptInstrumentForProgrammaticCapture();
+
+ const createNewRecording = false;
+ this.startCapturing(createNewRecording);
+ }
+
+ programmaticCaptureStopped()
+ {
+ // Called from WebInspector.TimelineObserver.
+
+ // FIXME: This is purely to avoid a noisy assert. Previously
+ // it was impossible to stop without stopping from the UI.
+ console.assert(!this._isCapturing);
+ this._isCapturing = true;
+
+ this.stopCapturing();
+ }
+
</ins><span class="cx"> eventRecorded(recordPayload)
</span><span class="cx"> {
</span><span class="cx"> // Called from WebInspector.TimelineObserver.
</span><span class="lines">@@ -485,7 +509,8 @@
</span><span class="cx">
</span><span class="cx"> case TimelineAgent.EventType.ConsoleProfile:
</span><span class="cx"> var profileData = recordPayload.data.profile;
</span><del>- console.assert(profileData);
</del><ins>+ // COMPATIBILITY (iOS 9): With the Sampling Profiler, profiles no longer include legacy profile data.
+ console.assert(profileData || TimelineAgent.setInstruments);
</ins><span class="cx"> return new WebInspector.ScriptTimelineRecord(WebInspector.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData);
</span><span class="cx">
</span><span class="cx"> case TimelineAgent.EventType.TimerFire:
</span><span class="lines">@@ -834,6 +859,24 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ scriptProfilerProgrammaticCaptureStarted()
+ {
+ // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+ console.assert(WebInspector.debuggableType === WebInspector.DebuggableType.JavaScript);
+ console.assert(!this._isCapturing);
+
+ this.programmaticCaptureStarted();
+ }
+
+ scriptProfilerProgrammaticCaptureStopped()
+ {
+ // FIXME: <https://webkit.org/b/158753> Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+ console.assert(WebInspector.debuggableType === WebInspector.DebuggableType.JavaScript);
+ console.assert(this._isCapturing);
+
+ this.programmaticCaptureStopped();
+ }
+
</ins><span class="cx"> scriptProfilerTrackingStarted(timestamp)
</span><span class="cx"> {
</span><span class="cx"> this._scriptProfilerRecords = [];
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScriptInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -56,5 +56,4 @@
</span><span class="cx">
</span><span class="cx"> ScriptProfilerAgent.stopTracking();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordingjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -127,7 +127,7 @@
</span><span class="cx"> instrument.startInstrumentation();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- stop()
</del><ins>+ stop(programmatic)
</ins><span class="cx"> {
</span><span class="cx"> console.assert(this._capturing, "Attempted to stop an already stopped session.");
</span><span class="cx"> console.assert(!this._readonly, "Attempted to stop a readonly session.");
</span><span class="lines">@@ -134,8 +134,10 @@
</span><span class="cx">
</span><span class="cx"> this._capturing = false;
</span><span class="cx">
</span><del>- for (let instrument of this._instruments)
- instrument.stopInstrumentation();
</del><ins>+ if (!programmatic) {
+ for (let instrument of this._instruments)
+ instrument.stopInstrumentation();
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> saveIdentityToCookie()
</span><span class="lines">@@ -307,6 +309,19 @@
</span><span class="cx"> return this._discontinuities.filter((item) => item.startTime < endTime && item.endTime > startTime);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ addScriptInstrumentForProgrammaticCapture()
+ {
+ for (let instrument of this._instruments) {
+ if (instrument instanceof WebInspector.ScriptInstrument)
+ return;
+ }
+
+ this.addInstrument(new WebInspector.ScriptInstrument);
+
+ let instrumentTypes = this._instruments.map((instrument) => instrument.timelineRecordType);
+ WebInspector.timelineManager.enabledTimelineTypes = instrumentTypes;
+ }
+
</ins><span class="cx"> computeElapsedTime(timestamp)
</span><span class="cx"> {
</span><span class="cx"> if (!timestamp || isNaN(timestamp))
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolScriptProfilerObserverjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -41,4 +41,14 @@
</span><span class="cx"> {
</span><span class="cx"> WebInspector.timelineManager.scriptProfilerTrackingCompleted(samples);
</span><span class="cx"> }
</span><ins>+
+ programmaticCaptureStarted()
+ {
+ WebInspector.timelineManager.scriptProfilerProgrammaticCaptureStarted();
+ }
+
+ programmaticCaptureStopped()
+ {
+ WebInspector.timelineManager.scriptProfilerProgrammaticCaptureStopped();
+ }
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolTimelineObserverjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js (202233 => 202234)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js        2016-06-20 19:10:00 UTC (rev 202233)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/TimelineObserver.js        2016-06-20 19:12:42 UTC (rev 202234)
</span><span class="lines">@@ -46,4 +46,14 @@
</span><span class="cx"> {
</span><span class="cx"> WebInspector.timelineManager.autoCaptureStarted();
</span><span class="cx"> }
</span><ins>+
+ programmaticCaptureStarted()
+ {
+ WebInspector.timelineManager.programmaticCaptureStarted();
+ }
+
+ programmaticCaptureStopped()
+ {
+ WebInspector.timelineManager.programmaticCaptureStopped();
+ }
</ins><span class="cx"> };
</span></span></pre>
</div>
</div>
</body>
</html>