<!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>[175203] 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/175203">175203</a></dd>
<dt>Author</dt> <dd>burg@cs.washington.edu</dd>
<dt>Date</dt> <dd>2014-10-25 15:05:57 -0700 (Sat, 25 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 debugger agent accounts
for suspended execution by pausing and resuming the stopwatch.

* API/JSProfilerPrivate.cpp:
(JSStartProfiling): Use a fresh stopwatch when profiling from the JSC API.
* inspector/InspectorEnvironment.h:
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
(Inspector::JSGlobalObjectInspectorController::executionStopwatch):
* inspector/JSGlobalObjectInspectorController.h:
* inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::handlePause):
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::didPause):
(Inspector::InspectorDebuggerAgent::breakpointActionProbe):
(Inspector::InspectorDebuggerAgent::didContinue):
* inspector/agents/InspectorDebuggerAgent.h:
* 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/Profile.cpp: The root node should always have a start time of 0.0.
(JSC::Profile::Profile):
* 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::AddParentForConsoleStartFunctor::operator()): The parent node of |console.profile|
should have a start time of 0.0, since it represents the starting node of profiling.

(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 a Stopwatch instance through the
inspector environment. The stopwatch runs with timelines and is paused with the debugger,
so subsequent time measurements will not include time elapsed while the debugger is paused.

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 unnecessary include.
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
(WebCore::InspectorController::executionStopwatch): Add a shared stopwatch.
* inspector/InspectorController.h:
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::timestamp): Redirect to the shared stopwatch.
(WebCore::InspectorPageAgent::domContentEventFired):
(WebCore::InspectorPageAgent::loadEventFired):
* inspector/InspectorPageAgent.h:
* inspector/InspectorResourceAgent.cpp:
(WebCore::InspectorResourceAgent::timestamp): Redirect to the shared stopwatch.
(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:
(WebCore::InspectorTimelineAgent::internalStart): Start and stop the stopwatch with timelines.
(WebCore::InspectorTimelineAgent::internalStop):
(WebCore::InspectorTimelineAgent::timestamp): Redirect to the shared stopwatch.
(WebCore::startProfiling):
(WebCore::InspectorTimelineAgent::startFromConsole):
(WebCore::InspectorTimelineAgent::willCallFunction):
(WebCore::InspectorTimelineAgent::willEvaluateScript):
(WebCore::TimelineTimeConverter::reset): Deleted.
* inspector/InspectorTimelineAgent.h:
(WebCore::TimelineTimeConverter::TimelineTimeConverter): Deleted.
(WebCore::TimelineTimeConverter::fromMonotonicallyIncreasingTime): Deleted.
(WebCore::InspectorTimelineAgent::timeConverter): Deleted.
* inspector/TimelineRecordFactory.cpp:
* inspector/WorkerInspectorController.cpp:
(WebCore::WorkerInspectorController::WorkerInspectorController):
(WebCore::WorkerInspectorController::executionStopwatch): Add a shared stopwatch.
* inspector/WorkerInspectorController.h:

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. Also convert code that
tracks page/resource load timings to use elapsed times rather than timestamps.

Add a workaround to preserve compatibility with old backends. Convert legacy timestamps
in multiple agents to elapsed times.

* UserInterface/Controllers/FrameResourceManager.js:
(WebInspector.FrameResourceManager.prototype.resourceRequestWillBeSent):
(WebInspector.FrameResourceManager.prototype.resourceRequestWasServedFromMemoryCache):
(WebInspector.FrameResourceManager.prototype.resourceRequestDidReceiveResponse):
(WebInspector.FrameResourceManager.prototype.resourceRequestDidReceiveData):
(WebInspector.FrameResourceManager.prototype.resourceRequestDidFinishLoading):
(WebInspector.FrameResourceManager.prototype.resourceRequestDidFailLoading):
(WebInspector.FrameResourceManager.prototype._addNewResourceToFrame):
* UserInterface/Controllers/ProbeManager.js:
* UserInterface/Controllers/TimelineManager.js:
(WebInspector.TimelineManager.prototype.computeElapsedTime): Forward to the active TimelineRecording.
(WebInspector.TimelineManager.prototype.eventRecorded.processRecord):
(WebInspector.TimelineManager.prototype.eventRecorded):
(WebInspector.TimelineManager.prototype.pageDidLoad):
(WebInspector.TimelineManager.prototype._loadNewRecording):
* UserInterface/Models/Probe.js:
(WebInspector.ProbeSample):
* UserInterface/Models/Resource.js:
(WebInspector.Resource.prototype.updateForRedirectResponse):
(WebInspector.Resource.prototype.updateForResponse):
(WebInspector.Resource.prototype.increaseSize):
(WebInspector.Resource.prototype.markAsFinished):
(WebInspector.Resource.prototype.markAsFailed):
(WebInspector.Resource.prototype.revertMarkAsFinished):
* UserInterface/Models/TimelineRecording.js:
(WebInspector.TimelineRecording.prototype.computeElapsedTime):
* 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::create):
(WTF::Stopwatch::Stopwatch):
(WTF::Stopwatch::reset):
(WTF::Stopwatch::start):
(WTF::Stopwatch::stop):
(WTF::Stopwatch::elapsedTime):</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="#trunkSourceJavaScriptCoreinspectorInspectorEnvironmenth">trunk/Source/JavaScriptCore/inspector/InspectorEnvironment.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh">trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptDebugServercpp">trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerLegacyProfilercpp">trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerLegacyProfilerh">trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerProfilecpp">trunk/Source/JavaScriptCore/profiler/Profile.cpp</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="#trunkSourceWebCoreinspectorInspectorControllercpp">trunk/Source/WebCore/inspector/InspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllerh">trunk/Source/WebCore/inspector/InspectorController.h</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="#trunkSourceWebCoreinspectorWorkerInspectorControllercpp">trunk/Source/WebCore/inspector/WorkerInspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorWorkerInspectorControllerh">trunk/Source/WebCore/inspector/WorkerInspectorController.h</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersFrameResourceManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersProbeManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/ProbeManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsProbejs">trunk/Source/WebInspectorUI/UserInterface/Models/Probe.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsResourcejs">trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordingjs">trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSProfilerPrivate.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/API/JSProfilerPrivate.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -34,7 +34,11 @@
</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>+    // Use an independent stopwatch for API-initiated profiling, since the user will expect it
+    // to be relative to when their command was issued.
+    RefPtr&lt;Stopwatch&gt; stopwatch = Stopwatch::create();
+    stopwatch-&gt;start();
+    LegacyProfiler::profiler()-&gt;startProfiling(toJS(ctx), title-&gt;string(), stopwatch.release());
</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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -1,3 +1,52 @@
</span><ins>+2014-10-18  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 debugger agent accounts
+        for suspended execution by pausing and resuming the stopwatch.
+
+        * API/JSProfilerPrivate.cpp:
+        (JSStartProfiling): Use a fresh stopwatch when profiling from the JSC API.
+        * inspector/InspectorEnvironment.h:
+        * inspector/JSGlobalObjectInspectorController.cpp:
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::executionStopwatch):
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/ScriptDebugServer.cpp:
+        (Inspector::ScriptDebugServer::handlePause):
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::didPause):
+        (Inspector::InspectorDebuggerAgent::breakpointActionProbe):
+        (Inspector::InspectorDebuggerAgent::didContinue):
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * 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/Profile.cpp: The root node should always have a start time of 0.0.
+        (JSC::Profile::Profile):
+        * 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::AddParentForConsoleStartFunctor::operator()): The parent node of |console.profile|
+        should have a start time of 0.0, since it represents the starting node of profiling.
+
+        (JSC::ProfileGenerator::beginCallEntry):
+        (JSC::ProfileGenerator::endCallEntry):
+        (JSC::ProfileGenerator::didPause): Deleted.
+        (JSC::ProfileGenerator::didContinue): Deleted.
+        * profiler/ProfileGenerator.h:
+
</ins><span class="cx"> 2014-10-24  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simplified IndexingType's hasAnyArrayStorage().
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorInspectorEnvironmenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/InspectorEnvironment.h (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/InspectorEnvironment.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/inspector/InspectorEnvironment.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -28,6 +28,10 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CallData.h&quot;
</span><span class="cx"> 
</span><ins>+namespace WTF {
+class Stopwatch;
+}
+
</ins><span class="cx"> namespace JSC {
</span><span class="cx"> class SourceCode;
</span><span class="cx"> }
</span><span class="lines">@@ -47,6 +51,7 @@
</span><span class="cx">     virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String&amp; scriptName, int scriptLine) = 0;
</span><span class="cx">     virtual void didCallInjectedScriptFunction(JSC::ExecState*) = 0;
</span><span class="cx">     virtual void frontendInitialized() = 0;
</span><ins>+    virtual PassRefPtr&lt;WTF::Stopwatch&gt; executionStopwatch() = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -43,6 +43,8 @@
</span><span class="cx"> #include &quot;ScriptArguments.h&quot;
</span><span class="cx"> #include &quot;ScriptCallStack.h&quot;
</span><span class="cx"> #include &quot;ScriptCallStackFactory.h&quot;
</span><ins>+#include &lt;wtf/Stopwatch.h&gt;
+
</ins><span class="cx"> #include &lt;cxxabi.h&gt;
</span><span class="cx"> #include &lt;dlfcn.h&gt;
</span><span class="cx"> #include &lt;execinfo.h&gt;
</span><span class="lines">@@ -59,6 +61,7 @@
</span><span class="cx">     : m_globalObject(globalObject)
</span><span class="cx">     , m_injectedScriptManager(std::make_unique&lt;InjectedScriptManager&gt;(*this, InjectedScriptHost::create()))
</span><span class="cx">     , m_inspectorFrontendChannel(nullptr)
</span><ins>+    , m_executionStopwatch(Stopwatch::create())
</ins><span class="cx">     , m_includeNativeCallStackWithExceptions(true)
</span><span class="cx">     , m_isAutomaticInspection(false)
</span><span class="cx"> #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
</span><span class="lines">@@ -79,6 +82,8 @@
</span><span class="cx">     m_agents.append(WTF::move(runtimeAgent));
</span><span class="cx">     m_agents.append(WTF::move(consoleAgent));
</span><span class="cx">     m_agents.append(WTF::move(debuggerAgent));
</span><ins>+
+    m_executionStopwatch-&gt;start();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSGlobalObjectInspectorController::~JSGlobalObjectInspectorController()
</span><span class="lines">@@ -213,6 +218,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PassRefPtr&lt;Stopwatch&gt; JSGlobalObjectInspectorController::executionStopwatch()
+{
+    return m_executionStopwatch;
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorJSGlobalObjectInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -38,6 +38,11 @@
</span><span class="cx"> #include &quot;AugmentableInspectorController.h&quot;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+namespace WTF {
+class Stopwatch;
+}
+
+
</ins><span class="cx"> namespace JSC {
</span><span class="cx"> class ConsoleClient;
</span><span class="cx"> class ExecState;
</span><span class="lines">@@ -89,6 +94,7 @@
</span><span class="cx">     virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String&amp;, int) override { }
</span><span class="cx">     virtual void didCallInjectedScriptFunction(JSC::ExecState*) override { }
</span><span class="cx">     virtual void frontendInitialized() override;
</span><ins>+    virtual PassRefPtr&lt;WTF::Stopwatch&gt; executionStopwatch() override;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
</span><span class="cx">     virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const override { return m_augmentingClient; } 
</span><span class="lines">@@ -109,6 +115,7 @@
</span><span class="cx">     InspectorAgentRegistry m_agents;
</span><span class="cx">     InspectorFrontendChannel* m_inspectorFrontendChannel;
</span><span class="cx">     RefPtr&lt;InspectorBackendDispatcher&gt; m_inspectorBackendDispatcher;
</span><ins>+    RefPtr&lt;WTF::Stopwatch&gt; m_executionStopwatch;
</ins><span class="cx">     bool m_includeNativeCallStackWithExceptions;
</span><span class="cx">     bool m_isAutomaticInspection;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptDebugServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</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="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;ScriptDebugServer.h&quot;
</span><span class="cx"> #include &quot;ScriptObject.h&quot;
</span><span class="cx"> #include &quot;ScriptValue.h&quot;
</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 Inspector {
</span><span class="lines">@@ -652,6 +653,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_listener)
</span><span class="cx">         m_listener-&gt;didPause();
</span><ins>+    
+    m_injectedScriptManager-&gt;inspectorEnvironment().executionStopwatch()-&gt;stop();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorDebuggerAgent::breakpointActionSound(int breakpointActionIdentifier)
</span><span class="lines">@@ -669,7 +672,7 @@
</span><span class="cx">         .setProbeId(action.identifier)
</span><span class="cx">         .setSampleId(sampleId)
</span><span class="cx">         .setBatchId(hitCount)
</span><del>-        .setTimestamp(monotonicallyIncreasingTime())
</del><ins>+        .setTimestamp(m_injectedScriptManager-&gt;inspectorEnvironment().executionStopwatch()-&gt;elapsedTime())
</ins><span class="cx">         .setPayload(payload.release());
</span><span class="cx"> 
</span><span class="cx">     m_frontendDispatcher-&gt;didSampleProbe(result.release());
</span><span class="lines">@@ -679,6 +682,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_pausedScriptState = nullptr;
</span><span class="cx">     m_currentCallStack = Deprecated::ScriptValue();
</span><ins>+    m_injectedScriptManager-&gt;inspectorEnvironment().executionStopwatch()-&gt;start();
</ins><span class="cx">     clearBreakDetails();
</span><span class="cx"> 
</span><span class="cx">     m_frontendDispatcher-&gt;resumed();
</span><span class="lines">@@ -745,7 +749,6 @@
</span><span class="cx">     m_breakAuxData = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorDebuggerAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -47,6 +47,10 @@
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringHash.h&gt;
</span><span class="cx"> 
</span><ins>+namespace WTF {
+class Stopwatch;
+}
+
</ins><span class="cx"> namespace Inspector {
</span><span class="cx"> 
</span><span class="cx"> class InjectedScript;
</span><span class="lines">@@ -163,6 +167,7 @@
</span><span class="cx">     RefPtr&lt;InspectorObject&gt; m_breakAuxData;
</span><span class="cx">     bool m_enabled;
</span><span class="cx">     bool m_javaScriptPauseScheduled;
</span><ins>+    RefPtr&lt;WTF::Stopwatch&gt; m_stopwatch;
</ins><span class="cx">     int m_nextProbeSampleId;
</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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/profiler/LegacyProfiler.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/profiler/LegacyProfiler.h        2014-10-25 22:05:57 UTC (rev 175203)
</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="trunkSourceJavaScriptCoreprofilerProfilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/Profile.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/Profile.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/profiler/Profile.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">     // FIXME: When multi-threading is supported this will be a vector and calls
</span><span class="cx">     // into the profiler will need to know which thread it is executing on.
</span><span class="cx">     m_rootNode = ProfileNode::create(nullptr, CallIdentifier(ASCIILiteral(&quot;Thread_1&quot;), String(), 0, 0), nullptr);
</span><del>-    m_rootNode-&gt;appendCall(ProfileNode::Call(currentTime()));
</del><ins>+    m_rootNode-&gt;appendCall(ProfileNode::Call(0.0));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Profile::~Profile()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerProfileGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</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">@@ -85,7 +81,9 @@
</span><span class="cx">         unsigned column = 0;
</span><span class="cx">         visitor-&gt;computeLineAndColumn(line, column);
</span><span class="cx">         m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor-&gt;callee(), visitor-&gt;sourceURL(), line, column), m_rootNode.get());
</span><del>-        m_currentNode-&gt;appendCall(ProfileNode::Call(currentTime()));
</del><ins>+        // Assume that profile times are relative to when the |console.profile| command is evaluated.
+        // This matches the logic in JSStartProfiling() and InspectorTimelineAgent::startFromConsole().
+        m_currentNode-&gt;appendCall(ProfileNode::Call(0.0));
</ins><span class="cx">         m_rootNode-&gt;spliceNode(m_currentNode.get());
</span><span class="cx"> 
</span><span class="cx">         m_foundParent = true;
</span><span class="lines">@@ -118,13 +116,8 @@
</span><span class="cx">     ASSERT_ARG(node, node);
</span><span class="cx"> 
</span><span class="cx">     if (std::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 (!std::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">@@ -134,21 +127,8 @@
</span><span class="cx"> 
</span><span class="cx">     ProfileNode::Call&amp; last = node-&gt;lastCall();
</span><span class="cx"> 
</span><del>-    // If the debugger is paused, ignore the interval that ends now.
-    if (!std::isnan(m_debuggerPausedTimestamp) &amp;&amp; !std::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 (!std::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 = std::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">@@ -180,7 +160,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_currentNode = calleeNode;
</span><del>-    beginCallEntry(calleeNode.get());
</del><ins>+    beginCallEntry(calleeNode.get(), m_stopwatch-&gt;elapsedTime());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier&amp; callIdentifier)
</span><span class="lines">@@ -223,33 +203,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(std::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(!std::isnan(last.startTime()));
-
-        double previousElapsedTime = std::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(!std::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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/JavaScriptCore/profiler/ProfileGenerator.h        2014-10-25 22:05:57 UTC (rev 175203)
</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,28 +55,24 @@
</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="cx">         void removeProfileEnd();
</span><span class="cx"> 
</span><del>-        void beginCallEntry(ProfileNode*, double startTime = NAN);
</del><ins>+        void beginCallEntry(ProfileNode*, double startTime);
</ins><span class="cx">         void endCallEntry(ProfileNode*);
</span><span class="cx"> 
</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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WTF/ChangeLog        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2014-10-18  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::create):
+        (WTF::Stopwatch::Stopwatch):
+        (WTF::Stopwatch::reset):
+        (WTF::Stopwatch::start):
+        (WTF::Stopwatch::stop):
+        (WTF::Stopwatch::elapsedTime):
+
</ins><span class="cx"> 2014-10-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Provide a way to have alternate inspector agents
</span></span></pre></div>
<a id="trunkSourceWTFWTFvcxprojWTFvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -270,6 +270,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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -614,6 +614,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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -273,6 +273,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">@@ -566,6 +567,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">@@ -858,6 +860,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">@@ -1078,6 +1081,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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/CMakeLists.txt        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WTF/wtf/CMakeLists.txt        2014-10-25 22:05:57 UTC (rev 175203)
</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 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Stopwatch.h                                (rev 0)
+++ trunk/Source/WTF/wtf/Stopwatch.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -0,0 +1,96 @@
</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(0.0)
+        , 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_lastStartTime));
+
+    m_lastStartTime = monotonicallyIncreasingTime();
+}
+
+inline void Stopwatch::stop()
+{
+    ASSERT(!isnan(m_lastStartTime));
+
+    m_elapsedTime += monotonicallyIncreasingTime() - m_lastStartTime;
+    m_lastStartTime = NAN;
+}
+
+inline double Stopwatch::elapsedTime()
+{
+    bool shouldSuspend = !isnan(m_lastStartTime);
+    if (shouldSuspend)
+        stop();
+
+    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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/ChangeLog        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2014-10-18  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 a Stopwatch instance through the
+        inspector environment. The stopwatch runs with timelines and is paused with the debugger,
+        so subsequent time measurements will not include time elapsed while the debugger is paused.
+
+        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 unnecessary include.
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        (WebCore::InspectorController::executionStopwatch): Add a shared stopwatch.
+        * inspector/InspectorController.h:
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::timestamp): Redirect to the shared stopwatch.
+        (WebCore::InspectorPageAgent::domContentEventFired):
+        (WebCore::InspectorPageAgent::loadEventFired):
+        * inspector/InspectorPageAgent.h:
+        * inspector/InspectorResourceAgent.cpp:
+        (WebCore::InspectorResourceAgent::timestamp): Redirect to the shared stopwatch.
+        (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:
+        (WebCore::InspectorTimelineAgent::internalStart): Start and stop the stopwatch with timelines.
+        (WebCore::InspectorTimelineAgent::internalStop):
+        (WebCore::InspectorTimelineAgent::timestamp): Redirect to the shared stopwatch.
+        (WebCore::startProfiling):
+        (WebCore::InspectorTimelineAgent::startFromConsole):
+        (WebCore::InspectorTimelineAgent::willCallFunction):
+        (WebCore::InspectorTimelineAgent::willEvaluateScript):
+        (WebCore::TimelineTimeConverter::reset): Deleted.
+        * inspector/InspectorTimelineAgent.h:
+        (WebCore::TimelineTimeConverter::TimelineTimeConverter): Deleted.
+        (WebCore::TimelineTimeConverter::fromMonotonicallyIncreasingTime): Deleted.
+        (WebCore::InspectorTimelineAgent::timeConverter): Deleted.
+        * inspector/TimelineRecordFactory.cpp:
+        * inspector/WorkerInspectorController.cpp:
+        (WebCore::WorkerInspectorController::WorkerInspectorController):
+        (WebCore::WorkerInspectorController::executionStopwatch): Add a shared stopwatch.
+        * inspector/WorkerInspectorController.h:
+
</ins><span class="cx"> 2014-10-25  Dan Bernstein  &lt;mitz@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix builds using the public SDK.
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorCSSAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -56,7 +56,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/InspectorProtocolObjects.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="trunkSourceWebCoreinspectorInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx"> #include &lt;inspector/agents/InspectorAgent.h&gt;
</span><span class="cx"> #include &lt;profiler/LegacyProfiler.h&gt;
</span><span class="cx"> #include &lt;runtime/JSLock.h&gt;
</span><ins>+#include &lt;wtf/Stopwatch.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(REMOTE_INSPECTOR)
</span><span class="cx"> #include &quot;PageDebuggable.h&quot;
</span><span class="lines">@@ -88,6 +89,7 @@
</span><span class="cx">     , m_injectedScriptManager(std::make_unique&lt;WebInjectedScriptManager&gt;(*this, WebInjectedScriptHost::create()))
</span><span class="cx">     , m_overlay(std::make_unique&lt;InspectorOverlay&gt;(page, inspectorClient))
</span><span class="cx">     , m_inspectorFrontendChannel(nullptr)
</span><ins>+    , m_executionStopwatch(Stopwatch::create())
</ins><span class="cx">     , m_page(page)
</span><span class="cx">     , m_inspectorClient(inspectorClient)
</span><span class="cx">     , m_inspectorFrontendClient(nullptr)
</span><span class="lines">@@ -452,6 +454,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PassRefPtr&lt;Stopwatch&gt; InspectorController::executionStopwatch()
+{
+    return m_executionStopwatch;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.h (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorController.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -130,6 +130,7 @@
</span><span class="cx">     virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String&amp; scriptName, int scriptLine) override;
</span><span class="cx">     virtual void didCallInjectedScriptFunction(JSC::ExecState*) override;
</span><span class="cx">     virtual void frontendInitialized() override;
</span><ins>+    virtual PassRefPtr&lt;WTF::Stopwatch&gt; executionStopwatch() override;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend InstrumentingAgents* instrumentationForPage(Page*);
</span><span class="lines">@@ -148,6 +149,7 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;Inspector::InspectorBackendDispatcher&gt; m_inspectorBackendDispatcher;
</span><span class="cx">     Inspector::InspectorFrontendChannel* m_inspectorFrontendChannel;
</span><ins>+    RefPtr&lt;WTF::Stopwatch&gt; m_executionStopwatch;
</ins><span class="cx">     Page&amp; m_page;
</span><span class="cx">     InspectorClient* m_inspectorClient;
</span><span class="cx">     InspectorFrontendClient* m_inspectorFrontendClient;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorPageAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorPageAgent.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorPageAgent.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorPageAgent.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</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;InstrumentingAgents.h&quot;
</span><span class="cx"> #include &quot;MainFrame.h&quot;
</span><span class="cx"> #include &quot;MemoryCache.h&quot;
</span><span class="lines">@@ -72,7 +73,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/text/Base64.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="lines">@@ -359,6 +359,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+double InspectorPageAgent::timestamp()
+{
+    return m_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch()-&gt;elapsedTime();
+}
+
</ins><span class="cx"> void InspectorPageAgent::enable(ErrorString&amp;)
</span><span class="cx"> {
</span><span class="cx">     m_enabled = true;
</span><span class="lines">@@ -709,12 +714,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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorPageAgent.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorPageAgent.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -161,6 +161,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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</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;InstrumentingAgents.h&quot;
</span><span class="cx"> #include &quot;JSMainThreadExecState.h&quot;
</span><span class="cx"> #include &quot;MemoryCache.h&quot;
</span><span class="lines">@@ -68,7 +69,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">@@ -275,6 +275,11 @@
</span><span class="cx">     ASSERT(!m_instrumentingAgents-&gt;inspectorResourceAgent());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+double InspectorResourceAgent::timestamp()
+{
+    return m_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch()-&gt;elapsedTime();
+}
+
</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">@@ -319,7 +324,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">@@ -364,7 +369,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">@@ -390,7 +395,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">@@ -410,7 +415,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">@@ -436,7 +441,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">@@ -454,7 +459,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">@@ -586,7 +591,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">@@ -595,12 +600,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">@@ -609,7 +614,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">@@ -618,12 +623,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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorResourceAgent.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.h        2014-10-25 22:05:57 UTC (rev 175203)
</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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -60,11 +60,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">@@ -117,7 +112,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_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch()-&gt;start();
</ins><span class="cx"> 
</span><span class="cx">     m_instrumentingAgents-&gt;setInspectorTimelineAgent(this);
</span><span class="cx"> 
</span><span class="lines">@@ -135,6 +130,8 @@
</span><span class="cx">     if (!m_enabled)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    m_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch()-&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">@@ -148,6 +145,11 @@
</span><span class="cx">         m_frontendDispatcher-&gt;recordingStopped();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+double InspectorTimelineAgent::timestamp()
+{
+    return m_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch()-&gt;elapsedTime();
+}
+
</ins><span class="cx"> void InspectorTimelineAgent::setPageScriptDebugServer(PageScriptDebugServer* scriptDebugServer)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_enabled);
</span><span class="lines">@@ -156,9 +158,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">@@ -166,9 +168,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">@@ -192,7 +194,11 @@
</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>+    // Use an independent stopwatch for console-initiated profiling, since the user will expect it
+    // to be relative to when their command was issued.
+    RefPtr&lt;Stopwatch&gt; profilerStopwatch = Stopwatch::create();
+    profilerStopwatch-&gt;start();
+    startProfiling(exec, title, profilerStopwatch.release());
</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">@@ -231,7 +237,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_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch());
</ins><span class="cx"> 
</span><span class="cx">     ++m_callStackDepth;
</span><span class="cx"> }
</span><span class="lines">@@ -406,7 +412,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_instrumentingAgents-&gt;inspectorEnvironment().executionStopwatch());
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -745,11 +751,6 @@
</span><span class="cx">     quad-&gt;setP4(frameView.contentsToRootView(roundedIntPoint(absolute.p4())));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-double InspectorTimelineAgent::timestamp()
-{
-    return m_timeConverter.fromMonotonicallyIncreasingTime(monotonicallyIncreasingTime());
-}
-
</del><span class="cx"> Page* InspectorTimelineAgent::page()
</span><span class="cx"> {
</span><span class="cx">     return m_pageAgent ? m_pageAgent-&gt;page() : nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorTimelineAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.h (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &lt;inspector/InspectorFrontendDispatchers.h&gt;
</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">@@ -218,7 +206,7 @@
</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><span class="cx">     virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue&amp;, const Deprecated::ScriptValue&amp;) override { }
</span><span class="lines">@@ -247,6 +235,7 @@
</span><span class="cx"> 
</span><span class="cx">     void internalStart(const int* maxCallStackDepth = nullptr);
</span><span class="cx">     void internalStop();
</span><ins>+    double timestamp();
</ins><span class="cx"> 
</span><span class="cx">     void sendEvent(PassRefPtr&lt;Inspector::InspectorObject&gt;);
</span><span class="cx">     void appendRecord(PassRefPtr&lt;Inspector::InspectorObject&gt; data, TimelineRecordType, bool captureCallStack, Frame*);
</span><span class="lines">@@ -264,17 +253,13 @@
</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><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 (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</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="trunkSourceWebCoreinspectorWorkerInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.cpp (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/WorkerInspectorController.cpp        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.cpp        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> #include &quot;WorkerThread.h&quot;
</span><span class="cx"> #include &lt;inspector/InspectorBackendDispatcher.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorFrontendDispatchers.h&gt;
</span><ins>+#include &lt;wtf/Stopwatch.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace Inspector;
</span><span class="cx"> 
</span><span class="lines">@@ -80,6 +81,7 @@
</span><span class="cx">     , m_instrumentingAgents(InstrumentingAgents::create(*this))
</span><span class="cx">     , m_injectedScriptManager(std::make_unique&lt;WebInjectedScriptManager&gt;(*this, WebInjectedScriptHost::create()))
</span><span class="cx">     , m_runtimeAgent(nullptr)
</span><ins>+    , m_executionStopwatch(Stopwatch::create())
</ins><span class="cx"> {
</span><span class="cx">     auto runtimeAgent = std::make_unique&lt;WorkerRuntimeAgent&gt;(m_injectedScriptManager.get(), &amp;workerGlobalScope);
</span><span class="cx">     m_runtimeAgent = runtimeAgent.get();
</span><span class="lines">@@ -170,6 +172,11 @@
</span><span class="cx">     InspectorInstrumentation::didCallFunction(cookie, scriptExecutionContext);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PassRefPtr&lt;Stopwatch&gt; WorkerInspectorController::executionStopwatch()
+{
+    return m_executionStopwatch;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorWorkerInspectorControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.h (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/WorkerInspectorController.h        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.h        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx">     virtual void willCallInjectedScriptFunction(JSC::ExecState*, const String&amp; scriptName, int scriptLine) override;
</span><span class="cx">     virtual void didCallInjectedScriptFunction(JSC::ExecState*) override;
</span><span class="cx">     virtual void frontendInitialized() override { }
</span><ins>+    virtual PassRefPtr&lt;WTF::Stopwatch&gt; executionStopwatch() override;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend InstrumentingAgents* instrumentationForWorkerGlobalScope(WorkerGlobalScope*);
</span><span class="lines">@@ -84,6 +85,7 @@
</span><span class="cx">     WorkerRuntimeAgent* m_runtimeAgent;
</span><span class="cx">     Inspector::InspectorAgentRegistry m_agents;
</span><span class="cx">     std::unique_ptr&lt;InspectorFrontendChannel&gt; m_frontendChannel;
</span><ins>+    RefPtr&lt;WTF::Stopwatch&gt; m_executionStopwatch;
</ins><span class="cx">     RefPtr&lt;Inspector::InspectorBackendDispatcher&gt; m_backendDispatcher;
</span><span class="cx">     Vector&lt;InspectorInstrumentationCookie, 2&gt; m_injectedScriptInstrumentationCookies;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2014-10-10 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. Also convert code that
+        tracks page/resource load timings to use elapsed times rather than timestamps.
+
+        Add a workaround to preserve compatibility with old backends. Convert legacy timestamps
+        in multiple agents to elapsed times.
+
+        * UserInterface/Controllers/FrameResourceManager.js:
+        (WebInspector.FrameResourceManager.prototype.resourceRequestWillBeSent):
+        (WebInspector.FrameResourceManager.prototype.resourceRequestWasServedFromMemoryCache):
+        (WebInspector.FrameResourceManager.prototype.resourceRequestDidReceiveResponse):
+        (WebInspector.FrameResourceManager.prototype.resourceRequestDidReceiveData):
+        (WebInspector.FrameResourceManager.prototype.resourceRequestDidFinishLoading):
+        (WebInspector.FrameResourceManager.prototype.resourceRequestDidFailLoading):
+        (WebInspector.FrameResourceManager.prototype._addNewResourceToFrame):
+        * UserInterface/Controllers/ProbeManager.js:
+        * UserInterface/Controllers/TimelineManager.js:
+        (WebInspector.TimelineManager.prototype.computeElapsedTime): Forward to the active TimelineRecording.
+        (WebInspector.TimelineManager.prototype.eventRecorded.processRecord):
+        (WebInspector.TimelineManager.prototype.eventRecorded):
+        (WebInspector.TimelineManager.prototype.pageDidLoad):
+        (WebInspector.TimelineManager.prototype._loadNewRecording):
+        * UserInterface/Models/Probe.js:
+        (WebInspector.ProbeSample):
+        * UserInterface/Models/Resource.js:
+        (WebInspector.Resource.prototype.updateForRedirectResponse):
+        (WebInspector.Resource.prototype.updateForResponse):
+        (WebInspector.Resource.prototype.increaseSize):
+        (WebInspector.Resource.prototype.markAsFinished):
+        (WebInspector.Resource.prototype.markAsFailed):
+        (WebInspector.Resource.prototype.revertMarkAsFinished):
+        * UserInterface/Models/TimelineRecording.js:
+        (WebInspector.TimelineRecording.prototype.computeElapsedTime):
+        * UserInterface/Views/TimelineContentView.js:
+        (WebInspector.TimelineContentView.prototype._debuggerPaused):
+        (WebInspector.TimelineContentView.prototype._debuggerResumed):
+
+
</ins><span class="cx"> 2014-10-23  Jono Wells  &lt;jonowells@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Double border appearing in node sidebar in expanded items in OS X Mavericks.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersFrameResourceManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -184,18 +184,19 @@
</span><span class="cx">         if (this._waitingForMainFrameResourceTreePayload)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
</ins><span class="cx">         var resource = this._resourceRequestIdentifierMap[requestIdentifier];
</span><span class="cx">         if (resource) {
</span><span class="cx">             // This is an existing request which is being redirected, update the resource.
</span><span class="cx">             console.assert(redirectResponse);
</span><del>-            resource.updateForRedirectResponse(request.url, request.headers, timestamp);
</del><ins>+            resource.updateForRedirectResponse(request.url, request.headers, elapsedTime);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         var initiatorSourceCodeLocation = this._initiatorSourceCodeLocationFromPayload(initiator);
</span><span class="cx"> 
</span><span class="cx">         // This is a new request, make a new resource and add it to the right frame.
</span><del>-        resource = this._addNewResourceToFrame(requestIdentifier, frameIdentifier, loaderIdentifier, request.url, type, request.method, request.headers, request.postData, timestamp, null, null, initiatorSourceCodeLocation);
</del><ins>+        resource = this._addNewResourceToFrame(requestIdentifier, frameIdentifier, loaderIdentifier, request.url, type, request.method, request.headers, request.postData, elapsedTime, null, null, initiatorSourceCodeLocation);
</ins><span class="cx"> 
</span><span class="cx">         // Associate the resource with the requestIdentifier so it can be found in future loading events.
</span><span class="cx">         this._resourceRequestIdentifierMap[requestIdentifier] = resource;
</span><span class="lines">@@ -230,13 +231,13 @@
</span><span class="cx"> 
</span><span class="cx">         console.assert(!(requestIdentifier in this._resourceRequestIdentifierMap));
</span><span class="cx"> 
</span><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
</ins><span class="cx">         var initiatorSourceCodeLocation = this._initiatorSourceCodeLocationFromPayload(initiator);
</span><del>-
</del><span class="cx">         var response = cachedResourcePayload.response;
</span><del>-        var resource = this._addNewResourceToFrame(requestIdentifier, frameIdentifier, loaderIdentifier, cachedResourcePayload.url, cachedResourcePayload.type, null, null, timestamp, null, null, initiatorSourceCodeLocation);
</del><ins>+        var resource = this._addNewResourceToFrame(requestIdentifier, frameIdentifier, loaderIdentifier, cachedResourcePayload.url, cachedResourcePayload.type, null, null, elapsedTime, null, null, initiatorSourceCodeLocation);
</ins><span class="cx">         resource.markAsCached();
</span><del>-        resource.updateForResponse(cachedResourcePayload.url, response.mimeType, cachedResourcePayload.type, response.headers, response.status, response.statusText, timestamp);
-        resource.markAsFinished(timestamp);
</del><ins>+        resource.updateForResponse(cachedResourcePayload.url, response.mimeType, cachedResourcePayload.type, response.headers, response.status, response.statusText, elapsedTime);
+        resource.markAsFinished(elapsedTime);
</ins><span class="cx"> 
</span><span class="cx">         if (cachedResourcePayload.sourceMapURL)
</span><span class="cx">             WebInspector.sourceMapManager.downloadSourceMap(cachedResourcePayload.sourceMapURL, resource.url, resource);
</span><span class="lines">@@ -253,6 +254,7 @@
</span><span class="cx">         if (this._waitingForMainFrameResourceTreePayload)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
</ins><span class="cx">         var resource = this._resourceRequestIdentifierMap[requestIdentifier];
</span><span class="cx"> 
</span><span class="cx">         // We might not have a resource if the inspector was opened during the page load (after resourceRequestWillBeSent is called).
</span><span class="lines">@@ -275,7 +277,7 @@
</span><span class="cx">         // If we haven't found an existing Resource by now, then it is a resource that was loading when the inspector
</span><span class="cx">         // opened and we just missed the resourceRequestWillBeSent for it. So make a new resource and add it.
</span><span class="cx">         if (!resource) {
</span><del>-            resource = this._addNewResourceToFrame(requestIdentifier, frameIdentifier, loaderIdentifier, response.url, type, null, response.requestHeaders, timestamp, null, null);
</del><ins>+            resource = this._addNewResourceToFrame(requestIdentifier, frameIdentifier, loaderIdentifier, response.url, type, null, response.requestHeaders, elapsedTime, null, null);
</ins><span class="cx"> 
</span><span class="cx">             // Associate the resource with the requestIdentifier so it can be found in future loading events.
</span><span class="cx">             this._resourceRequestIdentifierMap[requestIdentifier] = resource;
</span><span class="lines">@@ -284,7 +286,7 @@
</span><span class="cx">         if (response.fromDiskCache)
</span><span class="cx">             resource.markAsCached();
</span><span class="cx"> 
</span><del>-        resource.updateForResponse(response.url, response.mimeType, type, response.headers, response.status, response.statusText, timestamp);
</del><ins>+        resource.updateForResponse(response.url, response.mimeType, type, response.headers, response.status, response.statusText, elapsedTime);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     resourceRequestDidReceiveData: function(requestIdentifier, dataLength, encodedDataLength, timestamp)
</span><span class="lines">@@ -296,6 +298,7 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         var resource = this._resourceRequestIdentifierMap[requestIdentifier];
</span><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
</ins><span class="cx"> 
</span><span class="cx">         // We might not have a resource if the inspector was opened during the page load (after resourceRequestWillBeSent is called).
</span><span class="cx">         // We don't want to assert in this case since we do likely have the resource, via PageAgent.getResourceTree. The Resource
</span><span class="lines">@@ -303,7 +306,7 @@
</span><span class="cx">         if (!resource)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        resource.increaseSize(dataLength, timestamp);
</del><ins>+        resource.increaseSize(dataLength, elapsedTime);
</ins><span class="cx"> 
</span><span class="cx">         if (encodedDataLength !== -1)
</span><span class="cx">             resource.increaseTransferSize(encodedDataLength);
</span><span class="lines">@@ -324,7 +327,8 @@
</span><span class="cx">         if (!resource)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        resource.markAsFinished(timestamp);
</del><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
+        resource.markAsFinished(elapsedTime);
</ins><span class="cx"> 
</span><span class="cx">         if (sourceMapURL)
</span><span class="cx">             WebInspector.sourceMapManager.downloadSourceMap(sourceMapURL, resource.url, resource);
</span><span class="lines">@@ -347,7 +351,8 @@
</span><span class="cx">         if (!resource)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        resource.markAsFailed(canceled, timestamp);
</del><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
+        resource.markAsFailed(canceled, elapsedTime);
</ins><span class="cx"> 
</span><span class="cx">         if (resource === resource.parentFrame.provisionalMainResource)
</span><span class="cx">             resource.parentFrame.clearProvisionalLoad();
</span><span class="lines">@@ -382,7 +387,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Private
</span><span class="cx"> 
</span><del>-    _addNewResourceToFrame: function(requestIdentifier, frameIdentifier, loaderIdentifier, url, type, requestMethod, requestHeaders, requestData, timestamp, frameName, frameSecurityOrigin, initiatorSourceCodeLocation)
</del><ins>+    _addNewResourceToFrame: function(requestIdentifier, frameIdentifier, loaderIdentifier, url, type, requestMethod, requestHeaders, requestData, elapsedTime, frameName, frameSecurityOrigin, initiatorSourceCodeLocation)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._waitingForMainFrameResourceTreePayload);
</span><span class="cx"> 
</span><span class="lines">@@ -396,12 +401,12 @@
</span><span class="cx">             else if (frame.provisionalMainResource &amp;&amp; frame.provisionalMainResource.url === url &amp;&amp; frame.provisionalLoaderIdentifier === loaderIdentifier)
</span><span class="cx">                 resource = frame.provisionalMainResource;
</span><span class="cx">             else {
</span><del>-                resource = new WebInspector.Resource(url, null, type, loaderIdentifier, requestIdentifier, requestMethod, requestHeaders, requestData, timestamp, initiatorSourceCodeLocation);
</del><ins>+                resource = new WebInspector.Resource(url, null, type, loaderIdentifier, requestIdentifier, requestMethod, requestHeaders, requestData, elapsedTime, initiatorSourceCodeLocation);
</ins><span class="cx">                 this._addResourceToFrame(frame, resource);
</span><span class="cx">             }
</span><span class="cx">         } else {
</span><span class="cx">             // This is a new request for a new frame, which is always the main resource.
</span><del>-            resource = new WebInspector.Resource(url, null, type, loaderIdentifier, requestIdentifier, requestMethod, requestHeaders, requestData, timestamp, initiatorSourceCodeLocation);
</del><ins>+            resource = new WebInspector.Resource(url, null, type, loaderIdentifier, requestIdentifier, requestMethod, requestHeaders, requestData, elapsedTime, initiatorSourceCodeLocation);
</ins><span class="cx">             frame = new WebInspector.Frame(frameIdentifier, frameName, frameSecurityOrigin, loaderIdentifier, resource);
</span><span class="cx">             this._frameIdentifierMap[frame.id] = frame;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersProbeManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/ProbeManager.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/ProbeManager.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/ProbeManager.js        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -75,7 +75,8 @@
</span><span class="cx">     {
</span><span class="cx">         console.assert(this._probesByIdentifier.has(sample.probeId), &quot;Unknown probe identifier specified for sample: &quot;, sample);
</span><span class="cx">         var probe = this._probesByIdentifier.get(sample.probeId);
</span><del>-        probe.addSample(new WebInspector.ProbeSample(sample.sampleId, sample.batchId, sample.timestamp, sample.payload));
</del><ins>+        var elapsedTime = WebInspector.timelineManager.computeElapsedTime(sample.timestamp);
+        probe.addSample(new WebInspector.ProbeSample(sample.sampleId, sample.batchId, elapsedTime, sample.payload));
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Private
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -121,6 +121,14 @@
</span><span class="cx">         this._activeRecording = null;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    computeElapsedTime: function(timestamp)
+    {
+        if (!this._activeRecording)
+            return 0;
+
+        return this._activeRecording.computeElapsedTime(timestamp);
+    },
+
</ins><span class="cx">     // Protected
</span><span class="cx"> 
</span><span class="cx">     capturingStarted: function()
</span><span class="lines">@@ -163,10 +171,8 @@
</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 = this.activeRecording.computeElapsedTime(recordPayload.startTime);
+            var endTime = this.activeRecording.computeElapsedTime(recordPayload.endTime);
</ins><span class="cx">             var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);
</span><span class="cx"> 
</span><span class="cx">             var significantCallFrame = null;
</span><span class="lines">@@ -393,7 +399,7 @@
</span><span class="cx">     pageDidLoad: function(timestamp)
</span><span class="cx">     {
</span><span class="cx">         if (isNaN(WebInspector.frameResourceManager.mainFrame.loadEventTimestamp))
</span><del>-            WebInspector.frameResourceManager.mainFrame.markLoadEvent(timestamp);
</del><ins>+            WebInspector.frameResourceManager.mainFrame.markLoadEvent(this.activeRecording.computeElapsedTime(timestamp));
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Private
</span><span class="lines">@@ -417,6 +423,7 @@
</span><span class="cx">         if (oldRecording)
</span><span class="cx">             oldRecording.unloaded();
</span><span class="cx"> 
</span><ins>+        this._legacyFirstRecordedTimestamp = NaN;
</ins><span class="cx">         this._activeRecording = newRecording;
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.TimelineManager.Event.RecordingLoaded, {oldRecording: oldRecording});
</span><span class="cx">     },
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsProbejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Probe.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Probe.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Probe.js        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -24,11 +24,11 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebInspector.ProbeSample = function(sampleId, batchId, timestamp, payload)
</del><ins>+WebInspector.ProbeSample = function(sampleId, batchId, elapsedTime, payload)
</ins><span class="cx"> {
</span><span class="cx">     this.sampleId = sampleId;
</span><span class="cx">     this.batchId = batchId;
</span><del>-    this.timestamp = timestamp;
</del><ins>+    this.timestamp = elapsedTime;
</ins><span class="cx">     this.object = WebInspector.RemoteObject.fromPayload(payload);
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsResourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -459,7 +459,7 @@
</span><span class="cx">         return null;
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    updateForRedirectResponse: function(url, requestHeaders, timestamp)
</del><ins>+    updateForRedirectResponse: function(url, requestHeaders, elapsedTime)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._finished);
</span><span class="cx">         console.assert(!this._failed);
</span><span class="lines">@@ -469,7 +469,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._url = url;
</span><span class="cx">         this._requestHeaders = requestHeaders || {};
</span><del>-        this._lastRedirectReceivedTimestamp = timestamp || NaN;
</del><ins>+        this._lastRedirectReceivedTimestamp = elapsedTime || NaN;
</ins><span class="cx"> 
</span><span class="cx">         if (oldURL !== url) {
</span><span class="cx">             // Delete the URL components so the URL is re-parsed the next time it is requested.
</span><span class="lines">@@ -482,7 +482,7 @@
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Resource.Event.TimestampsDidChange);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    updateForResponse: function(url, mimeType, type, responseHeaders, statusCode, statusText, timestamp)
</del><ins>+    updateForResponse: function(url, mimeType, type, responseHeaders, statusCode, statusText, elapsedTime)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._finished);
</span><span class="cx">         console.assert(!this._failed);
</span><span class="lines">@@ -501,7 +501,7 @@
</span><span class="cx">         this._statusCode = statusCode;
</span><span class="cx">         this._statusText = statusText;
</span><span class="cx">         this._responseHeaders = responseHeaders || {};
</span><del>-        this._responseReceivedTimestamp = timestamp || NaN;
</del><ins>+        this._responseReceivedTimestamp = elapsedTime || NaN;
</ins><span class="cx"> 
</span><span class="cx">         this._responseHeadersSize = String(this._statusCode).length + this._statusText.length + 12; // Extra length is for &quot;HTTP/1.1 &quot;, &quot; &quot;, and &quot;\r\n&quot;.
</span><span class="cx">         for (var name in this._responseHeaders)
</span><span class="lines">@@ -563,7 +563,7 @@
</span><span class="cx">         return false;
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    increaseSize: function(dataLength, timestamp)
</del><ins>+    increaseSize: function(dataLength, elapsedTime)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(dataLength &gt;= 0);
</span><span class="cx"> 
</span><span class="lines">@@ -574,7 +574,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._size += dataLength;
</span><span class="cx"> 
</span><del>-        this._lastDataReceivedTimestamp = timestamp || NaN;
</del><ins>+        this._lastDataReceivedTimestamp = elapsedTime || NaN;
</ins><span class="cx"> 
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Resource.Event.SizeDidChange, {previousSize: previousSize});
</span><span class="cx"> 
</span><span class="lines">@@ -605,13 +605,13 @@
</span><span class="cx">             this.dispatchEventToListeners(WebInspector.Resource.Event.TransferSizeDidChange);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    markAsFinished: function(timestamp)
</del><ins>+    markAsFinished: function(elapsedTime)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._failed);
</span><span class="cx">         console.assert(!this._canceled);
</span><span class="cx"> 
</span><span class="cx">         this._finished = true;
</span><del>-        this._finishedOrFailedTimestamp = timestamp || NaN;
</del><ins>+        this._finishedOrFailedTimestamp = elapsedTime || NaN;
</ins><span class="cx"> 
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Resource.Event.LoadingDidFinish);
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Resource.Event.TimestampsDidChange);
</span><span class="lines">@@ -620,13 +620,13 @@
</span><span class="cx">             this.requestContentFromBackendIfNeeded();
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    markAsFailed: function(canceled, timestamp)
</del><ins>+    markAsFailed: function(canceled, elapsedTime)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._finished);
</span><span class="cx"> 
</span><span class="cx">         this._failed = true;
</span><span class="cx">         this._canceled = canceled;
</span><del>-        this._finishedOrFailedTimestamp = timestamp || NaN;
</del><ins>+        this._finishedOrFailedTimestamp = elapsedTime || NaN;
</ins><span class="cx"> 
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Resource.Event.LoadingDidFail);
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Resource.Event.TimestampsDidChange);
</span><span class="lines">@@ -635,7 +635,7 @@
</span><span class="cx">         this.servicePendingContentRequests(true);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    revertMarkAsFinished: function(timestamp)
</del><ins>+    revertMarkAsFinished: function()
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._failed);
</span><span class="cx">         console.assert(!this._canceled);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsTimelineRecordingjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/TimelineRecording.js        2014-10-25 22:05:57 UTC (rev 175203)
</span><span class="lines">@@ -32,6 +32,9 @@
</span><span class="cx">     this._displayName = displayName;
</span><span class="cx">     this._isWritable = true;
</span><span class="cx"> 
</span><ins>+    // For legacy backends, we compute the elapsed time of records relative to this timestamp.
+    this._legacyFirstRecordedTimestamp = NaN;
+
</ins><span class="cx">     for (var key of Object.keys(WebInspector.TimelineRecord.Type)) {
</span><span class="cx">         var type = WebInspector.TimelineRecord.Type[key];
</span><span class="cx">         var timeline = new WebInspector.Timeline(type);
</span><span class="lines">@@ -49,6 +52,8 @@
</span><span class="cx">     TimesUpdated: &quot;timeline-recording-times-updated&quot;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.TimelineRecording.TimestampThresholdForLegacyRecordConversion = 28800000; // Date.parse(&quot;Jan 1, 1970&quot;)
+
</ins><span class="cx"> WebInspector.TimelineRecording.prototype = {
</span><span class="cx">     constructor: WebInspector.TimelineRecording,
</span><span class="cx">     __proto__: WebInspector.Object.prototype,
</span><span class="lines">@@ -175,6 +180,24 @@
</span><span class="cx">             this.dispatchEventToListeners(WebInspector.TimelineRecording.Event.SourceCodeTimelineAdded, {sourceCodeTimeline: sourceCodeTimeline});
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    computeElapsedTime: function(timestamp)
+    {
+        if (!timestamp || isNaN(timestamp))
+            return NaN;
+
+        // COMPATIBILITY (iOS8): old backends send timestamps (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._legacyFirstRecordedTimestamp))
+            this._legacyFirstRecordedTimestamp = timestamp;
+
+        // If the record's start time sems unreasonably large, treat it as a legacy timestamp.
+        if (timestamp &gt; WebInspector.TimelineRecording.TimestampThresholdForLegacyRecordConversion)
+            return (timestamp - this._legacyFirstRecordedTimestamp) / 1000.0;
+
+        return timestamp;
+    },
+
</ins><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _keyForRecord: function(record)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTimelineContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js (175202 => 175203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js        2014-10-25 19:58:14 UTC (rev 175202)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineContentView.js        2014-10-25 22:05:57 UTC (rev 175203)
</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>