<!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
&lt;rdar://problem/24352431&gt;

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Currently console.profile/profileEnd behave slightly differently
between JSContext and Web inspection. Unifying will be part of:
&lt;https://webkit.org/b/158753&gt; 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 &quot;Profile (name)&quot; 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  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: console.profile should use the new Sampling Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=153499
+        &lt;rdar://problem/24352431&gt;
+
+        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  &lt;cdumez@apple.com&gt;
</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>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/protocol-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function triggerProgrammaticCapture(message) {
+    console.profile();
+    console.log(`Inside ${message} profile`);
+    console.profileEnd();
+}
+
+function test()
+{
+    let suite = ProtocolTest.createAsyncSuite(&quot;Timeline.setInstruments.programmatic-capture&quot;);
+
+    let heapExpected = false;
+    let programmaticCaptureStopped = null;
+
+    InspectorProtocol.eventHandler[&quot;Timeline.programmaticCaptureStarted&quot;] = () =&gt; {
+        ProtocolTest.pass(&quot;Timeline.programmaticCaptureStarted&quot;);
+    };
+    InspectorProtocol.eventHandler[&quot;Timeline.programmaticCaptureStopped&quot;] = () =&gt; {
+        ProtocolTest.pass(&quot;Timeline.programmaticCaptureStopped&quot;);
+        programmaticCaptureStopped();
+    };
+
+    InspectorProtocol.eventHandler[&quot;ScriptProfiler.trackingStart&quot;] = () =&gt; {
+        ProtocolTest.pass(&quot;ScriptProfiler.startTracking&quot;);
+    };
+
+    InspectorProtocol.eventHandler[&quot;Heap.trackingStart&quot;] = () =&gt; {
+        if (heapExpected)
+            ProtocolTest.pass(&quot;Heap.trackingStart&quot;);
+        else
+            ProtocolTest.fail(&quot;Unexpected Heap.trackingStart&quot;);
+    };
+
+    suite.addTestCase({
+        name: &quot;NoInstrumentsProgrammaticCapture&quot;,
+        test: (resolve, reject) =&gt; {
+            heapExpected = false;
+            programmaticCaptureStopped = resolve;
+
+            InspectorProtocol.sendCommand(&quot;Timeline.setInstruments&quot;, {instruments: []}, (messageObject) =&gt; {
+                ProtocolTest.expectThat(!messageObject.error, &quot;Should not be an error setting valid instruments.&quot;);
+            });
+            ProtocolTest.evaluateInPage(&quot;triggerProgrammaticCapture('NoInstrumentsProgrammaticCapture')&quot;);
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;MultipleInstrumentsProgrammaticCapture&quot;,
+        test: (resolve, reject) =&gt; {
+            heapExpected = true;
+            programmaticCaptureStopped = resolve;
+
+            InspectorProtocol.sendCommand(&quot;Timeline.setInstruments&quot;, {instruments: [&quot;ScriptProfiler&quot;, &quot;Heap&quot;]}, (messageObject) =&gt; {
+                ProtocolTest.expectThat(!messageObject.error, &quot;Should not be an error setting valid instruments.&quot;);
+            });
+            ProtocolTest.evaluateInPage(&quot;triggerProgrammaticCapture('MultipleInstrumentsProgrammaticCapture')&quot;);
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;NoInstrumentsProgrammaticCaptureAgain&quot;,
+        test: (resolve, reject) =&gt; {
+            heapExpected = true;
+            programmaticCaptureStopped = resolve;
+
+            InspectorProtocol.sendCommand(&quot;Timeline.setInstruments&quot;, {instruments: []}, (messageObject) =&gt; {
+                ProtocolTest.expectThat(!messageObject.error, &quot;Should not be an error setting valid instruments.&quot;);
+            });
+            ProtocolTest.evaluateInPage(&quot;triggerProgrammaticCapture('NoInstrumentsProgrammaticCaptureAgain')&quot;);
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;p&gt;Tests programmatic capture (console.profile/profileEnd) automatically starts instruments set via Timeline.setInstruments.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</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  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: console.profile should use the new Sampling Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=153499
+        &lt;rdar://problem/24352431&gt;
+
+        Reviewed by Timothy Hatcher.
+
+        Currently console.profile/profileEnd behave slightly differently
+        between JSContext and Web inspection. Unifying will be part of:
+        &lt;https://webkit.org/b/158753&gt; 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 &quot;Profile (name)&quot; 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  &lt;sbarati@apple.com&gt;
</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 &quot;ConsoleMessage.h&quot;
</span><span class="cx"> #include &quot;InspectorConsoleAgent.h&quot;
</span><ins>+#include &quot;InspectorDebuggerAgent.h&quot;
+#include &quot;InspectorScriptProfilerAgent.h&quot;
</ins><span class="cx"> #include &quot;ScriptArguments.h&quot;
</span><span class="cx"> #include &quot;ScriptCallStack.h&quot;
</span><span class="cx"> #include &quot;ScriptCallStackFactory.h&quot;
</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-&gt;count(exec, arguments);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSGlobalObjectConsoleClient::profile(JSC::ExecState*, const String&amp;)
</del><ins>+void JSGlobalObjectConsoleClient::profile(JSC::ExecState*, const String&amp; title)
</ins><span class="cx"> {
</span><del>-    // FIXME: support |console.profile| for JSContexts. &lt;https://webkit.org/b/136466&gt;
</del><ins>+    if (!m_consoleAgent-&gt;enabled())
+        return;
+
+    // Allow duplicate unnamed profiles. Disallow duplicate named profiles.
+    if (!title.isEmpty()) {
+        for (auto&amp; existingTitle : m_profiles) {
+            if (existingTitle == title) {
+                // FIXME: Send an enum to the frontend for localization?
+                String warning = title.isEmpty() ? ASCIILiteral(&quot;Unnamed Profile already exists&quot;) : makeString(&quot;Profile \&quot;&quot;, title, &quot;\&quot; already exists&quot;);
+                m_consoleAgent-&gt;addMessageToConsole(std::make_unique&lt;ConsoleMessage&gt;(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&amp;)
</del><ins>+void JSGlobalObjectConsoleClient::profileEnd(JSC::ExecState*, const String&amp; title)
</ins><span class="cx"> {
</span><del>-    // FIXME: support |console.profile| for JSContexts. &lt;https://webkit.org/b/136466&gt;
</del><ins>+    if (!m_consoleAgent-&gt;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 &gt;= 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(&quot;No profiles exist&quot;) : makeString(&quot;Profile \&quot;&quot;, title, &quot;\&quot; does not exist&quot;);
+    m_consoleAgent-&gt;addMessageToConsole(std::make_unique&lt;ConsoleMessage&gt;(MessageSource::ConsoleAPI, MessageType::ProfileEnd, MessageLevel::Warning, warning));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSGlobalObjectConsoleClient::startConsoleProfile()
+{
+    // FIXME: &lt;https://webkit.org/b/158753&gt; Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+    m_scriptProfilerAgent-&gt;programmaticCaptureStarted();
+
+    m_profileRestoreBreakpointActiveValue = m_debuggerAgent-&gt;breakpointsActive();
+
+    ErrorString unused;
+    m_debuggerAgent-&gt;setBreakpointsActive(unused, false);
+
+    const bool includeSamples = true;
+    m_scriptProfilerAgent-&gt;startTracking(unused, &amp;includeSamples);
+}
+
+void JSGlobalObjectConsoleClient::stopConsoleProfile()
+{
+    ErrorString unused;
+    m_scriptProfilerAgent-&gt;stopTracking(unused);
+
+    m_debuggerAgent-&gt;setBreakpointsActive(unused, m_profileRestoreBreakpointActiveValue);
+
+    // FIXME: &lt;https://webkit.org/b/158753&gt; Generalize the concept of Instruments on the backend to work equally for JSContext and Web inspection
+    m_scriptProfilerAgent-&gt;programmaticCaptureStopped();
+}
+
</ins><span class="cx"> void JSGlobalObjectConsoleClient::takeHeapSnapshot(JSC::ExecState*, const String&amp; title)
</span><span class="cx"> {
</span><span class="cx">     m_consoleAgent-&gt;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 &quot;ConsoleClient.h&quot;
</span><ins>+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
</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&amp; method);
</span><span class="cx">     void internalAddMessage(MessageType, MessageLevel, JSC::ExecState*, RefPtr&lt;ScriptArguments&gt;&amp;&amp;);
</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&lt;String&gt; 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&lt;InspectorHeapAgent&gt;(context);
</span><span class="cx">     auto consoleAgent = std::make_unique&lt;JSGlobalObjectConsoleAgent&gt;(context, heapAgent.get());
</span><span class="cx">     auto debuggerAgent = std::make_unique&lt;JSGlobalObjectDebuggerAgent&gt;(context, consoleAgent.get());
</span><ins>+    auto scriptProfilerAgent = std::make_unique&lt;InspectorScriptProfilerAgent&gt;(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&lt;JSGlobalObjectConsoleClient&gt;(m_consoleAgent);
</del><ins>+    m_consoleClient = std::make_unique&lt;JSGlobalObjectConsoleClient&gt;(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&lt;InspectorScriptProfilerAgent&gt;(context));
</del><ins>+    m_agents.append(WTFMove(scriptProfilerAgent));
</ins><span class="cx"> 
</span><span class="cx">     m_executionStopwatch-&gt;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&amp;, 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&amp;, const String&amp; callFrameId, const String&amp; expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr&lt;Inspector::Protocol::Runtime::RemoteObject&gt;&amp; result, Inspector::Protocol::OptOutput&lt;bool&gt;* wasThrown, Inspector::Protocol::OptOutput&lt;int&gt;* savedResultIndex) final;
</span><span class="cx">     void setOverlayMessage(ErrorString&amp;, 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-&gt;programmaticCaptureStarted();
+}
+
+void InspectorScriptProfilerAgent::programmaticCaptureStopped()
+{
+    m_frontendDispatcher-&gt;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&amp;, const bool* includeSamples) override;
</span><span class="cx">     void stopTracking(ErrorString&amp;) 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">             &quot;parameters&quot;: [
</span><span class="cx">                 { &quot;name&quot;: &quot;samples&quot;, &quot;$ref&quot;: &quot;Samples&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Stack traces.&quot; }
</span><span class="cx">             ]
</span><ins>+        },
+        {
+            &quot;name&quot;: &quot;programmaticCaptureStarted&quot;,
+            &quot;description&quot;: &quot;Fired when programmatic capture starts (console.profile). JSContext inspection only.&quot;
+        },
+        {
+            &quot;name&quot;: &quot;programmaticCaptureStopped&quot;,
+            &quot;description&quot;: &quot;Fired when programmatic capture stops (console.profileEnd). JSContext inspection only.&quot;
</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">             &quot;name&quot;: &quot;autoCaptureStarted&quot;,
</span><span class="cx">             &quot;description&quot;: &quot;Fired when auto capture started.&quot;
</span><ins>+        },
+        {
+            &quot;name&quot;: &quot;programmaticCaptureStarted&quot;,
+            &quot;description&quot;: &quot;Fired when programmatic capture starts (console.profile).&quot;
+        },
+        {
+            &quot;name&quot;: &quot;programmaticCaptureStopped&quot;,
+            &quot;description&quot;: &quot;Fired when programmatic capture stops (console.profileEnd).&quot;
</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  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: console.profile should use the new Sampling Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=153499
+        &lt;rdar://problem/24352431&gt;
+
+        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  &lt;akling@apple.com&gt;
</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 &quot;RenderView.h&quot;
</span><span class="cx"> #include &quot;ScriptState.h&quot;
</span><span class="cx"> #include &quot;TimelineRecordFactory.h&quot;
</span><ins>+#include &quot;WebConsoleAgent.h&quot;
+#include &lt;inspector/ConsoleMessage.h&gt;
</ins><span class="cx"> #include &lt;inspector/ScriptBreakpoint.h&gt;
</span><span class="cx"> #include &lt;inspector/agents/InspectorDebuggerAgent.h&gt;
</span><span class="cx"> #include &lt;inspector/agents/InspectorHeapAgent.h&gt;
</span><span class="lines">@@ -241,14 +243,55 @@
</span><span class="cx">     return m_environment.executionStopwatch()-&gt;elapsedTime();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorTimelineAgent::startFromConsole(JSC::ExecState*, const String&amp;)
</del><ins>+void InspectorTimelineAgent::startFromConsole(JSC::ExecState* exec, const String&amp; title)
</ins><span class="cx"> {
</span><del>-    // FIXME: &lt;https://webkit.org/b/153499&gt; 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&amp; record : m_pendingConsoleProfileRecords) {
+            String recordTitle;
+            record.data-&gt;getString(ASCIILiteral(&quot;title&quot;), recordTitle);
+            if (recordTitle == title) {
+                if (WebConsoleAgent* consoleAgent = m_instrumentingAgents.webConsoleAgent()) {
+                    // FIXME: Send an enum to the frontend for localization?
+                    String warning = title.isEmpty() ? ASCIILiteral(&quot;Unnamed Profile already exists&quot;) : makeString(&quot;Profile \&quot;&quot;, title, &quot;\&quot; already exists&quot;);
+                    consoleAgent-&gt;addMessageToConsole(std::make_unique&lt;ConsoleMessage&gt;(MessageSource::ConsoleAPI, MessageType::Profile, MessageLevel::Warning, warning));
+                }
+                return;
+            }
+        }
+    }
+
+    if (!m_enabled &amp;&amp; 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&amp;)
</del><ins>+void InspectorTimelineAgent::stopFromConsole(JSC::ExecState*, const String&amp; title)
</ins><span class="cx"> {
</span><del>-    // FIXME: &lt;https://webkit.org/b/153499&gt; 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 &gt;= 0; --i) {
+        const TimelineRecordEntry&amp; record = m_pendingConsoleProfileRecords[i];
+
+        String recordTitle;
+        record.data-&gt;getString(ASCIILiteral(&quot;title&quot;), recordTitle);
+        if (title.isEmpty() || recordTitle == title) {
+            didCompleteRecordEntry(record);
+            m_pendingConsoleProfileRecords.remove(i);
+
+            if (!m_enabledFromFrontend &amp;&amp; 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(&quot;No profiles exist&quot;) : makeString(&quot;Profile \&quot;&quot;, title, &quot;\&quot; does not exist&quot;);
+        consoleAgent-&gt;addMessageToConsole(std::make_unique&lt;ConsoleMessage&gt;(MessageSource::ConsoleAPI, MessageType::ProfileEnd, MessageLevel::Warning, warning));    
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorTimelineAgent::willCallFunction(const String&amp; 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-&gt;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-&gt;breakpointsActive();
+        if (m_programmaticCaptureRestoreBreakpointActiveValue) {
+            ErrorString unused;
+            debuggerAgent-&gt;setBreakpointsActive(unused, false);
+        }
+    } else
+        m_programmaticCaptureRestoreBreakpointActiveValue = false;
+
+    m_frontendDispatcher-&gt;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-&gt;setBreakpointsActive(unused, true);
+        }
+    }
+
+    m_frontendDispatcher-&gt;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-&gt;startTracking(unused, &amp;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-&gt;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-&gt;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-&gt;startTracking(unused, &amp;includeSamples);
+        } else
+            m_scriptProfilerAgent-&gt;stopTracking(unused);
+    }
+}
+
+void InspectorTimelineAgent::toggleHeapInstrument(InstrumentState state)
+{
+    if (m_heapAgent) {
+        ErrorString unused;
+        if (state == InstrumentState::Start)
+            m_heapAgent-&gt;startTracking(unused);
+        else
+            m_heapAgent-&gt;stopTracking(unused);
+    }
+}
+
+void InspectorTimelineAgent::toggleMemoryInstrument(InstrumentState state)
+{
+#if ENABLE(RESOURCE_USAGE)
+    if (InspectorMemoryAgent* memoryAgent = m_instrumentingAgents.inspectorMemoryAgent()) {
+        ErrorString unused;
+        if (state == InstrumentState::Start)
+            memoryAgent-&gt;startTracking(unused);
+        else
+            memoryAgent-&gt;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&amp;, const Inspector::ScriptBreakpointAction&amp;, 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&lt;TimelineRecordEntry&gt; m_recordStack;
</span><ins>+    Vector&lt;TimelineRecordEntry&gt; 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&lt;Inspector::Protocol::Timeline::Instrument&gt; 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  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: console.profile should use the new Sampling Profiler
+        https://bugs.webkit.org/show_bug.cgi?id=153499
+        &lt;rdar://problem/24352431&gt;
+
+        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  &lt;nvasilyev@apple.com&gt;
</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: &lt;https://webkit.org/b/158753&gt; 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: &lt;https://webkit.org/b/158753&gt; 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, &quot;Attempted to stop an already stopped session.&quot;);
</span><span class="cx">         console.assert(!this._readonly, &quot;Attempted to stop a readonly session.&quot;);
</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) =&gt; item.startTime &lt; endTime &amp;&amp; item.endTime &gt; 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) =&gt; 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>