<!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>[174319] 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/174319">174319</a></dd>
<dt>Author</dt> <dd>burg@cs.washington.edu</dd>
<dt>Date</dt> <dd>2014-10-04 12:18:38 -0700 (Sat, 04 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: timelines should not count time elapsed while paused in the debugger
https://bugs.webkit.org/show_bug.cgi?id=136351

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Now that we have a stopwatch to provide pause-aware timing data, we can remove the
profiler's handling of debugger pause/continue callbacks. The timeline agent accounts
for debugger pauses by pausing and resuming the stopwatch.

* API/JSProfilerPrivate.cpp:
(JSStartProfiling): Use a fresh stopwatch when profiling from the JSC API.
* inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::handlePause):
* profiler/LegacyProfiler.cpp:
(JSC::LegacyProfiler::profiler): Use nullptr.
(JSC::LegacyProfiler::startProfiling): Hand off a stopwatch to the profile generator.
(JSC::LegacyProfiler::stopProfiling): Use nullptr.
(JSC::LegacyProfiler::didPause): Deleted.
(JSC::LegacyProfiler::didContinue): Deleted.
* profiler/LegacyProfiler.h:
* profiler/ProfileGenerator.cpp: Remove debugger pause/continue callbacks and the
timestamp member that was used to track time elapsed by the debugger. Just use the
stopwatch's elapsed times to generate start/elapsed times for function calls.
(JSC::ProfileGenerator::create):
(JSC::ProfileGenerator::ProfileGenerator):
(JSC::ProfileGenerator::beginCallEntry):
(JSC::ProfileGenerator::endCallEntry):
(JSC::ProfileGenerator::didPause): Deleted.
(JSC::ProfileGenerator::didContinue): Deleted.
* profiler/ProfileGenerator.h:

Source/WebCore:

To avoid counting time elapsed while the debugger is paused, timeline records should
keep track of time elapsed since the start of timeline capturing, rather than wall clock
timestamps. We can easily compute elapsed time by sharing Stopwatch instance among
all timeline record-generating code. The stopwatch is paused while the debugger is paused,
so subsequent time measurements will not include time elapsed while the debugger is paused.

Agents use the shared stopwatch to generate timestamps if the timeline agent is active
(i.e., a timeline recording is being captured). If not, use a zero timestamp since the timing data is only revealed through the Timeline interface.

This refactoring is safe because start and end times are only used to graph records; the
timestamp's actual value is irrelevant and is not displayed in the user interface. Date
timestamps are still included with network-related records as part of their header data.

No new tests, because we cannot reliably test timing changes induced by debugger pauses.
It is possible for records to accrue time before the debugger pauses or after it resumes.

* inspector/InspectorCSSAgent.cpp: Remove unused include.
* inspector/InspectorPageAgent.cpp: Use timestamps from the shared stopwatch.
(WebCore::InspectorPageAgent::timestamp):
(WebCore::InspectorPageAgent::domContentEventFired):
(WebCore::InspectorPageAgent::loadEventFired):
* inspector/InspectorPageAgent.h:
* inspector/InspectorResourceAgent.cpp: Use timestamps from the shared stopwatch.
(WebCore::InspectorResourceAgent::timestamp):
(WebCore::InspectorResourceAgent::willSendRequest):
(WebCore::InspectorResourceAgent::didReceiveResponse):
(WebCore::InspectorResourceAgent::didReceiveData):
(WebCore::InspectorResourceAgent::didFinishLoading):
(WebCore::InspectorResourceAgent::didFailLoading):
(WebCore::InspectorResourceAgent::didLoadResourceFromMemoryCache):
(WebCore::InspectorResourceAgent::willSendWebSocketHandshakeRequest):
(WebCore::InspectorResourceAgent::didReceiveWebSocketHandshakeResponse):
(WebCore::InspectorResourceAgent::didCloseWebSocket):
(WebCore::InspectorResourceAgent::didReceiveWebSocketFrame):
(WebCore::InspectorResourceAgent::didSendWebSocketFrame):
(WebCore::InspectorResourceAgent::didReceiveWebSocketFrameError):
* inspector/InspectorResourceAgent.h:
* inspector/InspectorTimelineAgent.cpp: Add calls to reset, start, and stop the stopwatch.
(WebCore::InspectorTimelineAgent::didCreateFrontendAndBackend):
(WebCore::InspectorTimelineAgent::internalStart):
(WebCore::InspectorTimelineAgent::internalStop):
(WebCore::startProfiling):
(WebCore::InspectorTimelineAgent::startFromConsole):
(WebCore::InspectorTimelineAgent::willCallFunction):
(WebCore::InspectorTimelineAgent::willEvaluateScript):
(WebCore::InspectorTimelineAgent::didPause):
(WebCore::InspectorTimelineAgent::didContinue):
(WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
(WebCore::InspectorTimelineAgent::timestamp):
(WebCore::TimelineTimeConverter::reset): Deleted.
* inspector/InspectorTimelineAgent.h: Make timestamp() public, and remove old timepieces.
(WebCore::TimelineTimeConverter::TimelineTimeConverter): Deleted.
(WebCore::TimelineTimeConverter::fromMonotonicallyIncreasingTime): Deleted.
(WebCore::InspectorTimelineAgent::timeConverter): Deleted.
* inspector/TimelineRecordFactory.cpp:

Source/WebInspectorUI:

Don't update the timeline's current time when the debugger is paused.

Start and end times for timeline records are now in seconds elapsed since timeline
recording started, rather than milliseconds since the epoch. Add a workaround to
preserve compatibility with old backends.

* UserInterface/Controllers/TimelineManager.js:
(WebInspector.TimelineManager.prototype.capturingStarted):
(WebInspector.TimelineManager.prototype.eventRecorded.processRecord):
(WebInspector.TimelineManager.prototype.eventRecorded):
* UserInterface/Views/TimelineContentView.js:
(WebInspector.TimelineContentView.prototype._debuggerPaused):
(WebInspector.TimelineContentView.prototype._debuggerResumed):

Source/WTF:

* WTF.vcxproj/WTF.vcxproj:
* WTF.vcxproj/WTF.vcxproj.filters:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/Stopwatch.h: Added. This implements a refcounted monotonic stopwatch.
(WTF::Stopwatch::reset):
(WTF::Stopwatch::start):
(WTF::Stopwatch::stop):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSProfilerPrivatecpp">trunk/Source/JavaScriptCore/API/JSProfilerPrivate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptDebugServercpp">trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerLegacyProfilercpp">trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerLegacyProfilerh">trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerProfileGeneratorcpp">trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerProfileGeneratorh">trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFWTFvcxprojWTFvcxproj">trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj</a></li>
<li><a href="#trunkSourceWTFWTFvcxprojWTFvcxprojfilters">trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters</a></li>
<li><a href="#trunkSourceWTFWTFxcodeprojprojectpbxproj">trunk/Source/WTF/WTF.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWTFwtfCMakeListstxt">trunk/Source/WTF/wtf/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorCSSAgentcpp">trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorPageAgentcpp">trunk/Source/WebCore/inspector/InspectorPageAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorPageAgenth">trunk/Source/WebCore/inspector/InspectorPageAgent.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorResourceAgentcpp">trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorResourceAgenth">trunk/Source/WebCore/inspector/InspectorResourceAgent.h</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="#trunkSourceWebCoreinspectorTimelineRecordFactorycpp">trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp</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="#trunkSourceWebInspectorUIUserInterfaceViewsTimelineContentViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWTFwtfStopwatchh">trunk/Source/WTF/wtf/Stopwatch.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSProfilerPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSProfilerPrivate.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSProfilerPrivate.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/API/JSProfilerPrivate.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> 
</span><span class="cx"> void JSStartProfiling(JSContextRef ctx, JSStringRef title)
</span><span class="cx"> {
</span><del>-    LegacyProfiler::profiler()-&gt;startProfiling(toJS(ctx), title-&gt;string());
</del><ins>+    LegacyProfiler::profiler()-&gt;startProfiling(toJS(ctx), title-&gt;string(), Stopwatch::create());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSEndProfiling(JSContextRef ctx, JSStringRef title)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2014-10-04  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Reviewed by Timothy Hatcher.
+
+        Now that we have a stopwatch to provide pause-aware timing data, we can remove the
+        profiler's handling of debugger pause/continue callbacks. The timeline agent accounts
+        for debugger pauses by pausing and resuming the stopwatch.
+
+        * API/JSProfilerPrivate.cpp:
+        (JSStartProfiling): Use a fresh stopwatch when profiling from the JSC API.
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::handlePause):
+        * profiler/LegacyProfiler.cpp:
+        (JSC::LegacyProfiler::profiler): Use nullptr.
+        (JSC::LegacyProfiler::startProfiling): Hand off a stopwatch to the profile generator.
+        (JSC::LegacyProfiler::stopProfiling): Use nullptr.
+        (JSC::LegacyProfiler::didPause): Deleted.
+        (JSC::LegacyProfiler::didContinue): Deleted.
+        * profiler/LegacyProfiler.h:
+        * profiler/ProfileGenerator.cpp: Remove debugger pause/continue callbacks and the
+        timestamp member that was used to track time elapsed by the debugger. Just use the
+        stopwatch's elapsed times to generate start/elapsed times for function calls.
+        (JSC::ProfileGenerator::create):
+        (JSC::ProfileGenerator::ProfileGenerator):
+        (JSC::ProfileGenerator::beginCallEntry):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didPause): Deleted.
+        (JSC::ProfileGenerator::didContinue): Deleted.
+        * profiler/ProfileGenerator.h:
+
</ins><span class="cx"> 2014-10-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         FTL should sink PutLocals
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptDebugServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> #include &quot;JSJavaScriptCallFrame.h&quot;
</span><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="cx"> #include &quot;JavaScriptCallFrame.h&quot;
</span><del>-#include &quot;LegacyProfiler.h&quot;
</del><span class="cx"> #include &quot;ScriptValue.h&quot;
</span><span class="cx"> #include &quot;SourceProvider.h&quot;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="lines">@@ -307,14 +306,12 @@
</span><span class="cx"> void ScriptDebugServer::handlePause(Debugger::ReasonForPause, JSGlobalObject* vmEntryGlobalObject)
</span><span class="cx"> {
</span><span class="cx">     dispatchFunctionToListeners(&amp;ScriptDebugServer::dispatchDidPause);
</span><del>-    LegacyProfiler::profiler()-&gt;didPause(currentDebuggerCallFrame());
</del><span class="cx">     didPause(vmEntryGlobalObject);
</span><span class="cx"> 
</span><span class="cx">     m_doneProcessingDebuggerEvents = false;
</span><span class="cx">     runEventLoopWhilePaused();
</span><span class="cx"> 
</span><span class="cx">     didContinue(vmEntryGlobalObject);
</span><del>-    LegacyProfiler::profiler()-&gt;didContinue(currentDebuggerCallFrame());
</del><span class="cx">     dispatchFunctionToListeners(&amp;ScriptDebugServer::dispatchDidContinue);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerLegacyProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -32,7 +32,6 @@
</span><span class="cx"> #include &quot;CallFrame.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;CommonIdentifiers.h&quot;
</span><del>-#include &quot;DebuggerCallFrame.h&quot;
</del><span class="cx"> #include &quot;InternalFunction.h&quot;
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="lines">@@ -50,16 +49,16 @@
</span><span class="cx"> 
</span><span class="cx"> static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String&amp; defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber);
</span><span class="cx"> 
</span><del>-LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0;
</del><ins>+LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = nullptr;
</ins><span class="cx"> 
</span><span class="cx"> LegacyProfiler* LegacyProfiler::profiler()
</span><span class="cx"> {
</span><span class="cx">     if (!s_sharedLegacyProfiler)
</span><span class="cx">         s_sharedLegacyProfiler = new LegacyProfiler();
</span><span class="cx">     return s_sharedLegacyProfiler;
</span><del>-}   
</del><ins>+}
</ins><span class="cx"> 
</span><del>-void LegacyProfiler::startProfiling(ExecState* exec, const String&amp; title)
</del><ins>+void LegacyProfiler::startProfiling(ExecState* exec, const String&amp; title, PassRefPtr&lt;Stopwatch&gt; stopwatch)
</ins><span class="cx"> {
</span><span class="cx">     if (!exec)
</span><span class="cx">         return;
</span><span class="lines">@@ -75,14 +74,14 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     exec-&gt;vm().setEnabledProfiler(this);
</span><del>-    RefPtr&lt;ProfileGenerator&gt; profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
</del><ins>+    RefPtr&lt;ProfileGenerator&gt; profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID, stopwatch);
</ins><span class="cx">     m_currentProfiles.append(profileGenerator);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;Profile&gt; LegacyProfiler::stopProfiling(ExecState* exec, const String&amp; title)
</span><span class="cx"> {
</span><span class="cx">     if (!exec)
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx"> 
</span><span class="cx">     JSGlobalObject* origin = exec-&gt;lexicalGlobalObject();
</span><span class="cx">     for (ptrdiff_t i = m_currentProfiles.size() - 1; i &gt;= 0; --i) {
</span><span class="lines">@@ -94,12 +93,12 @@
</span><span class="cx">             m_currentProfiles.remove(i);
</span><span class="cx">             if (!m_currentProfiles.size())
</span><span class="cx">                 exec-&gt;vm().setEnabledProfiler(nullptr);
</span><del>-            
</del><ins>+
</ins><span class="cx">             return returnProfile;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return 0;
</del><ins>+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void LegacyProfiler::stopProfiling(JSGlobalObject* origin)
</span><span class="lines">@@ -184,28 +183,6 @@
</span><span class="cx">     callFunctionForProfilesWithGroup(std::bind(&amp;ProfileGenerator::exceptionUnwind, std::placeholders::_1, handlerCallFrame, callIdentifier), m_currentProfiles, handlerCallFrame-&gt;lexicalGlobalObject()-&gt;profileGroup());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void LegacyProfiler::didPause(PassRefPtr&lt;DebuggerCallFrame&gt; prpCallFrame)
-{
-    if (m_currentProfiles.isEmpty())
-        return;
-
-    RefPtr&lt;DebuggerCallFrame&gt; callFrame = prpCallFrame;
-    CallIdentifier callIdentifier = createCallIdentifier(callFrame-&gt;exec(), JSValue(), StringImpl::empty(), 0, 0);
-
-    callFunctionForProfilesWithGroup(std::bind(&amp;ProfileGenerator::didPause, std::placeholders::_1, callFrame, callIdentifier), m_currentProfiles, callFrame-&gt;vmEntryGlobalObject()-&gt;profileGroup());
-}
-
-void LegacyProfiler::didContinue(PassRefPtr&lt;DebuggerCallFrame&gt; prpCallFrame)
-{
-    if (m_currentProfiles.isEmpty())
-        return;
-
-    RefPtr&lt;DebuggerCallFrame&gt; callFrame = prpCallFrame;
-    CallIdentifier callIdentifier = createCallIdentifier(callFrame-&gt;exec(), JSValue(), StringImpl::empty(), 0, 0);
-
-    callFunctionForProfilesWithGroup(std::bind(&amp;ProfileGenerator::didContinue, std::placeholders::_1, callFrame, callIdentifier), m_currentProfiles, callFrame-&gt;vmEntryGlobalObject()-&gt;profileGroup());
-}
-
</del><span class="cx"> CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String&amp; defaultSourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber)
</span><span class="cx"> {
</span><span class="cx">     if (!functionValue)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerLegacyProfilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -32,13 +32,12 @@
</span><span class="cx"> #include &quot;Profile.h&quot;
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><ins>+#include &lt;wtf/Stopwatch.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-class DebuggerCallFrame;
</del><span class="cx"> class ExecState;
</span><del>-class VM;
</del><span class="cx"> class JSGlobalObject;
</span><span class="cx"> class JSObject;
</span><span class="cx"> class JSValue;
</span><span class="lines">@@ -48,10 +47,10 @@
</span><span class="cx"> class LegacyProfiler {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    JS_EXPORT_PRIVATE static LegacyProfiler* profiler(); 
</del><ins>+    JS_EXPORT_PRIVATE static LegacyProfiler* profiler();
</ins><span class="cx">     static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String&amp; sourceURL, unsigned defaultLineNumber, unsigned defaultColumnNumber);
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String&amp; title);
</del><ins>+    JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String&amp; title, PassRefPtr&lt;Stopwatch&gt;);
</ins><span class="cx">     JS_EXPORT_PRIVATE PassRefPtr&lt;Profile&gt; stopProfiling(ExecState*, const WTF::String&amp; title);
</span><span class="cx">     void stopProfiling(JSGlobalObject*);
</span><span class="cx"> 
</span><span class="lines">@@ -66,9 +65,6 @@
</span><span class="cx"> 
</span><span class="cx">     void exceptionUnwind(ExecState* handlerCallFrame);
</span><span class="cx"> 
</span><del>-    void didPause(PassRefPtr&lt;DebuggerCallFrame&gt;);
-    void didContinue(PassRefPtr&lt;DebuggerCallFrame&gt;);
-
</del><span class="cx">     const Vector&lt;RefPtr&lt;ProfileGenerator&gt;&gt;&amp; currentProfiles() { return m_currentProfiles; };
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerProfileGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CallFrame.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><del>-#include &quot;Debugger.h&quot;
</del><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> #include &quot;JSStringRef.h&quot;
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="lines">@@ -40,21 +39,18 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;ProfileGenerator&gt; ProfileGenerator::create(ExecState* exec, const String&amp; title, unsigned uid)
</del><ins>+PassRefPtr&lt;ProfileGenerator&gt; ProfileGenerator::create(ExecState* exec, const String&amp; title, unsigned uid, PassRefPtr&lt;Stopwatch&gt; stopwatch)
</ins><span class="cx"> {
</span><del>-    return adoptRef(new ProfileGenerator(exec, title, uid));
</del><ins>+    return adoptRef(new ProfileGenerator(exec, title, uid, stopwatch));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ProfileGenerator::ProfileGenerator(ExecState* exec, const String&amp; title, unsigned uid)
</del><ins>+ProfileGenerator::ProfileGenerator(ExecState* exec, const String&amp; title, unsigned uid, PassRefPtr&lt;Stopwatch&gt; stopwatch)
</ins><span class="cx">     : m_origin(exec ? exec-&gt;lexicalGlobalObject() : nullptr)
</span><span class="cx">     , m_profileGroup(exec ? exec-&gt;lexicalGlobalObject()-&gt;profileGroup() : 0)
</span><del>-    , m_debuggerPausedTimestamp(NAN)
</del><ins>+    , m_stopwatch(stopwatch)
</ins><span class="cx">     , m_foundConsoleStartParent(false)
</span><span class="cx">     , m_suspended(false)
</span><span class="cx"> {
</span><del>-    if (Debugger* debugger = exec-&gt;lexicalGlobalObject()-&gt;debugger())
-        m_debuggerPausedTimestamp = debugger-&gt;isPaused() ? currentTime() : NAN;
-
</del><span class="cx">     m_profile = Profile::create(title, uid);
</span><span class="cx">     m_currentNode = m_rootNode = m_profile-&gt;rootNode();
</span><span class="cx">     if (exec)
</span><span class="lines">@@ -118,13 +114,8 @@
</span><span class="cx">     ASSERT_ARG(node, node);
</span><span class="cx"> 
</span><span class="cx">     if (isnan(startTime))
</span><del>-        startTime = currentTime();
</del><ins>+        startTime = m_stopwatch-&gt;elapsedTime();
</ins><span class="cx"> 
</span><del>-    // If the debugger is paused when beginning, then don't set the start time. It
-    // will be fixed up when the debugger unpauses or the call entry ends.
-    if (!isnan(m_debuggerPausedTimestamp))
-        startTime = NAN;
-
</del><span class="cx">     node-&gt;appendCall(ProfileNode::Call(startTime));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -133,22 +124,8 @@
</span><span class="cx">     ASSERT_ARG(node, node);
</span><span class="cx"> 
</span><span class="cx">     ProfileNode::Call&amp; last = node-&gt;lastCall();
</span><del>-
-    // If the debugger is paused, ignore the interval that ends now.
-    if (!isnan(m_debuggerPausedTimestamp) &amp;&amp; !isnan(last.elapsedTime()))
-        return;
-
-    // If paused and no time was accrued then the debugger was never unpaused. The call will
-    // have no time accrued and appear to have started when the debugger was paused.
-    if (!isnan(m_debuggerPausedTimestamp)) {
-        last.setStartTime(m_debuggerPausedTimestamp);
-        last.setElapsedTime(0.0);
-        return;
-    }
-
-    // Otherwise, add the interval ending now to elapsed time.
</del><span class="cx">     double previousElapsedTime = isnan(last.elapsedTime()) ? 0.0 : last.elapsedTime();
</span><del>-    double newlyElapsedTime = currentTime() - last.startTime();
</del><ins>+    double newlyElapsedTime = m_stopwatch-&gt;elapsedTime() - last.startTime();
</ins><span class="cx">     last.setElapsedTime(previousElapsedTime + newlyElapsedTime);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -223,33 +200,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ProfileGenerator::didPause(PassRefPtr&lt;DebuggerCallFrame&gt;, const CallIdentifier&amp;)
-{
-    ASSERT(isnan(m_debuggerPausedTimestamp));
-
-    m_debuggerPausedTimestamp = currentTime();
-
-    for (ProfileNode* node = m_currentNode.get(); node != m_profile-&gt;rootNode(); node = node-&gt;parent()) {
-        ProfileNode::Call&amp; last = node-&gt;lastCall();
-        ASSERT(!isnan(last.startTime()));
-
-        double previousElapsedTime = isnan(last.elapsedTime()) ? 0.0 : last.elapsedTime();
-        double additionalElapsedTime = m_debuggerPausedTimestamp - last.startTime();
-        last.setStartTime(NAN);
-        last.setElapsedTime(previousElapsedTime + additionalElapsedTime);
-    }
-}
-
-void ProfileGenerator::didContinue(PassRefPtr&lt;DebuggerCallFrame&gt;, const CallIdentifier&amp;)
-{
-    ASSERT(!isnan(m_debuggerPausedTimestamp));
-
-    for (ProfileNode* node = m_currentNode.get(); node != m_profile-&gt;rootNode(); node = node-&gt;parent())
-        node-&gt;lastCall().setStartTime(m_debuggerPausedTimestamp);
-
-    m_debuggerPausedTimestamp = NAN;
-}
-
</del><span class="cx"> void ProfileGenerator::stopProfiling()
</span><span class="cx"> {
</span><span class="cx">     for (ProfileNode* node = m_currentNode.get(); node != m_profile-&gt;rootNode(); node = node-&gt;parent())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerProfileGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><ins>+#include &lt;wtf/Stopwatch.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -42,7 +43,7 @@
</span><span class="cx"> 
</span><span class="cx">     class ProfileGenerator : public RefCounted&lt;ProfileGenerator&gt;  {
</span><span class="cx">     public:
</span><del>-        static PassRefPtr&lt;ProfileGenerator&gt; create(ExecState*, const WTF::String&amp; title, unsigned uid);
</del><ins>+        static PassRefPtr&lt;ProfileGenerator&gt; create(ExecState*, const WTF::String&amp; title, unsigned uid, PassRefPtr&lt;Stopwatch&gt;);
</ins><span class="cx"> 
</span><span class="cx">         // Members
</span><span class="cx">         const WTF::String&amp; title() const;
</span><span class="lines">@@ -54,15 +55,12 @@
</span><span class="cx">         void didExecute(ExecState* callerCallFrame, const CallIdentifier&amp;);
</span><span class="cx">         void exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&amp;);
</span><span class="cx"> 
</span><del>-        void didPause(PassRefPtr&lt;DebuggerCallFrame&gt;, const CallIdentifier&amp;);
-        void didContinue(PassRefPtr&lt;DebuggerCallFrame&gt;, const CallIdentifier&amp;);
-
</del><span class="cx">         void setIsSuspended(bool suspended) { ASSERT(m_suspended != suspended); m_suspended = suspended; }
</span><span class="cx"> 
</span><span class="cx">         void stopProfiling();
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        ProfileGenerator(ExecState*, const WTF::String&amp; title, unsigned uid);
</del><ins>+        ProfileGenerator(ExecState*, const WTF::String&amp; title, unsigned uid, PassRefPtr&lt;Stopwatch&gt;);
</ins><span class="cx">         void addParentForConsoleStart(ExecState*);
</span><span class="cx"> 
</span><span class="cx">         void removeProfileStart();
</span><span class="lines">@@ -74,8 +72,7 @@
</span><span class="cx">         RefPtr&lt;Profile&gt; m_profile;
</span><span class="cx">         JSGlobalObject* m_origin;
</span><span class="cx">         unsigned m_profileGroup;
</span><del>-        // Timestamp is set to NAN when the debugger is not currently paused.
-        double m_debuggerPausedTimestamp;
</del><ins>+        RefPtr&lt;Stopwatch&gt; m_stopwatch;
</ins><span class="cx">         RefPtr&lt;ProfileNode&gt; m_rootNode;
</span><span class="cx">         RefPtr&lt;ProfileNode&gt; m_currentNode;
</span><span class="cx">         bool m_foundConsoleStartParent;
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WTF/ChangeLog        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2014-10-04  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Reviewed by Timothy Hatcher.
+
+        * WTF.vcxproj/WTF.vcxproj:
+        * WTF.vcxproj/WTF.vcxproj.filters:
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/CMakeLists.txt:
+        * wtf/Stopwatch.h: Added. This implements a refcounted monotonic stopwatch.
+        (WTF::Stopwatch::reset):
+        (WTF::Stopwatch::start):
+        (WTF::Stopwatch::stop):
+
</ins><span class="cx"> 2014-10-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         FTL should sink PutLocals
</span></span></pre></div>
<a id="trunkSourceWTFWTFvcxprojWTFvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -269,6 +269,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StackBounds.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StaticConstructors.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StdLibExtras.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\wtf\Stopwatch.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StringExtras.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StringHasher.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StringPrintStream.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWTFWTFvcxprojWTFvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -609,6 +609,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StdLibExtras.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;wtf&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\wtf\Stopwatch.h&quot;&gt;
+      &lt;Filter&gt;wtf&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\wtf\StringExtras.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;wtf&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceWTFWTFxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -272,6 +272,7 @@
</span><span class="cx">                 A8A47487151A825B004123FF /* WTFThreadData.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4737B151A825B004123FF /* WTFThreadData.h */; };
</span><span class="cx">                 A8A4748C151A8264004123FF /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4748B151A8264004123FF /* config.h */; };
</span><span class="cx">                 B38FD7BD168953E80065C969 /* FeatureDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = B38FD7BC168953E80065C969 /* FeatureDefines.h */; };
</span><ins>+                C4F8A93719C65EB400B2B15D /* Stopwatch.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F8A93619C65EB400B2B15D /* Stopwatch.h */; };
</ins><span class="cx">                 CD5497AC15857D0300B5BC30 /* MediaTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5497AA15857D0300B5BC30 /* MediaTime.cpp */; };
</span><span class="cx">                 CD5497AD15857D0300B5BC30 /* MediaTime.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5497AB15857D0300B5BC30 /* MediaTime.h */; };
</span><span class="cx">                 CE46516E19DB1FB4003ECA05 /* NSMapTableSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE46516D19DB1FB4003ECA05 /* NSMapTableSPI.h */; };
</span><span class="lines">@@ -564,6 +565,7 @@
</span><span class="cx">                 A8A4737B151A825B004123FF /* WTFThreadData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFThreadData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A8A4748B151A8264004123FF /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B38FD7BC168953E80065C969 /* FeatureDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeatureDefines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                C4F8A93619C65EB400B2B15D /* Stopwatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stopwatch.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CD5497AA15857D0300B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD5497AB15857D0300B5BC30 /* MediaTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaTime.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CE46516D19DB1FB4003ECA05 /* NSMapTableSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSMapTableSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -856,6 +858,7 @@
</span><span class="cx">                                 FEDACD3C1630F83F00C69634 /* StackStats.h */,
</span><span class="cx">                                 A8A47310151A825B004123FF /* StaticConstructors.h */,
</span><span class="cx">                                 A8A47311151A825B004123FF /* StdLibExtras.h */,
</span><ins>+                                C4F8A93619C65EB400B2B15D /* Stopwatch.h */,
</ins><span class="cx">                                 1A6BB768162F300500DD16DB /* StreamBuffer.h */,
</span><span class="cx">                                 A8A47313151A825B004123FF /* StringExtras.h */,
</span><span class="cx">                                 A748745117A0BDAE00FA04CB /* StringHashDumpContext.h */,
</span><span class="lines">@@ -1075,6 +1078,7 @@
</span><span class="cx">                                 A8A473A3151A825B004123FF /* DecimalNumber.h in Headers */,
</span><span class="cx">                                 0F2B66A617B6B4FB00A7AE3F /* DeferrableRefCounted.h in Headers */,
</span><span class="cx">                                 A8A473A5151A825B004123FF /* Deque.h in Headers */,
</span><ins>+                                C4F8A93719C65EB400B2B15D /* Stopwatch.h in Headers */,
</ins><span class="cx">                                 A8A473A6151A825B004123FF /* DisallowCType.h in Headers */,
</span><span class="cx">                                 A8A473AF151A825B004123FF /* diy-fp.h in Headers */,
</span><span class="cx">                                 A8A473B1151A825B004123FF /* double-conversion.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWTFwtfCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/CMakeLists.txt (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/CMakeLists.txt        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WTF/wtf/CMakeLists.txt        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -92,6 +92,7 @@
</span><span class="cx">     StackStats.h
</span><span class="cx">     StaticConstructors.h
</span><span class="cx">     StdLibExtras.h
</span><ins>+    Stopwatch.h
</ins><span class="cx">     StringExtras.h
</span><span class="cx">     StringHasher.h
</span><span class="cx">     StringPrintStream.h
</span></span></pre></div>
<a id="trunkSourceWTFwtfStopwatchh"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/Stopwatch.h (0 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Stopwatch.h                                (rev 0)
+++ trunk/Source/WTF/wtf/Stopwatch.h        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+/*
+ * Copyright (C) 2014 University of Washington. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Stopwatch_h
+#define Stopwatch_h
+
+#include &lt;cmath&gt;
+#include &lt;wtf/CurrentTime.h&gt;
+#include &lt;wtf/RefCounted.h&gt;
+
+namespace WTF {
+
+class Stopwatch : public RefCounted&lt;Stopwatch&gt; {
+public:
+    static PassRefPtr&lt;Stopwatch&gt; create()
+    {
+        return adoptRef(new Stopwatch());
+    }
+
+    void reset();
+    void start();
+    void stop();
+
+    double elapsedTime();
+
+private:
+    Stopwatch()
+        : m_elapsedTime(NAN)
+        , m_lastStartTime(NAN)
+    {
+    }
+
+    double m_elapsedTime;
+    double m_lastStartTime;
+};
+
+inline void Stopwatch::reset()
+{
+    m_elapsedTime = 0.0;
+    m_lastStartTime = NAN;
+}
+
+inline void Stopwatch::start()
+{
+    ASSERT(!isnan(m_elapsedTime) &amp;&amp; isnan(m_lastStartTime));
+
+    m_lastStartTime = monotonicallyIncreasingTime();
+}
+
+inline void Stopwatch::stop()
+{
+    ASSERT(!isnan(m_elapsedTime) &amp;&amp; !isnan(m_lastStartTime));
+
+    m_elapsedTime += monotonicallyIncreasingTime() - m_lastStartTime;
+    m_lastStartTime = NAN;
+}
+
+inline double Stopwatch::elapsedTime()
+{
+    bool shouldSuspend = !isnan(m_lastStartTime);
+    if (shouldSuspend)
+        stop();
+
+    ASSERT(!isnan(m_elapsedTime) &amp;&amp; isnan(m_lastStartTime));
+    double elapsedTime = m_elapsedTime;
+
+    if (shouldSuspend)
+        start();
+    return elapsedTime;
+}
+
+} // namespace WTF
+
+using WTF::Stopwatch;
+
+#endif // Stopwatch_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/ChangeLog        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -1,3 +1,66 @@
</span><ins>+2014-10-04  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Reviewed by Timothy Hatcher.
+
+        To avoid counting time elapsed while the debugger is paused, timeline records should
+        keep track of time elapsed since the start of timeline capturing, rather than wall clock
+        timestamps. We can easily compute elapsed time by sharing Stopwatch instance among
+        all timeline record-generating code. The stopwatch is paused while the debugger is paused,
+        so subsequent time measurements will not include time elapsed while the debugger is paused.
+
+        Agents use the shared stopwatch to generate timestamps if the timeline agent is active
+        (i.e., a timeline recording is being captured). If not, use a zero timestamp since the timing data is only revealed through the Timeline interface.
+
+        This refactoring is safe because start and end times are only used to graph records; the
+        timestamp's actual value is irrelevant and is not displayed in the user interface. Date
+        timestamps are still included with network-related records as part of their header data.
+
+        No new tests, because we cannot reliably test timing changes induced by debugger pauses.
+        It is possible for records to accrue time before the debugger pauses or after it resumes.
+
+        * inspector/InspectorCSSAgent.cpp: Remove unused include.
+        * inspector/InspectorPageAgent.cpp: Use timestamps from the shared stopwatch.
+        (WebCore::InspectorPageAgent::timestamp):
+        (WebCore::InspectorPageAgent::domContentEventFired):
+        (WebCore::InspectorPageAgent::loadEventFired):
+        * inspector/InspectorPageAgent.h:
+        * inspector/InspectorResourceAgent.cpp: Use timestamps from the shared stopwatch.
+        (WebCore::InspectorResourceAgent::timestamp):
+        (WebCore::InspectorResourceAgent::willSendRequest):
+        (WebCore::InspectorResourceAgent::didReceiveResponse):
+        (WebCore::InspectorResourceAgent::didReceiveData):
+        (WebCore::InspectorResourceAgent::didFinishLoading):
+        (WebCore::InspectorResourceAgent::didFailLoading):
+        (WebCore::InspectorResourceAgent::didLoadResourceFromMemoryCache):
+        (WebCore::InspectorResourceAgent::willSendWebSocketHandshakeRequest):
+        (WebCore::InspectorResourceAgent::didReceiveWebSocketHandshakeResponse):
+        (WebCore::InspectorResourceAgent::didCloseWebSocket):
+        (WebCore::InspectorResourceAgent::didReceiveWebSocketFrame):
+        (WebCore::InspectorResourceAgent::didSendWebSocketFrame):
+        (WebCore::InspectorResourceAgent::didReceiveWebSocketFrameError):
+        * inspector/InspectorResourceAgent.h:
+        * inspector/InspectorTimelineAgent.cpp: Add calls to reset, start, and stop the stopwatch.
+        (WebCore::InspectorTimelineAgent::didCreateFrontendAndBackend):
+        (WebCore::InspectorTimelineAgent::internalStart):
+        (WebCore::InspectorTimelineAgent::internalStop):
+        (WebCore::startProfiling):
+        (WebCore::InspectorTimelineAgent::startFromConsole):
+        (WebCore::InspectorTimelineAgent::willCallFunction):
+        (WebCore::InspectorTimelineAgent::willEvaluateScript):
+        (WebCore::InspectorTimelineAgent::didPause):
+        (WebCore::InspectorTimelineAgent::didContinue):
+        (WebCore::InspectorTimelineAgent::InspectorTimelineAgent):
+        (WebCore::InspectorTimelineAgent::timestamp):
+        (WebCore::TimelineTimeConverter::reset): Deleted.
+        * inspector/InspectorTimelineAgent.h: Make timestamp() public, and remove old timepieces.
+        (WebCore::TimelineTimeConverter::TimelineTimeConverter): Deleted.
+        (WebCore::TimelineTimeConverter::fromMonotonicallyIncreasingTime): Deleted.
+        (WebCore::InspectorTimelineAgent::timeConverter): Deleted.
+        * inspector/TimelineRecordFactory.cpp:
+
</ins><span class="cx"> 2014-10-04  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make it possible to test page overlays
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorCSSAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -57,7 +57,6 @@
</span><span class="cx"> #include &quot;StyleSheetList.h&quot;
</span><span class="cx"> #include &quot;WebKitNamedFlow.h&quot;
</span><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><del>-#include &lt;wtf/CurrentTime.h&gt;
</del><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/Ref.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorPageAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorPageAgent.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorPageAgent.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorPageAgent.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> #include &quot;InspectorDOMAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorInstrumentation.h&quot;
</span><span class="cx"> #include &quot;InspectorOverlay.h&quot;
</span><ins>+#include &quot;InspectorTimelineAgent.h&quot;
</ins><span class="cx"> #include &quot;InspectorWebFrontendDispatchers.h&quot;
</span><span class="cx"> #include &quot;InstrumentingAgents.h&quot;
</span><span class="cx"> #include &quot;MainFrame.h&quot;
</span><span class="lines">@@ -73,7 +74,6 @@
</span><span class="cx"> #include &lt;inspector/ContentSearchUtilities.h&gt;
</span><span class="cx"> #include &lt;inspector/IdentifiersFactory.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><del>-#include &lt;wtf/CurrentTime.h&gt;
</del><span class="cx"> #include &lt;wtf/ListHashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/Base64.h&gt;
</span><span class="lines">@@ -361,6 +361,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+double InspectorPageAgent::timestamp()
+{
+    // If the timeline agent is recording now, use its stopwatch. Otherwise, just report 0.0
+    // since the timestamps are only used to accurately graph records on the timeline.
+    if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents-&gt;inspectorTimelineAgent())
+        return timelineAgent-&gt;timestamp();
+
+    return 0.0;
+}
+
</ins><span class="cx"> void InspectorPageAgent::enable(ErrorString&amp;)
</span><span class="cx"> {
</span><span class="cx">     m_enabled = true;
</span><span class="lines">@@ -752,12 +762,12 @@
</span><span class="cx"> void InspectorPageAgent::domContentEventFired()
</span><span class="cx"> {
</span><span class="cx">     m_isFirstLayoutAfterOnLoad = true;
</span><del>-    m_frontendDispatcher-&gt;domContentEventFired(currentTime());
</del><ins>+    m_frontendDispatcher-&gt;domContentEventFired(timestamp());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorPageAgent::loadEventFired()
</span><span class="cx"> {
</span><del>-    m_frontendDispatcher-&gt;loadEventFired(currentTime());
</del><ins>+    m_frontendDispatcher-&gt;loadEventFired(timestamp());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorPageAgent::frameNavigated(DocumentLoader* loader)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorPageAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorPageAgent.h (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorPageAgent.h        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorPageAgent.h        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -167,6 +167,8 @@
</span><span class="cx">     void updateTouchEventEmulationInPage(bool);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    double timestamp();
+
</ins><span class="cx">     static bool mainResourceContent(Frame*, bool withBase64Encode, String* result);
</span><span class="cx">     static bool dataContent(const char* data, unsigned size, const String&amp; textEncodingName, bool withBase64Encode, String* result);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorResourceAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> #include &quot;IconController.h&quot;
</span><span class="cx"> #include &quot;InspectorClient.h&quot;
</span><span class="cx"> #include &quot;InspectorPageAgent.h&quot;
</span><ins>+#include &quot;InspectorTimelineAgent.h&quot;
</ins><span class="cx"> #include &quot;InspectorWebFrontendDispatchers.h&quot;
</span><span class="cx"> #include &quot;InstrumentingAgents.h&quot;
</span><span class="cx"> #include &quot;JSMainThreadExecState.h&quot;
</span><span class="lines">@@ -69,7 +70,6 @@
</span><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><span class="cx"> #include &lt;inspector/ScriptCallStack.h&gt;
</span><span class="cx"> #include &lt;inspector/ScriptCallStackFactory.h&gt;
</span><del>-#include &lt;wtf/CurrentTime.h&gt;
</del><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -276,6 +276,16 @@
</span><span class="cx">     ASSERT(!m_instrumentingAgents-&gt;inspectorResourceAgent());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+double InspectorResourceAgent::timestamp()
+{
+    // If the timeline agent is recording now, use its stopwatch. Otherwise, just report 0.0
+    // since the timestamps are only used to accurately graph records on the timeline.
+    if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents-&gt;inspectorTimelineAgent())
+        return timelineAgent-&gt;timestamp();
+
+    return 0.0;
+}
+
</ins><span class="cx"> void InspectorResourceAgent::willSendRequest(unsigned long identifier, DocumentLoader* loader, ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</span><span class="cx"> {
</span><span class="cx">     if (request.hiddenFromInspector()) {
</span><span class="lines">@@ -320,7 +330,7 @@
</span><span class="cx">     Inspector::Protocol::Page::ResourceType resourceType = InspectorPageAgent::resourceTypeJson(type);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;Inspector::Protocol::Network::Initiator&gt; initiatorObject = buildInitiatorObject(loader-&gt;frame() ? loader-&gt;frame()-&gt;document() : nullptr);
</span><del>-    m_frontendDispatcher-&gt;requestWillBeSent(requestId, m_pageAgent-&gt;frameId(loader-&gt;frame()), m_pageAgent-&gt;loaderId(loader), loader-&gt;url().string(), buildObjectForResourceRequest(request), currentTime(), initiatorObject, buildObjectForResourceResponse(redirectResponse, loader), type != InspectorPageAgent::OtherResource ? &amp;resourceType : nullptr);
</del><ins>+    m_frontendDispatcher-&gt;requestWillBeSent(requestId, m_pageAgent-&gt;frameId(loader-&gt;frame()), m_pageAgent-&gt;loaderId(loader), loader-&gt;url().string(), buildObjectForResourceRequest(request), timestamp(), initiatorObject, buildObjectForResourceResponse(redirectResponse, loader), type != InspectorPageAgent::OtherResource ? &amp;resourceType : nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::markResourceAsCached(unsigned long identifier)
</span><span class="lines">@@ -365,7 +375,7 @@
</span><span class="cx">     m_resourcesData-&gt;responseReceived(requestId, m_pageAgent-&gt;frameId(loader-&gt;frame()), response);
</span><span class="cx">     m_resourcesData-&gt;setResourceType(requestId, type);
</span><span class="cx"> 
</span><del>-    m_frontendDispatcher-&gt;responseReceived(requestId, m_pageAgent-&gt;frameId(loader-&gt;frame()), m_pageAgent-&gt;loaderId(loader), currentTime(), InspectorPageAgent::resourceTypeJson(type), resourceResponse);
</del><ins>+    m_frontendDispatcher-&gt;responseReceived(requestId, m_pageAgent-&gt;frameId(loader-&gt;frame()), m_pageAgent-&gt;loaderId(loader), timestamp(), InspectorPageAgent::resourceTypeJson(type), resourceResponse);
</ins><span class="cx"> 
</span><span class="cx">     // If we revalidated the resource and got Not modified, send content length following didReceiveResponse
</span><span class="cx">     // as there will be no calls to didReceiveData from the network stack.
</span><span class="lines">@@ -391,7 +401,7 @@
</span><span class="cx">             m_resourcesData-&gt;maybeAddResourceData(requestId, data, dataLength);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_frontendDispatcher-&gt;dataReceived(requestId, currentTime(), dataLength, encodedDataLength);
</del><ins>+    m_frontendDispatcher-&gt;dataReceived(requestId, timestamp(), dataLength, encodedDataLength);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double finishTime)
</span><span class="lines">@@ -411,7 +421,7 @@
</span><span class="cx">     // However, all other times passed to the Inspector are generated from the web process. Mixing
</span><span class="cx">     // times from different processes can cause the finish time to be earlier than the response
</span><span class="cx">     // received time due to inter-process communication lag.
</span><del>-    finishTime = currentTime();
</del><ins>+    finishTime = timestamp();
</ins><span class="cx"> 
</span><span class="cx">     String sourceMappingURL;
</span><span class="cx">     NetworkResourcesData::ResourceData const* resourceData = m_resourcesData-&gt;data(requestId);
</span><span class="lines">@@ -437,7 +447,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool canceled = error.isCancellation();
</span><del>-    m_frontendDispatcher-&gt;loadingFailed(requestId, currentTime(), error.localizedDescription(), canceled ? &amp;canceled : nullptr);
</del><ins>+    m_frontendDispatcher-&gt;loadingFailed(requestId, timestamp(), error.localizedDescription(), canceled ? &amp;canceled : nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* loader, CachedResource* resource)
</span><span class="lines">@@ -456,7 +466,7 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;Inspector::Protocol::Network::Initiator&gt; initiatorObject = buildInitiatorObject(loader-&gt;frame() ? loader-&gt;frame()-&gt;document() : nullptr);
</span><span class="cx"> 
</span><del>-    m_frontendDispatcher-&gt;requestServedFromMemoryCache(requestId, frameId, loaderId, loader-&gt;url().string(), currentTime(), initiatorObject, buildObjectForCachedResource(resource, loader));
</del><ins>+    m_frontendDispatcher-&gt;requestServedFromMemoryCache(requestId, frameId, loaderId, loader-&gt;url().string(), timestamp(), initiatorObject, buildObjectForCachedResource(resource, loader));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::setInitialScriptContent(unsigned long identifier, const String&amp; sourceString)
</span><span class="lines">@@ -588,7 +598,7 @@
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Inspector::Protocol::Network::WebSocketRequest&gt; requestObject = Inspector::Protocol::Network::WebSocketRequest::create()
</span><span class="cx">         .setHeaders(buildObjectForHeaders(request.httpHeaderFields()));
</span><del>-    m_frontendDispatcher-&gt;webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), currentTime(), requestObject);
</del><ins>+    m_frontendDispatcher-&gt;webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), requestObject);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse&amp; response)
</span><span class="lines">@@ -597,12 +607,12 @@
</span><span class="cx">         .setStatus(response.httpStatusCode())
</span><span class="cx">         .setStatusText(response.httpStatusText())
</span><span class="cx">         .setHeaders(buildObjectForHeaders(response.httpHeaderFields()));
</span><del>-    m_frontendDispatcher-&gt;webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), currentTime(), responseObject);
</del><ins>+    m_frontendDispatcher-&gt;webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), timestamp(), responseObject);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didCloseWebSocket(unsigned long identifier)
</span><span class="cx"> {
</span><del>-    m_frontendDispatcher-&gt;webSocketClosed(IdentifiersFactory::requestId(identifier), currentTime());
</del><ins>+    m_frontendDispatcher-&gt;webSocketClosed(IdentifiersFactory::requestId(identifier), timestamp());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame&amp; frame)
</span><span class="lines">@@ -611,7 +621,7 @@
</span><span class="cx">         .setOpcode(frame.opCode)
</span><span class="cx">         .setMask(frame.masked)
</span><span class="cx">         .setPayloadData(String(frame.payload, frame.payloadLength));
</span><del>-    m_frontendDispatcher-&gt;webSocketFrameReceived(IdentifiersFactory::requestId(identifier), currentTime(), frameObject);
</del><ins>+    m_frontendDispatcher-&gt;webSocketFrameReceived(IdentifiersFactory::requestId(identifier), timestamp(), frameObject);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame&amp; frame)
</span><span class="lines">@@ -620,12 +630,12 @@
</span><span class="cx">         .setOpcode(frame.opCode)
</span><span class="cx">         .setMask(frame.masked)
</span><span class="cx">         .setPayloadData(String(frame.payload, frame.payloadLength));
</span><del>-    m_frontendDispatcher-&gt;webSocketFrameSent(IdentifiersFactory::requestId(identifier), currentTime(), frameObject);
</del><ins>+    m_frontendDispatcher-&gt;webSocketFrameSent(IdentifiersFactory::requestId(identifier), timestamp(), frameObject);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorResourceAgent::didReceiveWebSocketFrameError(unsigned long identifier, const String&amp; errorMessage)
</span><span class="cx"> {
</span><del>-    m_frontendDispatcher-&gt;webSocketFrameError(IdentifiersFactory::requestId(identifier), currentTime(), errorMessage);
</del><ins>+    m_frontendDispatcher-&gt;webSocketFrameError(IdentifiersFactory::requestId(identifier), timestamp(), errorMessage);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEB_SOCKETS)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorResourceAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorResourceAgent.h (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorResourceAgent.h        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.h        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -138,6 +138,8 @@
</span><span class="cx"> private:
</span><span class="cx">     void enable();
</span><span class="cx"> 
</span><ins>+    double timestamp();
+
</ins><span class="cx">     InspectorPageAgent* m_pageAgent;
</span><span class="cx">     InspectorClient* m_client;
</span><span class="cx">     std::unique_ptr&lt;Inspector::InspectorNetworkFrontendDispatcher&gt; m_frontendDispatcher;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -61,11 +61,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-void TimelineTimeConverter::reset()
-{
-    m_startOffset = monotonicallyIncreasingTime() - currentTime();
-}
-
</del><span class="cx"> InspectorTimelineAgent::~InspectorTimelineAgent()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -76,6 +71,7 @@
</span><span class="cx">     m_backendDispatcher = InspectorTimelineBackendDispatcher::create(backendDispatcher, this);
</span><span class="cx"> 
</span><span class="cx">     m_instrumentingAgents-&gt;setPersistentInspectorTimelineAgent(this);
</span><ins>+    m_stopwatch-&gt;reset();
</ins><span class="cx"> 
</span><span class="cx">     if (m_scriptDebugServer)
</span><span class="cx">         m_scriptDebugServer-&gt;recompileAllJSFunctions();
</span><span class="lines">@@ -118,7 +114,7 @@
</span><span class="cx">     else
</span><span class="cx">         m_maxCallStackDepth = 5;
</span><span class="cx"> 
</span><del>-    m_timeConverter.reset();
</del><ins>+    m_stopwatch-&gt;start();
</ins><span class="cx"> 
</span><span class="cx">     m_instrumentingAgents-&gt;setInspectorTimelineAgent(this);
</span><span class="cx"> 
</span><span class="lines">@@ -136,6 +132,8 @@
</span><span class="cx">     if (!m_enabled)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    m_stopwatch-&gt;stop();
+
</ins><span class="cx">     m_instrumentingAgents-&gt;setInspectorTimelineAgent(nullptr);
</span><span class="cx"> 
</span><span class="cx">     if (m_scriptDebugServer)
</span><span class="lines">@@ -157,9 +155,9 @@
</span><span class="cx">     m_scriptDebugServer = scriptDebugServer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline void startProfiling(JSC::ExecState* exec, const String&amp; title)
</del><ins>+static inline void startProfiling(JSC::ExecState* exec, const String&amp; title, PassRefPtr&lt;Stopwatch&gt; stopwatch)
</ins><span class="cx"> {
</span><del>-    JSC::LegacyProfiler::profiler()-&gt;startProfiling(exec, title);
</del><ins>+    JSC::LegacyProfiler::profiler()-&gt;startProfiling(exec, title, stopwatch);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline PassRefPtr&lt;JSC::Profile&gt; stopProfiling(JSC::ExecState* exec, const String&amp; title)
</span><span class="lines">@@ -167,9 +165,9 @@
</span><span class="cx">     return JSC::LegacyProfiler::profiler()-&gt;stopProfiling(exec, title);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline void startProfiling(Frame* frame, const String&amp; title)
</del><ins>+static inline void startProfiling(Frame* frame, const String&amp; title, PassRefPtr&lt;Stopwatch&gt; stopwatch)
</ins><span class="cx"> {
</span><del>-    startProfiling(toJSDOMWindow(frame, debuggerWorld())-&gt;globalExec(), title);
</del><ins>+    startProfiling(toJSDOMWindow(frame, debuggerWorld())-&gt;globalExec(), title, stopwatch);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline PassRefPtr&lt;JSC::Profile&gt; stopProfiling(Frame* frame, const String&amp; title)
</span><span class="lines">@@ -193,7 +191,7 @@
</span><span class="cx">     if (!m_enabled &amp;&amp; m_pendingConsoleProfileRecords.isEmpty())
</span><span class="cx">         internalStart();
</span><span class="cx"> 
</span><del>-    startProfiling(exec, title);
</del><ins>+    startProfiling(exec, title, m_stopwatch);
</ins><span class="cx"> 
</span><span class="cx">     m_pendingConsoleProfileRecords.append(createRecordEntry(TimelineRecordFactory::createConsoleProfileData(title), TimelineRecordType::ConsoleProfile, true, frameFromExecState(exec)));
</span><span class="cx"> }
</span><span class="lines">@@ -232,7 +230,7 @@
</span><span class="cx">     pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frame);
</span><span class="cx"> 
</span><span class="cx">     if (frame &amp;&amp; !m_callStackDepth)
</span><del>-        startProfiling(frame, ASCIILiteral(&quot;Timeline FunctionCall&quot;));
</del><ins>+        startProfiling(frame, ASCIILiteral(&quot;Timeline FunctionCall&quot;), m_stopwatch);
</ins><span class="cx"> 
</span><span class="cx">     ++m_callStackDepth;
</span><span class="cx"> }
</span><span class="lines">@@ -407,7 +405,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (frame &amp;&amp; !m_callStackDepth) {
</span><span class="cx">         ++m_callStackDepth;
</span><del>-        startProfiling(frame, ASCIILiteral(&quot;Timeline EvaluateScript&quot;));
</del><ins>+        startProfiling(frame, ASCIILiteral(&quot;Timeline EvaluateScript&quot;), m_stopwatch);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -554,6 +552,16 @@
</span><span class="cx">     appendRecord(TimelineRecordFactory::createProbeSampleData(action, hitCount), TimelineRecordType::ProbeSample, false, frameFromExecState(exec));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InspectorTimelineAgent::didPause(JSC::ExecState*, const Deprecated::ScriptValue&amp;, const Deprecated::ScriptValue&amp;)
+{
+    m_stopwatch-&gt;stop();
+}
+
+void InspectorTimelineAgent::didContinue()
+{
+    m_stopwatch-&gt;start();
+}
+
</ins><span class="cx"> static Inspector::Protocol::Timeline::EventType toProtocol(TimelineRecordType type)
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><span class="lines">@@ -690,6 +698,7 @@
</span><span class="cx">     : InspectorAgentBase(ASCIILiteral(&quot;Timeline&quot;), instrumentingAgents)
</span><span class="cx">     , m_pageAgent(pageAgent)
</span><span class="cx">     , m_scriptDebugServer(nullptr)
</span><ins>+    , m_stopwatch(Stopwatch::create())
</ins><span class="cx">     , m_id(1)
</span><span class="cx">     , m_callStackDepth(0)
</span><span class="cx">     , m_maxCallStackDepth(5)
</span><span class="lines">@@ -748,7 +757,7 @@
</span><span class="cx"> 
</span><span class="cx"> double InspectorTimelineAgent::timestamp()
</span><span class="cx"> {
</span><del>-    return m_timeConverter.fromMonotonicallyIncreasingTime(monotonicallyIncreasingTime());
</del><ins>+    return m_stopwatch-&gt;elapsedTime();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Page* InspectorTimelineAgent::page()
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;LayoutRect.h&quot;
</span><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><span class="cx"> #include &lt;inspector/ScriptDebugListener.h&gt;
</span><ins>+#include &lt;wtf/Stopwatch.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/WeakPtr.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -113,19 +114,6 @@
</span><span class="cx">     WebSocketDestroy
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class TimelineTimeConverter {
-public:
-    TimelineTimeConverter()
-        : m_startOffset(0)
-    {
-    }
-    double fromMonotonicallyIncreasingTime(double time) const  { return (time - m_startOffset) * 1000.0; }
-    void reset();
-
-private:
-    double m_startOffset;
-};
-
</del><span class="cx"> class InspectorTimelineAgent
</span><span class="cx">     : public InspectorAgentBase
</span><span class="cx">     , public Inspector::InspectorTimelineBackendDispatcherHandler
</span><span class="lines">@@ -210,6 +198,10 @@
</span><span class="cx">     void willFireAnimationFrame(int callbackId, Frame*);
</span><span class="cx">     void didFireAnimationFrame();
</span><span class="cx"> 
</span><ins>+    // Returns the elapsed time from a monotonic stopwatch that starts with timeline recording and
+    // pauses when the debugger pauses or execution is otherwise suspended.
+    double timestamp();
+
</ins><span class="cx"> #if ENABLE(WEB_SOCKETS)
</span><span class="cx">     void didCreateWebSocket(unsigned long identifier, const URL&amp;, const String&amp; protocol, Frame*);
</span><span class="cx">     void willSendWebSocketHandshakeRequest(unsigned long identifier, Frame*);
</span><span class="lines">@@ -218,11 +210,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    // ScriptDebugListener. This is only used to create records for probe samples.
</del><ins>+    // ScriptDebugListener
</ins><span class="cx">     virtual void didParseSource(JSC::SourceID, const Script&amp;) override { }
</span><span class="cx">     virtual void failedToParseSource(const String&amp;, const String&amp;, int, int, const String&amp;) override { }
</span><del>-    virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue&amp;, const Deprecated::ScriptValue&amp;) override { }
-    virtual void didContinue() override { }
</del><ins>+    virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue&amp;, const Deprecated::ScriptValue&amp;) override;
+    virtual void didContinue() override;
</ins><span class="cx"> 
</span><span class="cx">     virtual void breakpointActionLog(JSC::ExecState*, const String&amp;) override { }
</span><span class="cx">     virtual void breakpointActionSound(int) override { }
</span><span class="lines">@@ -264,17 +256,15 @@
</span><span class="cx">     void clearRecordStack();
</span><span class="cx"> 
</span><span class="cx">     void localToPageQuad(const RenderObject&amp;, const LayoutRect&amp;, FloatQuad*);
</span><del>-    const TimelineTimeConverter&amp; timeConverter() const { return m_timeConverter; }
-    double timestamp();
</del><span class="cx">     Page* page();
</span><span class="cx"> 
</span><span class="cx">     InspectorPageAgent* m_pageAgent;
</span><span class="cx">     PageScriptDebugServer* m_scriptDebugServer;
</span><del>-    TimelineTimeConverter m_timeConverter;
</del><span class="cx"> 
</span><ins>+    RefPtr&lt;Stopwatch&gt; m_stopwatch;
+
</ins><span class="cx">     std::unique_ptr&lt;Inspector::InspectorTimelineFrontendDispatcher&gt; m_frontendDispatcher;
</span><span class="cx">     RefPtr&lt;Inspector::InspectorTimelineBackendDispatcher&gt; m_backendDispatcher;
</span><del>-    double m_timestampOffset;
</del><span class="cx"> 
</span><span class="cx">     Vector&lt;TimelineRecordEntry&gt; m_recordStack;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorTimelineRecordFactorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -47,7 +47,6 @@
</span><span class="cx"> #include &lt;inspector/ScriptCallStack.h&gt;
</span><span class="cx"> #include &lt;inspector/ScriptCallStackFactory.h&gt;
</span><span class="cx"> #include &lt;profiler/Profile.h&gt;
</span><del>-#include &lt;wtf/CurrentTime.h&gt;
</del><span class="cx"> 
</span><span class="cx"> using namespace Inspector;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2014-10-04  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
+
+        Web Inspector: timelines should not count time elapsed while paused in the debugger
+        https://bugs.webkit.org/show_bug.cgi?id=136351
+
+        Reviewed by Timothy Hatcher.
+
+        Don't update the timeline's current time when the debugger is paused.
+
+        Start and end times for timeline records are now in seconds elapsed since timeline
+        recording started, rather than milliseconds since the epoch. Add a workaround to
+        preserve compatibility with old backends.
+
+        * UserInterface/Controllers/TimelineManager.js:
+        (WebInspector.TimelineManager.prototype.capturingStarted):
+        (WebInspector.TimelineManager.prototype.eventRecorded.processRecord):
+        (WebInspector.TimelineManager.prototype.eventRecorded):
+        * UserInterface/Views/TimelineContentView.js:
+        (WebInspector.TimelineContentView.prototype._debuggerPaused):
+        (WebInspector.TimelineContentView.prototype._debuggerResumed):
+
</ins><span class="cx"> 2014-10-03  Saam Barati  &lt;saambarati1@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Move the computation that results in UI strings from JSC to the Web Inspector
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -35,6 +35,8 @@
</span><span class="cx">     this._activeRecording = null;
</span><span class="cx">     this._isCapturing = false;
</span><span class="cx"> 
</span><ins>+    // For legacy backends, we compute the elapsed time of records relative to this timestamp.
+    this._legacyFirstRecordTimestamp = NaN;
</ins><span class="cx">     this._nextRecordingIdentifier = 1;
</span><span class="cx"> 
</span><span class="cx">     this._boundStopCapturing = this.stopCapturing.bind(this);
</span><span class="lines">@@ -55,6 +57,7 @@
</span><span class="cx">     CapturingStopped: &quot;timeline-manager-capturing-stopped&quot;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.TimelineManager.StartTimeThresholdForLegacyRecordConversion = 28800000; // Date.parse(&quot;Jan 1, 1970&quot;)
</ins><span class="cx"> WebInspector.TimelineManager.MaximumAutoRecordDuration = 90000; // 90 seconds
</span><span class="cx"> WebInspector.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent = 10000; // 10 seconds
</span><span class="cx"> WebInspector.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly = 2000; // 2 seconds
</span><span class="lines">@@ -163,10 +166,21 @@
</span><span class="cx"> 
</span><span class="cx">         function processRecord(recordPayload, parentRecordPayload)
</span><span class="cx">         {
</span><del>-            // Convert the timestamps to seconds to match the resource timestamps.
-            var startTime = recordPayload.startTime / 1000;
-            var endTime = recordPayload.endTime / 1000;
</del><ins>+            var startTime = recordPayload.startTime;
+            var endTime = recordPayload.endTime;
</ins><span class="cx"> 
</span><ins>+            // COMPATIBILITY (iOS8): old versions use milliseconds since the epoch, rather
+            // than seconds elapsed since timeline capturing started. We approximate the latter by
+            // subtracting the start timestamp, as old versions did not use monotonic times.
+            if (isNaN(this._legacyFirstRecordTimestamp))
+                this._legacyFirstRecordTimestamp = recordPayload.startTime;
+
+            // If the record's start time sems unreasonably large, treat it as a legacy timestamp.
+            if (startTime &gt; WebInspector.StartTimeThresholdForLegacyRecordConversion) {
+                startTime = (startTime - this._legacyFirstRecordTimestamp) / 1000;
+                endTime = isNaN(endTime) ? NaN : (startTime - this._legacyFirstRecordTimestamp) / 1000;
+            }
+
</ins><span class="cx">             var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
</span><span class="cx"> 
</span><span class="cx">             var significantCallFrame = null;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js (174318 => 174319)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js        2014-10-04 17:18:25 UTC (rev 174318)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js        2014-10-04 19:18:38 UTC (rev 174319)
</span><span class="lines">@@ -98,6 +98,9 @@
</span><span class="cx">     WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
</span><span class="cx">     WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
</span><span class="cx"> 
</span><ins>+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Paused, this._debuggerPaused, this);
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed, this._debuggerResumed, this);
+
</ins><span class="cx">     this.showOverviewTimelineView();
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -407,6 +410,22 @@
</span><span class="cx">         this._stopUpdatingCurrentTime();
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    _debuggerPaused: function(event)
+    {
+        if (WebInspector.replayManager.sessionState === WebInspector.ReplayManager.SessionState.Replaying)
+            return;
+
+        this._stopUpdatingCurrentTime();
+    },
+
+    _debuggerResumed: function(event)
+    {
+        if (WebInspector.replayManager.sessionState === WebInspector.ReplayManager.SessionState.Replaying)
+            return;
+
+        this._startUpdatingCurrentTime();
+    },
+
</ins><span class="cx">     _recordingTimesUpdated: function(event)
</span><span class="cx">     {
</span><span class="cx">         if (!this._waitingToResetCurrentTime)
</span></span></pre>
</div>
</div>

</body>
</html>