<!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>[202384] trunk/Source</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/202384">202384</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2016-06-23 11:52:59 -0700 (Thu, 23 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: first heap snapshot taken when a page is reloaded happens before the reload navigation
https://bugs.webkit.org/show_bug.cgi?id=158995
&lt;rdar://problem/26923778&gt;

Reviewed by Brian Burg.

Source/WebCore:

When the &quot;Heap&quot; instrument is included in the Timeline list
of instruments, defer starting it in an auto-capture scenario
until after the page does its first navigation.

AutoCapture on the backend happens when it is enabled at
the main resource starts loading. In that case it proceeds
through the following phases:

    No Auto Capture:
        None

    Auto Capture:
        BeforeLoad -&gt; FirstNavigation -&gt; AfterFirstNavigation

When toggling instruments for backend initiated capture
most instruments do not care and will just start/stop.

* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didCommitLoadImpl):
Inform the TimelineAgent that the main frame navigated.
Do this after informing the HeapAgent (so any potential
snapshot does not get cleared) and PageAgent (so the
frontend knows the page navigated before the agent starts).

* inspector/InspectorTimelineAgent.h:
* inspector/InspectorTimelineAgent.cpp:
(WebCore::InspectorTimelineAgent::internalStop):
(WebCore::InspectorTimelineAgent::mainFrameStartedLoading):
(WebCore::InspectorTimelineAgent::mainFrameNavigated):
Update the auto capture phase transitions.

(WebCore::InspectorTimelineAgent::toggleHeapInstrument):
Only start the heap agent during the None phase (console.profile)
or with the first navigation (auto capture page navigation).

Source/WebInspectorUI:

Let instruments decide to do work or not based on programmatic
(backend initiated) starts and stop.

Programmatic start can happen due to Auto Capture or console.profile.
Programmatic stop can happen due to console.profileEnd.

For example, this allows the frontend to avoid sending agents start/stop
messages when the backend would have already started/stopped the agents.

* UserInterface/Controllers/TimelineManager.js:
(WebInspector.TimelineManager):
(WebInspector.TimelineManager.prototype.startCapturing):
(WebInspector.TimelineManager.prototype.capturingStopped):
(WebInspector.TimelineManager.prototype.autoCaptureStarted):
(WebInspector.TimelineManager.prototype.programmaticCaptureStarted):
Call Recording.start/stop with a programmatic flag so the frontend
instruments can perform a more informed start/stop.

* UserInterface/Models/TimelineRecording.js:
(WebInspector.TimelineRecording.prototype.start):
(WebInspector.TimelineRecording.prototype.stop):
Let the instruments decide to do work based on the start/stop
being initiated by the backend or not.

* UserInterface/Models/HeapAllocationsInstrument.js:
(WebInspector.HeapAllocationsInstrument.prototype.startInstrumentation):
(WebInspector.HeapAllocationsInstrument.prototype.stopInstrumentation):
* UserInterface/Models/Instrument.js:
(WebInspector.Instrument.startLegacyTimelineAgent):
(WebInspector.Instrument.prototype.startInstrumentation):
(WebInspector.Instrument.prototype.stopInstrumentation):
(WebInspector.Instrument):
* UserInterface/Models/MemoryInstrument.js:
(WebInspector.MemoryInstrument.prototype.startInstrumentation):
(WebInspector.MemoryInstrument.prototype.stopInstrumentation):
(WebInspector.MemoryInstrument):
* UserInterface/Models/NetworkInstrument.js:
* UserInterface/Models/ScriptInstrument.js:
(WebInspector.ScriptInstrument.prototype.startInstrumentation):
(WebInspector.ScriptInstrument.prototype.stopInstrumentation):
(WebInspector.ScriptInstrument):
Avoid sending start/stop tracking messages when programmatic.
This still allows the instruments to do their own frontend tracking,
such as the Heap agent triggering periodic snapshots.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorInstrumentationcpp">trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp</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="#trunkSourceWebInspectorUIUserInterfaceModelsHeapAllocationsInstrumentjs">trunk/Source/WebInspectorUI/UserInterface/Models/HeapAllocationsInstrument.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsInstrumentjs">trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsMemoryInstrumentjs">trunk/Source/WebInspectorUI/UserInterface/Models/MemoryInstrument.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsNetworkInstrumentjs">trunk/Source/WebInspectorUI/UserInterface/Models/NetworkInstrument.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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebCore/ChangeLog        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -1,5 +1,48 @@
</span><span class="cx"> 2016-06-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: first heap snapshot taken when a page is reloaded happens before the reload navigation
+        https://bugs.webkit.org/show_bug.cgi?id=158995
+        &lt;rdar://problem/26923778&gt;
+
+        Reviewed by Brian Burg.
+
+        When the &quot;Heap&quot; instrument is included in the Timeline list
+        of instruments, defer starting it in an auto-capture scenario
+        until after the page does its first navigation.
+
+        AutoCapture on the backend happens when it is enabled at
+        the main resource starts loading. In that case it proceeds
+        through the following phases:
+
+            No Auto Capture:
+                None
+
+            Auto Capture:
+                BeforeLoad -&gt; FirstNavigation -&gt; AfterFirstNavigation
+
+        When toggling instruments for backend initiated capture
+        most instruments do not care and will just start/stop.
+
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didCommitLoadImpl):
+        Inform the TimelineAgent that the main frame navigated.
+        Do this after informing the HeapAgent (so any potential
+        snapshot does not get cleared) and PageAgent (so the
+        frontend knows the page navigated before the agent starts).
+
+        * inspector/InspectorTimelineAgent.h:
+        * inspector/InspectorTimelineAgent.cpp:
+        (WebCore::InspectorTimelineAgent::internalStop):
+        (WebCore::InspectorTimelineAgent::mainFrameStartedLoading):
+        (WebCore::InspectorTimelineAgent::mainFrameNavigated):
+        Update the auto capture phase transitions.
+
+        (WebCore::InspectorTimelineAgent::toggleHeapInstrument):
+        Only start the heap agent during the None phase (console.profile)
+        or with the first navigation (auto capture page navigation).
+
+2016-06-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: Snapshots should be cleared at some point
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=157907
</span><span class="cx">         &lt;rdar://problem/26373610&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorInstrumentationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -754,6 +754,11 @@
</span><span class="cx">     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
</span><span class="cx">         pageAgent-&gt;frameNavigated(loader);
</span><span class="cx"> 
</span><ins>+    if (loader-&gt;frame()-&gt;isMainFrame()) {
+        if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
+            timelineAgent-&gt;mainFrameNavigated();
+    }
+
</ins><span class="cx"> #if ENABLE(WEB_REPLAY)
</span><span class="cx">     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
</span><span class="cx">         replayAgent-&gt;frameNavigated(loader);
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -234,6 +234,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_enabled = false;
</span><span class="cx">     m_startedComposite = false;
</span><ins>+    m_autoCapturePhase = AutoCapturePhase::None;
</ins><span class="cx"> 
</span><span class="cx">     m_frontendDispatcher-&gt;recordingStopped(timestamp());
</span><span class="cx"> }
</span><span class="lines">@@ -439,6 +440,8 @@
</span><span class="cx">     if (m_instruments.isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    m_autoCapturePhase = AutoCapturePhase::BeforeLoad;
+
</ins><span class="cx">     // Pre-emptively disable breakpoints. The frontend must re-enable them.
</span><span class="cx">     if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) {
</span><span class="cx">         ErrorString unused;
</span><span class="lines">@@ -451,6 +454,15 @@
</span><span class="cx">     toggleInstruments(InstrumentState::Start);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InspectorTimelineAgent::mainFrameNavigated()
+{
+    if (m_autoCapturePhase == AutoCapturePhase::BeforeLoad) {
+        m_autoCapturePhase = AutoCapturePhase::FirstNavigation;
+        toggleInstruments(InstrumentState::Start);
+        m_autoCapturePhase = AutoCapturePhase::AfterFirstNavigation;
+    }
+}
+
</ins><span class="cx"> void InspectorTimelineAgent::startProgrammaticCapture()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_enabled);
</span><span class="lines">@@ -531,9 +543,10 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_heapAgent) {
</span><span class="cx">         ErrorString unused;
</span><del>-        if (state == InstrumentState::Start)
-            m_heapAgent-&gt;startTracking(unused);
-        else
</del><ins>+        if (state == InstrumentState::Start) {
+            if (m_autoCapturePhase == AutoCapturePhase::None || m_autoCapturePhase == AutoCapturePhase::FirstNavigation)
+                m_heapAgent-&gt;startTracking(unused);
+        } else
</ins><span class="cx">             m_heapAgent-&gt;stopTracking(unused);
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx">     void time(Frame&amp;, const String&amp;);
</span><span class="cx">     void timeEnd(Frame&amp;, const String&amp;);
</span><span class="cx">     void mainFrameStartedLoading();
</span><ins>+    void mainFrameNavigated();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     // ScriptDebugListener
</span><span class="lines">@@ -222,6 +223,8 @@
</span><span class="cx">     bool m_programmaticCaptureRestoreBreakpointActiveValue { false };
</span><span class="cx"> 
</span><span class="cx">     bool m_autoCaptureEnabled { false };
</span><ins>+    enum class AutoCapturePhase { None, BeforeLoad, FirstNavigation, AfterFirstNavigation };
+    AutoCapturePhase m_autoCapturePhase { AutoCapturePhase::None };
</ins><span class="cx">     Vector&lt;Inspector::Protocol::Timeline::Instrument&gt; m_instruments;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -1,5 +1,58 @@
</span><span class="cx"> 2016-06-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: first heap snapshot taken when a page is reloaded happens before the reload navigation
+        https://bugs.webkit.org/show_bug.cgi?id=158995
+        &lt;rdar://problem/26923778&gt;
+
+        Reviewed by Brian Burg.
+
+        Let instruments decide to do work or not based on programmatic
+        (backend initiated) starts and stop.
+
+        Programmatic start can happen due to Auto Capture or console.profile.
+        Programmatic stop can happen due to console.profileEnd.
+
+        For example, this allows the frontend to avoid sending agents start/stop
+        messages when the backend would have already started/stopped the agents.
+
+        * UserInterface/Controllers/TimelineManager.js:
+        (WebInspector.TimelineManager):
+        (WebInspector.TimelineManager.prototype.startCapturing):
+        (WebInspector.TimelineManager.prototype.capturingStopped):
+        (WebInspector.TimelineManager.prototype.autoCaptureStarted):
+        (WebInspector.TimelineManager.prototype.programmaticCaptureStarted):
+        Call Recording.start/stop with a programmatic flag so the frontend
+        instruments can perform a more informed start/stop.
+
+        * UserInterface/Models/TimelineRecording.js:
+        (WebInspector.TimelineRecording.prototype.start):
+        (WebInspector.TimelineRecording.prototype.stop):
+        Let the instruments decide to do work based on the start/stop
+        being initiated by the backend or not.
+
+        * UserInterface/Models/HeapAllocationsInstrument.js:
+        (WebInspector.HeapAllocationsInstrument.prototype.startInstrumentation):
+        (WebInspector.HeapAllocationsInstrument.prototype.stopInstrumentation):
+        * UserInterface/Models/Instrument.js:
+        (WebInspector.Instrument.startLegacyTimelineAgent):
+        (WebInspector.Instrument.prototype.startInstrumentation):
+        (WebInspector.Instrument.prototype.stopInstrumentation):
+        (WebInspector.Instrument):
+        * UserInterface/Models/MemoryInstrument.js:
+        (WebInspector.MemoryInstrument.prototype.startInstrumentation):
+        (WebInspector.MemoryInstrument.prototype.stopInstrumentation):
+        (WebInspector.MemoryInstrument):
+        * UserInterface/Models/NetworkInstrument.js:
+        * UserInterface/Models/ScriptInstrument.js:
+        (WebInspector.ScriptInstrument.prototype.startInstrumentation):
+        (WebInspector.ScriptInstrument.prototype.stopInstrumentation):
+        (WebInspector.ScriptInstrument):
+        Avoid sending start/stop tracking messages when programmatic.
+        This still allows the instruments to do their own frontend tracking,
+        such as the Heap agent triggering periodic snapshots.
+
+2016-06-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: Snapshots should be cleared at some point
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=157907
</span><span class="cx">         &lt;rdar://problem/26373610&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -42,6 +42,8 @@
</span><span class="cx">         this._persistentNetworkTimeline = new WebInspector.NetworkTimeline;
</span><span class="cx"> 
</span><span class="cx">         this._isCapturing = false;
</span><ins>+        this._initiatedByBackendStart = false;
+        this._initiatedByBackendStop = false;
</ins><span class="cx">         this._waitingForCapturingStartedEvent = false;
</span><span class="cx">         this._isCapturingPageReload = false;
</span><span class="cx">         this._autoCaptureOnPageLoad = false;
</span><span class="lines">@@ -180,7 +182,7 @@
</span><span class="cx"> 
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingWillStart);
</span><span class="cx"> 
</span><del>-        this._activeRecording.start();
</del><ins>+        this._activeRecording.start(this._initiatedByBackendStart);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     stopCapturing()
</span><span class="lines">@@ -187,7 +189,7 @@
</span><span class="cx">     {
</span><span class="cx">         console.assert(this._isCapturing, &quot;TimelineManager is not capturing.&quot;);
</span><span class="cx"> 
</span><del>-        this._activeRecording.stop();
</del><ins>+        this._activeRecording.stop(this._initiatedByBackendStop);
</ins><span class="cx"> 
</span><span class="cx">         // NOTE: Always stop immediately instead of waiting for a Timeline.recordingStopped event.
</span><span class="cx">         // This way the UI feels as responsive to a stop as possible.
</span><span class="lines">@@ -263,6 +265,8 @@
</span><span class="cx">         this._isCapturingPageReload = false;
</span><span class="cx">         this._shouldSetAutoCapturingMainResource = false;
</span><span class="cx">         this._mainResourceForAutoCapturing = null;
</span><ins>+        this._initiatedByBackendStart = false;
+        this._initiatedByBackendStop = false;
</ins><span class="cx"> 
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingStopped, {endTime});
</span><span class="cx">     }
</span><span class="lines">@@ -274,6 +278,8 @@
</span><span class="cx">         if (this._isCapturing)
</span><span class="cx">             this.stopCapturing();
</span><span class="cx"> 
</span><ins>+        this._initiatedByBackendStart = true;
+
</ins><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><span class="lines">@@ -289,6 +295,8 @@
</span><span class="cx">     {
</span><span class="cx">         // Called from WebInspector.TimelineObserver.
</span><span class="cx"> 
</span><ins>+        this._initiatedByBackendStart = true;
+
</ins><span class="cx">         this._activeRecording.addScriptInstrumentForProgrammaticCapture();
</span><span class="cx"> 
</span><span class="cx">         const createNewRecording = false;
</span><span class="lines">@@ -299,6 +307,8 @@
</span><span class="cx">     {
</span><span class="cx">         // Called from WebInspector.TimelineObserver.
</span><span class="cx"> 
</span><ins>+        this._initiatedByBackendStop = true;
+
</ins><span class="cx">         // FIXME: This is purely to avoid a noisy assert. Previously
</span><span class="cx">         // it was impossible to stop without stopping from the UI.
</span><span class="cx">         console.assert(!this._isCapturing);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsHeapAllocationsInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/HeapAllocationsInstrument.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/HeapAllocationsInstrument.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/HeapAllocationsInstrument.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -49,12 +49,13 @@
</span><span class="cx">         return WebInspector.TimelineRecord.Type.HeapAllocations;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    startInstrumentation()
</del><ins>+    startInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         // FIXME: Include a &quot;track allocations&quot; option for this instrument.
</span><span class="cx">         // FIXME: Include a periodic snapshot interval option for this instrument.
</span><span class="cx"> 
</span><del>-        HeapAgent.startTracking();
</del><ins>+        if (!initiatedByBackend)
+            HeapAgent.startTracking();
</ins><span class="cx"> 
</span><span class="cx">         // Periodic snapshots.
</span><span class="cx">         const snapshotInterval = 10000;
</span><span class="lines">@@ -61,9 +62,10 @@
</span><span class="cx">         this._snapshotIntervalIdentifier = setInterval(this._takeHeapSnapshot.bind(this), snapshotInterval);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    stopInstrumentation()
</del><ins>+    stopInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><del>-        HeapAgent.stopTracking();
</del><ins>+        if (!initiatedByBackend)
+            HeapAgent.stopTracking();
</ins><span class="cx"> 
</span><span class="cx">         window.clearInterval(this._snapshotIntervalIdentifier);
</span><span class="cx">         this._snapshotIntervalIdentifier = undefined;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static startLegacyTimelineAgent()
</del><ins>+    static startLegacyTimelineAgent(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(window.TimelineAgent, &quot;Attempted to start legacy timeline agent without TimelineAgent.&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -57,6 +57,9 @@
</span><span class="cx"> 
</span><span class="cx">         WebInspector.Instrument._legacyTimelineAgentStarted = true;
</span><span class="cx"> 
</span><ins>+        if (initiatedByBackend)
+            return;
+
</ins><span class="cx">         let result = TimelineAgent.start();
</span><span class="cx"> 
</span><span class="cx">         // COMPATIBILITY (iOS 7): recordingStarted event did not exist yet. Start explicitly.
</span><span class="lines">@@ -67,7 +70,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static stopLegacyTimelineAgent()
</del><ins>+    static stopLegacyTimelineAgent(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         if (!WebInspector.Instrument._legacyTimelineAgentStarted)
</span><span class="cx">             return;
</span><span class="lines">@@ -74,6 +77,9 @@
</span><span class="cx"> 
</span><span class="cx">         WebInspector.Instrument._legacyTimelineAgentStarted = false;
</span><span class="cx"> 
</span><ins>+        if (initiatedByBackend)
+            return;
+
</ins><span class="cx">         TimelineAgent.stop();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -84,14 +90,14 @@
</span><span class="cx">         return null; // Implemented by subclasses.
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    startInstrumentation()
</del><ins>+    startInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><del>-        WebInspector.Instrument.startLegacyTimelineAgent();
</del><ins>+        WebInspector.Instrument.startLegacyTimelineAgent(initiatedByBackend);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    stopInstrumentation()
</del><ins>+    stopInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><del>-        WebInspector.Instrument.stopLegacyTimelineAgent();
</del><ins>+        WebInspector.Instrument.stopLegacyTimelineAgent(initiatedByBackend);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsMemoryInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/MemoryInstrument.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/MemoryInstrument.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/MemoryInstrument.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -47,13 +47,15 @@
</span><span class="cx">         return WebInspector.TimelineRecord.Type.Memory;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    startInstrumentation()
</del><ins>+    startInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><del>-        MemoryAgent.startTracking();
</del><ins>+        if (!initiatedByBackend)
+            MemoryAgent.startTracking();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    stopInstrumentation()
</del><ins>+    stopInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><del>-        MemoryAgent.stopTracking();
</del><ins>+        if (!initiatedByBackend)
+            MemoryAgent.stopTracking();
</ins><span class="cx">     }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsNetworkInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/NetworkInstrument.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/NetworkInstrument.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/NetworkInstrument.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -32,12 +32,12 @@
</span><span class="cx">         return WebInspector.TimelineRecord.Type.Network;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    startInstrumentation()
</del><ins>+    startInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         // Nothing to do, network instrumentation is always happening.
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    stopInstrumentation()
</del><ins>+    stopInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         // Nothing to do, network instrumentation is always happening.
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScriptInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx">         return WebInspector.TimelineRecord.Type.Script;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    startInstrumentation()
</del><ins>+    startInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         // COMPATIBILITY (iOS 9): Legacy backends did not have ScriptProfilerAgent. They use TimelineAgent.
</span><span class="cx">         if (!window.ScriptProfilerAgent) {
</span><span class="lines">@@ -43,10 +43,11 @@
</span><span class="cx">         // FIXME: Make this some UI visible option.
</span><span class="cx">         const includeSamples = true;
</span><span class="cx"> 
</span><del>-        ScriptProfilerAgent.startTracking(includeSamples);
</del><ins>+        if (!initiatedByBackend)
+            ScriptProfilerAgent.startTracking(includeSamples);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    stopInstrumentation()
</del><ins>+    stopInstrumentation(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         // COMPATIBILITY (iOS 9): Legacy backends did not have ScriptProfilerAgent. They use TimelineAgent.
</span><span class="cx">         if (!window.ScriptProfilerAgent) {
</span><span class="lines">@@ -54,6 +55,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        ScriptProfilerAgent.stopTracking();
</del><ins>+        if (!initiatedByBackend)
+            ScriptProfilerAgent.stopTracking();
</ins><span class="cx">     }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordingjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js (202383 => 202384)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js        2016-06-23 18:52:54 UTC (rev 202383)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js        2016-06-23 18:52:59 UTC (rev 202384)
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">         return this._topFunctionsBottomUpCallingContextTree;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    start()
</del><ins>+    start(initiatedByBackend)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._capturing, &quot;Attempted to start an already started session.&quot;);
</span><span class="cx">         console.assert(!this._readonly, &quot;Attempted to start a readonly session.&quot;);
</span><span class="lines">@@ -124,10 +124,10 @@
</span><span class="cx">         this._capturing = true;
</span><span class="cx"> 
</span><span class="cx">         for (let instrument of this._instruments)
</span><del>-            instrument.startInstrumentation();
</del><ins>+            instrument.startInstrumentation(initiatedByBackend);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    stop(programmatic)
</del><ins>+    stop(initiatedByBackend)
</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,10 +134,8 @@
</span><span class="cx"> 
</span><span class="cx">         this._capturing = false;
</span><span class="cx"> 
</span><del>-        if (!programmatic) {
-            for (let instrument of this._instruments)
-                instrument.stopInstrumentation();
-        }
</del><ins>+        for (let instrument of this._instruments)
+            instrument.stopInstrumentation(initiatedByBackend);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     saveIdentityToCookie()
</span></span></pre>
</div>
</div>

</body>
</html>