Diff
Modified: trunk/Source/WebCore/ChangeLog (202383 => 202384)
--- 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)
@@ -1,5 +1,48 @@
2016-06-23 Joseph Pecoraro <[email protected]>
+ 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
+ <rdar://problem/26923778>
+
+ Reviewed by Brian Burg.
+
+ When the "Heap" 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 -> FirstNavigation -> 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 <[email protected]>
+
Web Inspector: Snapshots should be cleared at some point
https://bugs.webkit.org/show_bug.cgi?id=157907
<rdar://problem/26373610>
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (202383 => 202384)
--- 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)
@@ -754,6 +754,11 @@
if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
pageAgent->frameNavigated(loader);
+ if (loader->frame()->isMainFrame()) {
+ if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
+ timelineAgent->mainFrameNavigated();
+ }
+
#if ENABLE(WEB_REPLAY)
if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
replayAgent->frameNavigated(loader);
Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (202383 => 202384)
--- 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)
@@ -234,6 +234,7 @@
m_enabled = false;
m_startedComposite = false;
+ m_autoCapturePhase = AutoCapturePhase::None;
m_frontendDispatcher->recordingStopped(timestamp());
}
@@ -439,6 +440,8 @@
if (m_instruments.isEmpty())
return;
+ m_autoCapturePhase = AutoCapturePhase::BeforeLoad;
+
// Pre-emptively disable breakpoints. The frontend must re-enable them.
if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents.inspectorDebuggerAgent()) {
ErrorString unused;
@@ -451,6 +454,15 @@
toggleInstruments(InstrumentState::Start);
}
+void InspectorTimelineAgent::mainFrameNavigated()
+{
+ if (m_autoCapturePhase == AutoCapturePhase::BeforeLoad) {
+ m_autoCapturePhase = AutoCapturePhase::FirstNavigation;
+ toggleInstruments(InstrumentState::Start);
+ m_autoCapturePhase = AutoCapturePhase::AfterFirstNavigation;
+ }
+}
+
void InspectorTimelineAgent::startProgrammaticCapture()
{
ASSERT(!m_enabled);
@@ -531,9 +543,10 @@
{
if (m_heapAgent) {
ErrorString unused;
- if (state == InstrumentState::Start)
- m_heapAgent->startTracking(unused);
- else
+ if (state == InstrumentState::Start) {
+ if (m_autoCapturePhase == AutoCapturePhase::None || m_autoCapturePhase == AutoCapturePhase::FirstNavigation)
+ m_heapAgent->startTracking(unused);
+ } else
m_heapAgent->stopTracking(unused);
}
}
Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (202383 => 202384)
--- 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)
@@ -141,6 +141,7 @@
void time(Frame&, const String&);
void timeEnd(Frame&, const String&);
void mainFrameStartedLoading();
+ void mainFrameNavigated();
private:
// ScriptDebugListener
@@ -222,6 +223,8 @@
bool m_programmaticCaptureRestoreBreakpointActiveValue { false };
bool m_autoCaptureEnabled { false };
+ enum class AutoCapturePhase { None, BeforeLoad, FirstNavigation, AfterFirstNavigation };
+ AutoCapturePhase m_autoCapturePhase { AutoCapturePhase::None };
Vector<Inspector::Protocol::Timeline::Instrument> m_instruments;
#if PLATFORM(COCOA)
Modified: trunk/Source/WebInspectorUI/ChangeLog (202383 => 202384)
--- 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)
@@ -1,5 +1,58 @@
2016-06-23 Joseph Pecoraro <[email protected]>
+ 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
+ <rdar://problem/26923778>
+
+ 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 <[email protected]>
+
Web Inspector: Snapshots should be cleared at some point
https://bugs.webkit.org/show_bug.cgi?id=157907
<rdar://problem/26373610>
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (202383 => 202384)
--- 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)
@@ -42,6 +42,8 @@
this._persistentNetworkTimeline = new WebInspector.NetworkTimeline;
this._isCapturing = false;
+ this._initiatedByBackendStart = false;
+ this._initiatedByBackendStop = false;
this._waitingForCapturingStartedEvent = false;
this._isCapturingPageReload = false;
this._autoCaptureOnPageLoad = false;
@@ -180,7 +182,7 @@
this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingWillStart);
- this._activeRecording.start();
+ this._activeRecording.start(this._initiatedByBackendStart);
}
stopCapturing()
@@ -187,7 +189,7 @@
{
console.assert(this._isCapturing, "TimelineManager is not capturing.");
- this._activeRecording.stop();
+ this._activeRecording.stop(this._initiatedByBackendStop);
// NOTE: Always stop immediately instead of waiting for a Timeline.recordingStopped event.
// This way the UI feels as responsive to a stop as possible.
@@ -263,6 +265,8 @@
this._isCapturingPageReload = false;
this._shouldSetAutoCapturingMainResource = false;
this._mainResourceForAutoCapturing = null;
+ this._initiatedByBackendStart = false;
+ this._initiatedByBackendStop = false;
this.dispatchEventToListeners(WebInspector.TimelineManager.Event.CapturingStopped, {endTime});
}
@@ -274,6 +278,8 @@
if (this._isCapturing)
this.stopCapturing();
+ this._initiatedByBackendStart = true;
+
// We may already have an fresh TimelineRecording created if autoCaptureStarted is received
// between sending the Timeline.start command and receiving Timeline.capturingStarted event.
// In that case, there is no need to call startCapturing again. Reuse the fresh recording.
@@ -289,6 +295,8 @@
{
// Called from WebInspector.TimelineObserver.
+ this._initiatedByBackendStart = true;
+
this._activeRecording.addScriptInstrumentForProgrammaticCapture();
const createNewRecording = false;
@@ -299,6 +307,8 @@
{
// Called from WebInspector.TimelineObserver.
+ this._initiatedByBackendStop = true;
+
// FIXME: This is purely to avoid a noisy assert. Previously
// it was impossible to stop without stopping from the UI.
console.assert(!this._isCapturing);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/HeapAllocationsInstrument.js (202383 => 202384)
--- 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)
@@ -49,12 +49,13 @@
return WebInspector.TimelineRecord.Type.HeapAllocations;
}
- startInstrumentation()
+ startInstrumentation(initiatedByBackend)
{
// FIXME: Include a "track allocations" option for this instrument.
// FIXME: Include a periodic snapshot interval option for this instrument.
- HeapAgent.startTracking();
+ if (!initiatedByBackend)
+ HeapAgent.startTracking();
// Periodic snapshots.
const snapshotInterval = 10000;
@@ -61,9 +62,10 @@
this._snapshotIntervalIdentifier = setInterval(this._takeHeapSnapshot.bind(this), snapshotInterval);
}
- stopInstrumentation()
+ stopInstrumentation(initiatedByBackend)
{
- HeapAgent.stopTracking();
+ if (!initiatedByBackend)
+ HeapAgent.stopTracking();
window.clearInterval(this._snapshotIntervalIdentifier);
this._snapshotIntervalIdentifier = undefined;
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Instrument.js (202383 => 202384)
--- 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)
@@ -48,7 +48,7 @@
}
}
- static startLegacyTimelineAgent()
+ static startLegacyTimelineAgent(initiatedByBackend)
{
console.assert(window.TimelineAgent, "Attempted to start legacy timeline agent without TimelineAgent.");
@@ -57,6 +57,9 @@
WebInspector.Instrument._legacyTimelineAgentStarted = true;
+ if (initiatedByBackend)
+ return;
+
let result = TimelineAgent.start();
// COMPATIBILITY (iOS 7): recordingStarted event did not exist yet. Start explicitly.
@@ -67,7 +70,7 @@
}
}
- static stopLegacyTimelineAgent()
+ static stopLegacyTimelineAgent(initiatedByBackend)
{
if (!WebInspector.Instrument._legacyTimelineAgentStarted)
return;
@@ -74,6 +77,9 @@
WebInspector.Instrument._legacyTimelineAgentStarted = false;
+ if (initiatedByBackend)
+ return;
+
TimelineAgent.stop();
}
@@ -84,14 +90,14 @@
return null; // Implemented by subclasses.
}
- startInstrumentation()
+ startInstrumentation(initiatedByBackend)
{
- WebInspector.Instrument.startLegacyTimelineAgent();
+ WebInspector.Instrument.startLegacyTimelineAgent(initiatedByBackend);
}
- stopInstrumentation()
+ stopInstrumentation(initiatedByBackend)
{
- WebInspector.Instrument.stopLegacyTimelineAgent();
+ WebInspector.Instrument.stopLegacyTimelineAgent(initiatedByBackend);
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/MemoryInstrument.js (202383 => 202384)
--- 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)
@@ -47,13 +47,15 @@
return WebInspector.TimelineRecord.Type.Memory;
}
- startInstrumentation()
+ startInstrumentation(initiatedByBackend)
{
- MemoryAgent.startTracking();
+ if (!initiatedByBackend)
+ MemoryAgent.startTracking();
}
- stopInstrumentation()
+ stopInstrumentation(initiatedByBackend)
{
- MemoryAgent.stopTracking();
+ if (!initiatedByBackend)
+ MemoryAgent.stopTracking();
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/NetworkInstrument.js (202383 => 202384)
--- 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)
@@ -32,12 +32,12 @@
return WebInspector.TimelineRecord.Type.Network;
}
- startInstrumentation()
+ startInstrumentation(initiatedByBackend)
{
// Nothing to do, network instrumentation is always happening.
}
- stopInstrumentation()
+ stopInstrumentation(initiatedByBackend)
{
// Nothing to do, network instrumentation is always happening.
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js (202383 => 202384)
--- 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)
@@ -32,7 +32,7 @@
return WebInspector.TimelineRecord.Type.Script;
}
- startInstrumentation()
+ startInstrumentation(initiatedByBackend)
{
// COMPATIBILITY (iOS 9): Legacy backends did not have ScriptProfilerAgent. They use TimelineAgent.
if (!window.ScriptProfilerAgent) {
@@ -43,10 +43,11 @@
// FIXME: Make this some UI visible option.
const includeSamples = true;
- ScriptProfilerAgent.startTracking(includeSamples);
+ if (!initiatedByBackend)
+ ScriptProfilerAgent.startTracking(includeSamples);
}
- stopInstrumentation()
+ stopInstrumentation(initiatedByBackend)
{
// COMPATIBILITY (iOS 9): Legacy backends did not have ScriptProfilerAgent. They use TimelineAgent.
if (!window.ScriptProfilerAgent) {
@@ -54,6 +55,7 @@
return;
}
- ScriptProfilerAgent.stopTracking();
+ if (!initiatedByBackend)
+ ScriptProfilerAgent.stopTracking();
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js (202383 => 202384)
--- 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)
@@ -116,7 +116,7 @@
return this._topFunctionsBottomUpCallingContextTree;
}
- start()
+ start(initiatedByBackend)
{
console.assert(!this._capturing, "Attempted to start an already started session.");
console.assert(!this._readonly, "Attempted to start a readonly session.");
@@ -124,10 +124,10 @@
this._capturing = true;
for (let instrument of this._instruments)
- instrument.startInstrumentation();
+ instrument.startInstrumentation(initiatedByBackend);
}
- stop(programmatic)
+ stop(initiatedByBackend)
{
console.assert(this._capturing, "Attempted to stop an already stopped session.");
console.assert(!this._readonly, "Attempted to stop a readonly session.");
@@ -134,10 +134,8 @@
this._capturing = false;
- if (!programmatic) {
- for (let instrument of this._instruments)
- instrument.stopInstrumentation();
- }
+ for (let instrument of this._instruments)
+ instrument.stopInstrumentation(initiatedByBackend);
}
saveIdentityToCookie()