No subject


Mon Sep 28 12:00:37 PDT 2015


object. Because the Timelines UI knows how to interact with the
CPUProfile object and display it, we currently map the tree to this object
to make it trivially easy to display the SamplingProfiler's data. In the future,
we may want to find ways to work directly with the CallingContextTree instead
of mapping it into another object.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Controllers/TimelineManager.js:
* UserInterface/Main.html:
* UserInterface/Models/CallingContextTree.js: Added.
* UserInterface/Models/ScriptInstrument.js:
* UserInterface/Protocol/ScriptProfilerObserver.js:
* UserInterface/TestStub.html:
* UserInterface/Views/ScriptTimelineView.js:

LayoutTests:

* inspector/sampling-profiler: Added.
* inspector/sampling-profiler/basic-expected.txt: Added.
* inspector/sampling-profiler/basic.html: Added.
* inspector/sampling-profiler/call-frame-with-dom-functions-expected.txt: Added.
* inspector/sampling-profiler/call-frame-with-dom-functions.html: Added.
* inspector/sampling-profiler/eval-source-url-expected.txt: Added.
* inspector/sampling-profiler/eval-source-url.html: Added.
* inspector/sampling-profiler/many-call-frames-expected.txt: Added.
* inspector/sampling-profiler/many-call-frames.html: Added.
* inspector/sampling-profiler/named-function-expression-expected.txt: Added.
* inspector/sampling-profiler/named-function-expression.html: Added.
* inspector/script-profiler/event-type-API-expected.txt:
* inspector/script-profiler/event-type-API.html:
* inspector/script-profiler/event-type-Microtask-expected.txt:
* inspector/script-profiler/event-type-Microtask.html:
* inspector/script-profiler/event-type-Other-expected.txt:
* inspector/script-profiler/event-type-Other.html:
* inspector/script-profiler/tracking-expected.txt:
* inspector/script-profiler/tracking.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilereventtypeAPIexpectedtxt">trunk/LayoutTests/inspector/script-profiler/event-type-API-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilereventtypeAPIhtml">trunk/LayoutTests/inspector/script-profiler/event-type-API.html</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilereventtypeMicrotaskexpectedtxt">trunk/LayoutTests/inspector/script-profiler/event-type-Microtask-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilereventtypeMicrotaskhtml">trunk/LayoutTests/inspector/script-profiler/event-type-Microtask.html</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilereventtypeOtherexpectedtxt">trunk/LayoutTests/inspector/script-profiler/event-type-Other-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilereventtypeOtherhtml">trunk/LayoutTests/inspector/script-profiler/event-type-Other.html</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilertrackingexpectedtxt">trunk/LayoutTests/inspector/script-profiler/tracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorscriptprofilertrackinghtml">trunk/LayoutTests/inspector/script-profiler/tracking.html</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggercpp">trunk/Source/JavaScriptCore/debugger/Debugger.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerh">trunk/Source/JavaScriptCore/debugger/Debugger.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerScriptProfilingScopeh">trunk/Source/JavaScriptCore/debugger/ScriptProfilingScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolScriptProfilerjson">trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSamplingProfilercpp">trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSamplingProfilerh">trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssamplingprofilersamplingProfilerjs">trunk/Source/JavaScriptCore/tests/stress/sampling-profiler/samplingProfiler.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssamplingprofileranonymousfunctionjs">trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-anonymous-function.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssamplingprofilerbasicjs">trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-basic.js</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs">trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsScriptInstrumentjs">trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolScriptProfilerObserverjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTestStubhtml">trunk/Source/WebInspectorUI/UserInterface/TestStub.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsScriptTimelineViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineView.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/inspector/sampling-profiler/</li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilerbasicexpectedtxt">trunk/LayoutTests/inspector/sampling-profiler/basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilerbasichtml">trunk/LayoutTests/inspector/sampling-profiler/basic.html</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilercallframewithdomfunctionsexpectedtxt">trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilercallframewithdomfunctionshtml">trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions.html</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilerevalsourceurlexpectedtxt">trunk/LayoutTests/inspector/sampling-profiler/eval-source-url-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilerevalsourceurlhtml">trunk/LayoutTests/inspector/sampling-profiler/eval-source-url.html</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilermanycallframesexpectedtxt">trunk/LayoutTests/inspector/sampling-profiler/many-call-frames-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilermanycallframeshtml">trunk/LayoutTests/inspector/sampling-profiler/many-call-frames.html</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilernamedfunctionexpressionexpectedtxt">trunk/LayoutTests/inspector/sampling-profiler/named-function-expression-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorsamplingprofilernamedfunctionexpressionhtml">trunk/LayoutTests/inspector/sampling-profiler/named-function-expression.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreejs">trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/ChangeLog	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2016-01-20  Saam barati  &lt;sbarati at apple.com&gt;
+
+        Web Inspector: Hook the sampling profiler into the Timelines UI
+        https://bugs.webkit.org/show_bug.cgi?id=152766
+        &lt;rdar://problem/24066360&gt;
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/sampling-profiler: Added.
+        * inspector/sampling-profiler/basic-expected.txt: Added.
+        * inspector/sampling-profiler/basic.html: Added.
+        * inspector/sampling-profiler/call-frame-with-dom-functions-expected.txt: Added.
+        * inspector/sampling-profiler/call-frame-with-dom-functions.html: Added.
+        * inspector/sampling-profiler/eval-source-url-expected.txt: Added.
+        * inspector/sampling-profiler/eval-source-url.html: Added.
+        * inspector/sampling-profiler/many-call-frames-expected.txt: Added.
+        * inspector/sampling-profiler/many-call-frames.html: Added.
+        * inspector/sampling-profiler/named-function-expression-expected.txt: Added.
+        * inspector/sampling-profiler/named-function-expression.html: Added.
+        * inspector/script-profiler/event-type-API-expected.txt:
+        * inspector/script-profiler/event-type-API.html:
+        * inspector/script-profiler/event-type-Microtask-expected.txt:
+        * inspector/script-profiler/event-type-Microtask.html:
+        * inspector/script-profiler/event-type-Other-expected.txt:
+        * inspector/script-profiler/event-type-Other.html:
+        * inspector/script-profiler/tracking-expected.txt:
+        * inspector/script-profiler/tracking.html:
+
</ins><span class="cx"> 2016-01-20  Daniel Bates  &lt;dabates at apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CSP: Add tests to ensure that alternative text of an image is rendered when CSP blocks its load
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilerbasicexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/basic-expected.txt (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/basic-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/basic-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+
+== Running test suite: ScriptProfiler.Samples.Basic
+-- Running test case: Sampling Profiler basic
+PASS: Should have seen stacktrace:
+[
+  {
+    &quot;name&quot;: &quot;foo&quot;
+  },
+  {
+    &quot;name&quot;: &quot;runFor&quot;
+  }
+]
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilerbasichtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/basic.html (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/basic.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/basic.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/protocol-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function runFor(func, millis) {
+    let start = Date.now();
+    do {
+        func();
+    } while (Date.now() - start &lt; millis);
+}
+
+function foo() {
+    for (let i = 0; i &lt; 10000; i++) {
+        i++;
+        i--;
+    }
+}
+noInline(foo);
+
+function test()
+{
+    let suite = ProtocolTest.createAsyncSuite(&quot;ScriptProfiler.Samples.Basic&quot;);
+
+    suite.addTestCase({
+        name: &quot;Sampling Profiler basic&quot;,
+        description: &quot;Sample some basic code.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
+                let tree = WebInspector.CallingContextTree.__test_makeTreeFromProtocolMessageObject(messageObject);
+                let trace = [
+                    {name: &quot;foo&quot;},
+                    {name: &quot;runFor&quot;}
+                ];
+                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), &quot;Should have seen stacktrace:\n&quot; + JSON.stringify(trace, undefined, 2));
+                resolve();
+            });
+
+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {includeSamples: true});
+            ProtocolTest.evaluateInPage(&quot;runFor(foo, 100)&quot;);
+            InspectorProtocol.sendCommand('ScriptProfiler.stopTracking', {});
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilercallframewithdomfunctionsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions-expected.txt (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+
+== Running test suite: SciptProfiler.Samples.DOM
+-- Running test case: Sampling Profiler sourceURL directive.
+PASS: Should have seen stacktrace:
+[
+  {
+    &quot;name&quot;: &quot;createElement&quot;
+  },
+  {
+    &quot;name&quot;: &quot;foo&quot;
+  },
+  {
+    &quot;name&quot;: &quot;runFor&quot;
+  }
+]
+PASS: Should have seen stacktrace:
+[
+  {
+    &quot;name&quot;: &quot;appendChild&quot;
+  },
+  {
+    &quot;name&quot;: &quot;foo&quot;
+  },
+  {
+    &quot;name&quot;: &quot;runFor&quot;
+  }
+]
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilercallframewithdomfunctionshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions.html (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/call-frame-with-dom-functions.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/protocol-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function runFor(func, millis) {
+    let start = Date.now();
+    do {
+        func();
+    } while (Date.now() - start &lt; millis);
+}
+
+function foo() {
+    let body = document.body;
+    for (let i = 0; i &lt; 10000; i++) {
+        let p = document.createElement(&quot;p&quot;);
+        body.appendChild(p);
+    }
+}
+noInline(foo);
+
+function test()
+{
+    let suite = ProtocolTest.createAsyncSuite(&quot;SciptProfiler.Samples.DOM&quot;);
+
+    suite.addTestCase({
+        name: &quot;Sampling Profiler sourceURL directive.&quot;,
+        description: &quot;Sample some basic code.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
+                let tree = WebInspector.CallingContextTree.__test_makeTreeFromProtocolMessageObject(messageObject);
+
+                let trace = [
+                    {name: &quot;createElement&quot;},
+                    {name: &quot;foo&quot;},
+                    {name: &quot;runFor&quot;}
+                ];
+                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), &quot;Should have seen stacktrace:\n&quot; + JSON.stringify(trace, undefined, 2));
+
+                trace = [
+                    {name: &quot;appendChild&quot;},
+                    {name: &quot;foo&quot;},
+                    {name: &quot;runFor&quot;}
+                ];
+                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), &quot;Should have seen stacktrace:\n&quot; + JSON.stringify(trace, undefined, 2));
+
+                resolve();
+            });
+
+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {includeSamples: true});
+            ProtocolTest.evaluateInPage(&quot;runFor(foo, 100)&quot;);
+            InspectorProtocol.sendCommand('ScriptProfiler.stopTracking', {});
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilerevalsourceurlexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/eval-source-url-expected.txt (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/eval-source-url-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/eval-source-url-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+
+== Running test suite: ScriptProfiler.Samples.SourceURL
+-- Running test case: Sampling Profiler sourceURL directive.
+PASS: Should have seen stacktrace:
+[
+  {
+    &quot;name&quot;: &quot;foo&quot;
+  },
+  {
+    &quot;name&quot;: &quot;(program)&quot;,
+    &quot;url&quot;: &quot;eval.js&quot;
+  },
+  {
+    &quot;name&quot;: &quot;eval&quot;
+  },
+  {
+    &quot;name&quot;: &quot;bar&quot;
+  },
+  {
+    &quot;name&quot;: &quot;runFor&quot;
+  }
+]
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilerevalsourceurlhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/eval-source-url.html (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/eval-source-url.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/eval-source-url.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/protocol-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function runFor(func, millis) {
+    let start = Date.now();
+    do {
+        func();
+    } while (Date.now() - start &lt; millis);
+}
+
+function foo() {
+    for (let i = 0; i &lt; 10000; i++) {
+        i++;
+        i--;
+    }
+}
+noInline(foo);
+
+function bar() {
+    for (let i = 0; i &lt; 2; i++)
+        eval(&quot;//# sourceURL=eval.js\nfoo();&quot;);
+}
+noInline(bar);
+
+function test()
+{
+    let suite = ProtocolTest.createAsyncSuite(&quot;ScriptProfiler.Samples.SourceURL&quot;);
+
+    suite.addTestCase({
+        name: &quot;Sampling Profiler sourceURL directive.&quot;,
+        description: &quot;Sample some basic code.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
+                let tree = WebInspector.CallingContextTree.__test_makeTreeFromProtocolMessageObject(messageObject);
+
+                let trace = [
+                    {name: &quot;foo&quot;},
+                    {name: &quot;(program)&quot;, url: &quot;eval.js&quot;},
+                    {name: &quot;eval&quot;},
+                    {name: &quot;bar&quot;},
+                    {name: &quot;runFor&quot;}
+                ];
+                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), &quot;Should have seen stacktrace:\n&quot; + JSON.stringify(trace, undefined, 2));
+                resolve();
+            });
+
+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {includeSamples: true});
+            ProtocolTest.evaluateInPage(&quot;runFor(bar, 100)&quot;);
+            InspectorProtocol.sendCommand('ScriptProfiler.stopTracking', {});
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilermanycallframesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/many-call-frames-expected.txt (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/many-call-frames-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/many-call-frames-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+
+== Running test suite: ScriptProfiler.Samples.ManyCallFrames
+-- Running test case: Sampling Profiler sourceURL directive.
+PASS: Should have seen stacktrace:
+[
+  {
+    &quot;name&quot;: &quot;top&quot;
+  },
+  {
+    &quot;name&quot;: &quot;g&quot;
+  },
+  {
+    &quot;name&quot;: &quot;f&quot;
+  },
+  {
+    &quot;name&quot;: &quot;e&quot;
+  },
+  {
+    &quot;name&quot;: &quot;d&quot;
+  },
+  {
+    &quot;name&quot;: &quot;c&quot;
+  },
+  {
+    &quot;name&quot;: &quot;b&quot;
+  },
+  {
+    &quot;name&quot;: &quot;a&quot;
+  },
+  {
+    &quot;name&quot;: &quot;runFor&quot;
+  }
+]
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilermanycallframeshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/many-call-frames.html (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/many-call-frames.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/many-call-frames.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/protocol-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function runFor(func, millis) {
+    let start = Date.now();
+    do {
+        func();
+    } while (Date.now() - start &lt; millis);
+}
+function a() { b(); }
+function b() { c(); }
+function c() { d(); }
+function d() { e(); }
+function e() { f(); }
+function f() { g(); }
+function g() { top(); }
+
+function top() {
+    for (let i = 0; i &lt; 10000; i++) {
+        i++;
+        i--;
+    }
+}
+noInline(top);
+
+function test()
+{
+    let suite = ProtocolTest.createAsyncSuite(&quot;ScriptProfiler.Samples.ManyCallFrames&quot;);
+
+    suite.addTestCase({
+        name: &quot;Sampling Profiler sourceURL directive.&quot;,
+        description: &quot;Sample some basic code.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
+                let tree = WebInspector.CallingContextTree.__test_makeTreeFromProtocolMessageObject(messageObject);
+
+                let trace = [
+                    {name: &quot;top&quot;},
+                    {name: &quot;g&quot;},
+                    {name: &quot;f&quot;},
+                    {name: &quot;e&quot;},
+                    {name: &quot;d&quot;},
+                    {name: &quot;c&quot;},
+                    {name: &quot;b&quot;},
+                    {name: &quot;a&quot;},
+                    {name: &quot;runFor&quot;}
+                ];
+                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), &quot;Should have seen stacktrace:\n&quot; + JSON.stringify(trace, undefined, 2));
+                resolve();
+            });
+
+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {includeSamples: true});
+            ProtocolTest.evaluateInPage(&quot;runFor(a, 100)&quot;);
+            InspectorProtocol.sendCommand('ScriptProfiler.stopTracking', {});
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilernamedfunctionexpressionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/named-function-expression-expected.txt (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/named-function-expression-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/named-function-expression-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+
+== Running test suite: ScriptProfiler.Samples.NamedFunctionExpression
+-- Running test case: Sampling Profiler basic
+PASS: Should have seen stacktrace:
+[
+  {
+    &quot;name&quot;: &quot;bar&quot;
+  },
+  {
+    &quot;name&quot;: &quot;foo&quot;
+  },
+  {
+    &quot;name&quot;: &quot;runFor&quot;
+  }
+]
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorsamplingprofilernamedfunctionexpressionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/sampling-profiler/named-function-expression.html (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/sampling-profiler/named-function-expression.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/sampling-profiler/named-function-expression.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/protocol-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+
+function runFor(func, millis) {
+    let start = Date.now();
+    do {
+        func();
+    } while (Date.now() - start &lt; millis);
+}
+
+function foo() {
+    let bar = function() {
+        for (let i = 0; i &lt; 10000; i++) {
+            i++;
+            i--;
+        }
+    };
+    noInline(bar);
+    bar();
+}
+noInline(foo);
+
+function test()
+{
+    let suite = ProtocolTest.createAsyncSuite(&quot;ScriptProfiler.Samples.NamedFunctionExpression&quot;);
+
+    suite.addTestCase({
+        name: &quot;Sampling Profiler basic&quot;,
+        description: &quot;Sample some basic code.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
+                let tree = WebInspector.CallingContextTree.__test_makeTreeFromProtocolMessageObject(messageObject);
+                let trace = [
+                    {name: &quot;bar&quot;},
+                    {name: &quot;foo&quot;},
+                    {name: &quot;runFor&quot;}
+                ];
+                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), &quot;Should have seen stacktrace:\n&quot; + JSON.stringify(trace, undefined, 2));
+                resolve();
+            });
+
+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {includeSamples: true});
+            ProtocolTest.evaluateInPage(&quot;runFor(foo, 100)&quot;);
+            InspectorProtocol.sendCommand('ScriptProfiler.stopTracking', {});
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilereventtypeAPIexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/event-type-API-expected.txt (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/event-type-API-expected.txt	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/event-type-API-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -8,6 +8,4 @@
</span><span class="cx"> ScriptProfiler.trackingUpdate
</span><span class="cx"> PASS: Event type should be API.
</span><span class="cx"> ScriptProfiler.trackingComplete
</span><del>-PASS: Profiles should exist when complete.
-PASS: Should be 1 profile for this session.
</del><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilereventtypeAPIhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/event-type-API.html (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/event-type-API.html	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/event-type-API.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -27,12 +27,10 @@
</span><span class="cx"> 
</span><span class="cx">             InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
</span><span class="cx">                 ProtocolTest.log(&quot;ScriptProfiler.trackingComplete&quot;);
</span><del>-                ProtocolTest.expectThat(Array.isArray(messageObject.params.profiles), &quot;Profiles should exist when complete.&quot;);
-                ProtocolTest.expectThat(messageObject.params.profiles.length === 1, &quot;Should be 1 profile for this session.&quot;);
</del><span class="cx">                 resolve();
</span><span class="cx">             });
</span><span class="cx"> 
</span><del>-            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {profile: true});
</del><ins>+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {});
</ins><span class="cx">             ProtocolTest.evaluateInPage(&quot;triggerAPIScript();&quot;); // This ultimately uses the JSEvaluateScript API on the Page's context.
</span><span class="cx">             InspectorProtocol.sendCommand(&quot;ScriptProfiler.stopTracking&quot;, {});
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilereventtypeMicrotaskexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/event-type-Microtask-expected.txt (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/event-type-Microtask-expected.txt	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/event-type-Microtask-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -8,6 +8,4 @@
</span><span class="cx"> ScriptProfiler.trackingUpdate
</span><span class="cx"> PASS: Event type should be Microtask.
</span><span class="cx"> ScriptProfiler.trackingComplete
</span><del>-PASS: Profiles should exist when complete.
-PASS: Should be 1 profile for this session.
</del><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilereventtypeMicrotaskhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/event-type-Microtask.html (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/event-type-Microtask.html	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/event-type-Microtask.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -28,12 +28,10 @@
</span><span class="cx"> 
</span><span class="cx">             InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
</span><span class="cx">                 ProtocolTest.log(&quot;ScriptProfiler.trackingComplete&quot;);
</span><del>-                ProtocolTest.expectThat(Array.isArray(messageObject.params.profiles), &quot;Profiles should exist when complete.&quot;);
-                ProtocolTest.expectThat(messageObject.params.profiles.length === 1, &quot;Should be 1 profile for this session.&quot;);
</del><span class="cx">                 resolve();
</span><span class="cx">             });
</span><span class="cx"> 
</span><del>-            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {profile: true});
</del><ins>+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {});
</ins><span class="cx">             ProtocolTest.evaluateInPage(&quot;triggerMicrotask()&quot;);
</span><span class="cx">             InspectorProtocol.sendCommand(&quot;ScriptProfiler.stopTracking&quot;, {});
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilereventtypeOtherexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/event-type-Other-expected.txt (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/event-type-Other-expected.txt	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/event-type-Other-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -14,6 +14,4 @@
</span><span class="cx"> ScriptProfiler.trackingUpdate
</span><span class="cx"> PASS: Event type should be Other.
</span><span class="cx"> ScriptProfiler.trackingComplete
</span><del>-PASS: Profiles should exist when complete.
-PASS: Should be 3 profiles for this session.
</del><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilereventtypeOtherhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/event-type-Other.html (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/event-type-Other.html	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/event-type-Other.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -41,12 +41,10 @@
</span><span class="cx"> 
</span><span class="cx">             InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
</span><span class="cx">                 ProtocolTest.log(&quot;ScriptProfiler.trackingComplete&quot;);
</span><del>-                ProtocolTest.expectThat(Array.isArray(messageObject.params.profiles), &quot;Profiles should exist when complete.&quot;);
-                ProtocolTest.expectThat(messageObject.params.profiles.length === 3, &quot;Should be 3 profiles for this session.&quot;);
</del><span class="cx">                 resolve();
</span><span class="cx">             });
</span><span class="cx"> 
</span><del>-            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {profile: true});
</del><ins>+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {});
</ins><span class="cx">             ProtocolTest.evaluateInPage(&quot;triggerScriptEvaluation()&quot;);
</span><span class="cx">             ProtocolTest.evaluateInPage(&quot;triggerEventDispatchEvaluation()&quot;);
</span><span class="cx">             ProtocolTest.evaluateInPage(&quot;triggerTimerEvaluation()&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilertrackingexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/tracking-expected.txt (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/tracking-expected.txt	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/tracking-expected.txt	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -6,6 +6,4 @@
</span><span class="cx"> ScriptProfiler.trackingStart
</span><span class="cx"> PASS: Should have a timestamp when starting.
</span><span class="cx"> ScriptProfiler.trackingComplete
</span><del>-PASS: Profiles should exist when complete.
-PASS: Should be no profiles for this session.
</del><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorscriptprofilertrackinghtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/script-profiler/tracking.html (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/script-profiler/tracking.html	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/LayoutTests/inspector/script-profiler/tracking.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -18,12 +18,10 @@
</span><span class="cx"> 
</span><span class="cx">             InspectorProtocol.awaitEvent({event: &quot;ScriptProfiler.trackingComplete&quot;}).then((messageObject) =&gt; {
</span><span class="cx">                 ProtocolTest.log(&quot;ScriptProfiler.trackingComplete&quot;);
</span><del>-                ProtocolTest.expectThat(Array.isArray(messageObject.params.profiles), &quot;Profiles should exist when complete.&quot;);
-                ProtocolTest.expectThat(!messageObject.params.profiles.length, &quot;Should be no profiles for this session.&quot;);
</del><span class="cx">                 resolve();
</span><span class="cx">             });
</span><span class="cx"> 
</span><del>-            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {profile: true});
</del><ins>+            InspectorProtocol.sendCommand(&quot;ScriptProfiler.startTracking&quot;, {});
</ins><span class="cx">             InspectorProtocol.sendCommand(&quot;ScriptProfiler.stopTracking&quot;, {});
</span><span class="cx">         }
</span><span class="cx">     });
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/ChangeLog	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -1,3 +1,76 @@
</span><ins>+2016-01-20  Saam barati  &lt;sbarati at apple.com&gt;
+
+        Web Inspector: Hook the sampling profiler into the Timelines UI
+        https://bugs.webkit.org/show_bug.cgi?id=152766
+        &lt;rdar://problem/24066360&gt;
+
+        Reviewed by Joseph Pecoraro.
+
+        This patch adds some necessary functions to SamplingProfiler::StackFrame
+        to allow it to give data to the Inspector for the timelines UI. i.e, the
+        sourceID of the executable of a stack frame.
+
+        This patch also swaps in the SamplingProfiler in place of the
+        LegacyProfiler inside InspectorScriptProfilerAgent. It adds
+        the necessary protocol data to allow the SamplingProfiler's
+        data to hook into the timelines UI.
+
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::setProfilingClient):
+        (JSC::Debugger::willEvaluateScript):
+        (JSC::Debugger::didEvaluateScript):
+        (JSC::Debugger::toggleBreakpoint):
+        * debugger/Debugger.h:
+        * debugger/ScriptProfilingScope.h:
+        (JSC::ScriptProfilingScope::ScriptProfilingScope):
+        (JSC::ScriptProfilingScope::~ScriptProfilingScope):
+        * inspector/agents/InspectorScriptProfilerAgent.cpp:
+        (Inspector::InspectorScriptProfilerAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorScriptProfilerAgent::startTracking):
+        (Inspector::InspectorScriptProfilerAgent::stopTracking):
+        (Inspector::InspectorScriptProfilerAgent::isAlreadyProfiling):
+        (Inspector::InspectorScriptProfilerAgent::willEvaluateScript):
+        (Inspector::InspectorScriptProfilerAgent::didEvaluateScript):
+        (Inspector::InspectorScriptProfilerAgent::addEvent):
+        (Inspector::buildSamples):
+        (Inspector::InspectorScriptProfilerAgent::trackingComplete):
+        (Inspector::buildAggregateCallInfoInspectorObject): Deleted.
+        (Inspector::buildInspectorObject): Deleted.
+        (Inspector::buildProfileInspectorObject): Deleted.
+        * inspector/agents/InspectorScriptProfilerAgent.h:
+        * inspector/protocol/ScriptProfiler.json:
+        * jsc.cpp:
+        (functionSamplingProfilerStackTraces):
+        * runtime/SamplingProfiler.cpp:
+        (JSC::SamplingProfiler::start):
+        (JSC::SamplingProfiler::stop):
+        (JSC::SamplingProfiler::clearData):
+        (JSC::SamplingProfiler::StackFrame::displayName):
+        (JSC::SamplingProfiler::StackFrame::displayNameForJSONTests):
+        (JSC::SamplingProfiler::StackFrame::startLine):
+        (JSC::SamplingProfiler::StackFrame::startColumn):
+        (JSC::SamplingProfiler::StackFrame::sourceID):
+        (JSC::SamplingProfiler::StackFrame::url):
+        (JSC::SamplingProfiler::stackTraces):
+        (JSC::SamplingProfiler::stackTracesAsJSON):
+        (JSC::displayName): Deleted.
+        (JSC::SamplingProfiler::stacktracesAsJSON): Deleted.
+        * runtime/SamplingProfiler.h:
+        (JSC::SamplingProfiler::StackFrame::StackFrame):
+        (JSC::SamplingProfiler::getLock):
+        (JSC::SamplingProfiler::setTimingInterval):
+        (JSC::SamplingProfiler::totalTime):
+        (JSC::SamplingProfiler::setStopWatch):
+        (JSC::SamplingProfiler::stackTraces): Deleted.
+        * tests/stress/sampling-profiler-anonymous-function.js:
+        (platformSupportsSamplingProfiler.baz):
+        (platformSupportsSamplingProfiler):
+        * tests/stress/sampling-profiler-basic.js:
+        (platformSupportsSamplingProfiler.nothing):
+        (platformSupportsSamplingProfiler.top):
+        * tests/stress/sampling-profiler/samplingProfiler.js:
+        (doesTreeHaveStackTrace):
+
</ins><span class="cx"> 2016-01-20  Keith Miller  &lt;keith_miller at apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         TypedArray's .buffer does not return the JSArrayBuffer that was passed to it on creation.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/Debugger.cpp (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/Debugger.cpp	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/debugger/Debugger.cpp	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -234,14 +234,14 @@
</span><span class="cx">     recompileAllJSFunctions();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-double Debugger::willEvaluateScript(JSGlobalObject&amp; globalObject)
</del><ins>+double Debugger::willEvaluateScript()
</ins><span class="cx"> {
</span><del>-    return m_profilingClient-&gt;willEvaluateScript(globalObject);
</del><ins>+    return m_profilingClient-&gt;willEvaluateScript();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Debugger::didEvaluateScript(JSGlobalObject&amp; globalObject, double startTime, ProfilingReason reason)
</del><ins>+void Debugger::didEvaluateScript(double startTime, ProfilingReason reason)
</ins><span class="cx"> {
</span><del>-    m_profilingClient-&gt;didEvaluateScript(globalObject, startTime, reason);
</del><ins>+    m_profilingClient-&gt;didEvaluateScript(startTime, reason);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint&amp; breakpoint, BreakpointState enabledOrNot)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/Debugger.h (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/Debugger.h	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/debugger/Debugger.h	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -132,15 +132,15 @@
</span><span class="cx">     public:
</span><span class="cx">         virtual ~ProfilingClient() { }
</span><span class="cx">         virtual bool isAlreadyProfiling() const = 0;
</span><del>-        virtual double willEvaluateScript(JSGlobalObject&amp;) = 0;
-        virtual void didEvaluateScript(JSGlobalObject&amp;, double startTime, ProfilingReason) = 0;
</del><ins>+        virtual double willEvaluateScript() = 0;
+        virtual void didEvaluateScript(double startTime, ProfilingReason) = 0;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     void setProfilingClient(ProfilingClient*);
</span><span class="cx">     bool hasProfilingClient() const { return m_profilingClient != nullptr; }
</span><span class="cx">     bool isAlreadyProfiling() const { return m_profilingClient &amp;&amp; m_profilingClient-&gt;isAlreadyProfiling(); }
</span><del>-    double willEvaluateScript(JSGlobalObject&amp;);
-    void didEvaluateScript(JSGlobalObject&amp;, double startTime, ProfilingReason);
</del><ins>+    double willEvaluateScript();
+    void didEvaluateScript(double startTime, ProfilingReason);
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     virtual bool needPauseHandling(JSGlobalObject*) { return false; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerScriptProfilingScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/ScriptProfilingScope.h (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/ScriptProfilingScope.h	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/debugger/ScriptProfilingScope.h	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -39,13 +39,13 @@
</span><span class="cx">         , m_reason(reason)
</span><span class="cx">     {
</span><span class="cx">         if (shouldStartProfile())
</span><del>-            m_startTime = m_globalObject-&gt;debugger()-&gt;willEvaluateScript(*m_globalObject);
</del><ins>+            m_startTime = m_globalObject-&gt;debugger()-&gt;willEvaluateScript();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ~ScriptProfilingScope()
</span><span class="cx">     {
</span><span class="cx">         if (shouldEndProfile())
</span><del>-            m_globalObject-&gt;debugger()-&gt;didEvaluateScript(*m_globalObject, m_startTime.value(), m_reason);
</del><ins>+            m_globalObject-&gt;debugger()-&gt;didEvaluateScript(m_startTime.value(), m_reason);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.cpp	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> #include &quot;InspectorScriptProfilerAgent.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;InspectorEnvironment.h&quot;
</span><del>-#include &quot;LegacyProfiler.h&quot;
</del><ins>+#include &quot;SamplingProfiler.h&quot;
</ins><span class="cx"> #include &lt;wtf/RunLoop.h&gt;
</span><span class="cx"> #include &lt;wtf/Stopwatch.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -57,16 +57,30 @@
</span><span class="cx">     stopTracking(ignored);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorScriptProfilerAgent::startTracking(ErrorString&amp;, const bool* profile)
</del><ins>+void InspectorScriptProfilerAgent::startTracking(ErrorString&amp;, const bool* includeSamples)
</ins><span class="cx"> {
</span><span class="cx">     if (m_tracking)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_tracking = true;
</span><span class="cx"> 
</span><del>-    if (profile &amp;&amp; *profile)
-        m_enableLegacyProfiler = true;
</del><ins>+#if ENABLE(SAMPLING_PROFILER)
+    if (includeSamples &amp;&amp; *includeSamples) {
+        VM&amp; vm = m_environment.scriptDebugServer().vm();
+        vm.ensureSamplingProfiler(m_environment.executionStopwatch());
</ins><span class="cx"> 
</span><ins>+        SamplingProfiler&amp; samplingProfiler = *vm.samplingProfiler();
+        LockHolder locker(samplingProfiler.getLock());
+
+        samplingProfiler.setStopWatch(locker, m_environment.executionStopwatch());
+        samplingProfiler.noticeCurrentThreadAsJSCExecutionThread(locker);
+        samplingProfiler.start(locker);
+        m_enabledSamplingProfiler = true;
+    }
+#else
+    UNUSED_PARAM(includeSamples);
+#endif // ENABLE(SAMPLING_PROFILER)
+
</ins><span class="cx">     m_environment.scriptDebugServer().setProfilingClient(this);
</span><span class="cx"> 
</span><span class="cx">     m_frontendDispatcher-&gt;trackingStart(m_environment.executionStopwatch()-&gt;elapsedTime());
</span><span class="lines">@@ -78,7 +92,6 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_tracking = false;
</span><del>-    m_enableLegacyProfiler = false;
</del><span class="cx">     m_activeEvaluateScript = false;
</span><span class="cx"> 
</span><span class="cx">     m_environment.scriptDebugServer().setProfilingClient(nullptr);
</span><span class="lines">@@ -91,23 +104,25 @@
</span><span class="cx">     return m_activeEvaluateScript;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-double InspectorScriptProfilerAgent::willEvaluateScript(JSGlobalObject&amp; globalObject)
</del><ins>+double InspectorScriptProfilerAgent::willEvaluateScript()
</ins><span class="cx"> {
</span><span class="cx">     m_activeEvaluateScript = true;
</span><span class="cx"> 
</span><del>-    if (m_enableLegacyProfiler)
-        LegacyProfiler::profiler()-&gt;startProfiling(globalObject.globalExec(), ASCIILiteral(&quot;ScriptProfiler&quot;), m_environment.executionStopwatch());
</del><ins>+#if ENABLE(SAMPLING_PROFILER)
+    if (m_enabledSamplingProfiler) {
+        SamplingProfiler* samplingProfiler = m_environment.scriptDebugServer().vm().samplingProfiler();
+        RELEASE_ASSERT(samplingProfiler);
+        samplingProfiler-&gt;noticeCurrentThreadAsJSCExecutionThread();
+    }
+#endif
</ins><span class="cx"> 
</span><span class="cx">     return m_environment.executionStopwatch()-&gt;elapsedTime();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorScriptProfilerAgent::didEvaluateScript(JSGlobalObject&amp; globalObject, double startTime, ProfilingReason reason)
</del><ins>+void InspectorScriptProfilerAgent::didEvaluateScript(double startTime, ProfilingReason reason)
</ins><span class="cx"> {
</span><span class="cx">     m_activeEvaluateScript = false;
</span><span class="cx"> 
</span><del>-    if (m_enableLegacyProfiler)
-        m_profiles.append(LegacyProfiler::profiler()-&gt;stopProfiling(globalObject.globalExec(), ASCIILiteral(&quot;ScriptProfiler&quot;)));
-
</del><span class="cx">     double endTime = m_environment.executionStopwatch()-&gt;elapsedTime();
</span><span class="cx"> 
</span><span class="cx">     addEvent(startTime, endTime, reason);
</span><span class="lines">@@ -141,71 +156,57 @@
</span><span class="cx">     m_frontendDispatcher-&gt;trackingUpdate(WTFMove(event));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static Ref&lt;Protocol::Timeline::CPUProfileNodeAggregateCallInfo&gt; buildAggregateCallInfoInspectorObject(const JSC::ProfileNode* node)
</del><ins>+#if ENABLE(SAMPLING_PROFILER)
+static Ref&lt;Protocol::ScriptProfiler::Samples&gt; buildSamples(Vector&lt;SamplingProfiler::StackTrace&gt;&amp; samplingProfilerStackTraces, double totalTime)
</ins><span class="cx"> {
</span><del>-    double startTime = node-&gt;calls()[0].startTime();
-    double endTime = node-&gt;calls().last().startTime() + node-&gt;calls().last().elapsedTime();
</del><ins>+    Ref&lt;Protocol::Array&lt;Protocol::ScriptProfiler::StackTrace&gt;&gt; stackTraces = Protocol::Array&lt;Protocol::ScriptProfiler::StackTrace&gt;::create();
+    for (SamplingProfiler::StackTrace&amp; stackTrace : samplingProfilerStackTraces) {
+        Ref&lt;Protocol::Array&lt;Protocol::ScriptProfiler::StackFrame&gt;&gt; frames = Protocol::Array&lt;Protocol::ScriptProfiler::StackFrame&gt;::create();
+        for (SamplingProfiler::StackFrame&amp; stackFrame : stackTrace.frames) {
+            Ref&lt;Protocol::ScriptProfiler::StackFrame&gt; frame = Protocol::ScriptProfiler::StackFrame::create()
+                .setSourceID(String::number(stackFrame.sourceID()))
+                .setName(stackFrame.displayName())
+                .setLine(stackFrame.startLine())
+                .setColumn(stackFrame.startColumn())
+                .setUrl(stackFrame.url())
+                .release();
+            frames-&gt;addItem(WTFMove(frame));
+        }
+        Ref&lt;Protocol::ScriptProfiler::StackTrace&gt; inspectorStackTrace = Protocol::ScriptProfiler::StackTrace::create()
+            .setTimestamp(stackTrace.timestamp)
+            .setStackFrames(WTFMove(frames))
+            .release();
+        stackTraces-&gt;addItem(WTFMove(inspectorStackTrace));
+    }
</ins><span class="cx"> 
</span><del>-    double totalTime = 0;
-    for (const JSC::ProfileNode::Call&amp; call : node-&gt;calls())
-        totalTime += call.elapsedTime();
-
-    return Protocol::Timeline::CPUProfileNodeAggregateCallInfo::create()
-        .setCallCount(node-&gt;calls().size())
-        .setStartTime(startTime)
-        .setEndTime(endTime)
</del><ins>+    return Protocol::ScriptProfiler::Samples::create()
+        .setStackTraces(WTFMove(stackTraces))
</ins><span class="cx">         .setTotalTime(totalTime)
</span><span class="cx">         .release();
</span><span class="cx"> }
</span><ins>+#endif // ENABLE(SAMPLING_PROFILER)
</ins><span class="cx"> 
</span><del>-static Ref&lt;Protocol::Timeline::CPUProfileNode&gt; buildInspectorObject(const JSC::ProfileNode* node)
</del><ins>+void InspectorScriptProfilerAgent::trackingComplete()
</ins><span class="cx"> {
</span><del>-    auto result = Protocol::Timeline::CPUProfileNode::create()
-        .setId(node-&gt;id())
-        .setCallInfo(buildAggregateCallInfoInspectorObject(node))
-        .release();
</del><ins>+#if ENABLE(SAMPLING_PROFILER)
+    if (m_enabledSamplingProfiler) {
+        SamplingProfiler* samplingProfiler = m_environment.scriptDebugServer().vm().samplingProfiler();
+        RELEASE_ASSERT(samplingProfiler);
+        LockHolder locker(samplingProfiler-&gt;getLock());
+        samplingProfiler-&gt;stop(locker);
+        Ref&lt;Protocol::ScriptProfiler::Samples&gt; samples = buildSamples(samplingProfiler-&gt;stackTraces(locker), samplingProfiler-&gt;totalTime(locker));
+        samplingProfiler-&gt;clearData(locker);
</ins><span class="cx"> 
</span><del>-    if (!node-&gt;functionName().isEmpty())
-        result-&gt;setFunctionName(node-&gt;functionName());
</del><ins>+        locker.unlockEarly();
</ins><span class="cx"> 
</span><del>-    if (!node-&gt;url().isEmpty()) {
-        result-&gt;setUrl(node-&gt;url());
-        result-&gt;setLineNumber(node-&gt;lineNumber());
-        result-&gt;setColumnNumber(node-&gt;columnNumber());
-    }
</del><ins>+        m_enabledSamplingProfiler = false;
</ins><span class="cx"> 
</span><del>-    if (!node-&gt;children().isEmpty()) {
-        auto children = Protocol::Array&lt;Protocol::Timeline::CPUProfileNode&gt;::create();
-        for (RefPtr&lt;JSC::ProfileNode&gt; profileNode : node-&gt;children())
-            children-&gt;addItem(buildInspectorObject(profileNode.get()));
-        result-&gt;setChildren(WTFMove(children));
-    }
-
-    return result;
</del><ins>+        m_frontendDispatcher-&gt;trackingComplete(WTFMove(samples));
+    } else
+        m_frontendDispatcher-&gt;trackingComplete(nullptr);
+#else
+    m_frontendDispatcher-&gt;trackingComplete(nullptr);
+#endif // ENABLE(SAMPLING_PROFILER)
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static Ref&lt;Protocol::Timeline::CPUProfile&gt; buildProfileInspectorObject(const JSC::Profile* profile)
-{
-    auto rootNodes = Protocol::Array&lt;Protocol::Timeline::CPUProfileNode&gt;::create();
-    for (RefPtr&lt;JSC::ProfileNode&gt; profileNode : profile-&gt;rootNode()-&gt;children())
-        rootNodes-&gt;addItem(buildInspectorObject(profileNode.get()));
-
-    return Protocol::Timeline::CPUProfile::create()
-        .setRootNodes(WTFMove(rootNodes))
-        .release();
-}
-
-void InspectorScriptProfilerAgent::trackingComplete()
-{
-    RefPtr&lt;Inspector::Protocol::Array&lt;InspectorValue&gt;&gt; profiles = Inspector::Protocol::Array&lt;InspectorValue&gt;::create();
-    for (auto&amp; profile : m_profiles) {
-        Ref&lt;InspectorValue&gt; value = buildProfileInspectorObject(profile.get());
-        profiles-&gt;addItem(WTFMove(value));
-    }
-
-    m_frontendDispatcher-&gt;trackingComplete(profiles);
-
-    m_profiles.clear();
-}
-
</del><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorScriptProfilerAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorScriptProfilerAgent.h	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -50,13 +50,13 @@
</span><span class="cx">     virtual void willDestroyFrontendAndBackend(DisconnectReason) override;
</span><span class="cx"> 
</span><span class="cx">     // ScriptProfilerBackendDispatcherHandler
</span><del>-    virtual void startTracking(ErrorString&amp;, const bool* profile) override;
</del><ins>+    virtual void startTracking(ErrorString&amp;, const bool* includeSamples) override;
</ins><span class="cx">     virtual void stopTracking(ErrorString&amp;) override;
</span><span class="cx"> 
</span><span class="cx">     // Debugger::ProfilingClient
</span><span class="cx">     virtual bool isAlreadyProfiling() const override;
</span><del>-    virtual double willEvaluateScript(JSC::JSGlobalObject&amp;) override;
-    virtual void didEvaluateScript(JSC::JSGlobalObject&amp;, double, JSC::ProfilingReason) override;
</del><ins>+    virtual double willEvaluateScript() override;
+    virtual void didEvaluateScript(double, JSC::ProfilingReason) override;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     struct Event {
</span><span class="lines">@@ -70,10 +70,9 @@
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;ScriptProfilerFrontendDispatcher&gt; m_frontendDispatcher;
</span><span class="cx">     RefPtr&lt;ScriptProfilerBackendDispatcher&gt; m_backendDispatcher;
</span><del>-    Vector&lt;RefPtr&lt;JSC::Profile&gt;&gt; m_profiles;
</del><span class="cx">     InspectorEnvironment&amp; m_environment;
</span><span class="cx">     bool m_tracking { false };
</span><del>-    bool m_enableLegacyProfiler { false };
</del><ins>+    bool m_enabledSamplingProfiler { false };
</ins><span class="cx">     bool m_activeEvaluateScript { false };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolScriptProfilerjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/inspector/protocol/ScriptProfiler.json	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -15,6 +15,33 @@
</span><span class="cx">                 { &quot;name&quot;: &quot;endTime&quot;, &quot;type&quot;: &quot;number&quot; },
</span><span class="cx">                 { &quot;name&quot;: &quot;type&quot;, &quot;$ref&quot;: &quot;EventType&quot; }
</span><span class="cx">             ]
</span><ins>+        },
+        {
+            &quot;id&quot;: &quot;StackFrame&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;sourceID&quot;, &quot;$ref&quot;: &quot;Debugger.ScriptId&quot;, &quot;description&quot;: &quot;Unique script identifier.&quot; },
+                { &quot;name&quot;: &quot;name&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;A displayable name for the stack frame. i.e function name, (program), etc.&quot; },
+                { &quot;name&quot;: &quot;line&quot;, &quot;type&quot;: &quot;integer&quot; },
+                { &quot;name&quot;: &quot;column&quot;, &quot;type&quot;: &quot;integer&quot; },
+                { &quot;name&quot;: &quot;url&quot;, &quot;type&quot;: &quot;string&quot; }
+            ]
+        },
+        {
+            &quot;id&quot;: &quot;StackTrace&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;timestamp&quot;, &quot;type&quot;: &quot;number&quot; },
+                { &quot;name&quot;: &quot;stackFrames&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;StackFrame&quot; }, &quot;description&quot;: &quot;First array item is the bottom of the call stack and last array item is the top of the call stack.&quot; }
+            ]
+        },
+        {
+            &quot;id&quot;: &quot;Samples&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;totalTime&quot;, &quot;type&quot;: &quot;number&quot;, &quot;description&quot;: &quot;Total execution time of the profiler's data. (Note: not total elapsed time.)&quot; },
+                { &quot;name&quot;: &quot;stackTraces&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;StackTrace&quot; } }
+            ]
</ins><span class="cx">         }
</span><span class="cx">     ],
</span><span class="cx">     &quot;commands&quot;: [
</span><span class="lines">@@ -22,7 +49,7 @@
</span><span class="cx">             &quot;name&quot;: &quot;startTracking&quot;,
</span><span class="cx">             &quot;description&quot;: &quot;Start tracking script evaluations.&quot;,
</span><span class="cx">             &quot;parameters&quot;: [
</span><del>-                { &quot;name&quot;: &quot;profile&quot;, &quot;type&quot;: &quot;boolean&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Profile script evaluations, defaults to false.&quot; }
</del><ins>+                { &quot;name&quot;: &quot;includeSamples&quot;, &quot;type&quot;: &quot;boolean&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Start the sampling profiler, defaults to false.&quot; }
</ins><span class="cx">             ]
</span><span class="cx">         },
</span><span class="cx">         {
</span><span class="lines">@@ -49,7 +76,7 @@
</span><span class="cx">             &quot;name&quot;: &quot;trackingComplete&quot;,
</span><span class="cx">             &quot;description&quot;: &quot;When tracking is complete the backend will send any buffered data, such as profiling information.&quot;,
</span><span class="cx">             &quot;parameters&quot;: [
</span><del>-                { &quot;name&quot;: &quot;profiles&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;any&quot; }, &quot;optional&quot;: true }
</del><ins>+                { &quot;name&quot;: &quot;samples&quot;, &quot;$ref&quot;: &quot;Samples&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Stack traces.&quot; }
</ins><span class="cx">             ]
</span><span class="cx">         }
</span><span class="cx">     ]
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/jsc.cpp	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -1642,7 +1642,7 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionSamplingProfilerStackTraces(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(exec-&gt;vm().samplingProfiler());
</span><del>-    String jsonString = exec-&gt;vm().samplingProfiler()-&gt;stacktracesAsJSON();
</del><ins>+    String jsonString = exec-&gt;vm().samplingProfiler()-&gt;stackTracesAsJSON();
</ins><span class="cx">     exec-&gt;vm().samplingProfiler()-&gt;clearData();
</span><span class="cx">     EncodedJSValue result = JSValue::encode(JSONParse(exec, jsonString));
</span><span class="cx">     RELEASE_ASSERT(!exec-&gt;hadException());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSamplingProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -405,6 +405,12 @@
</span><span class="cx"> void SamplingProfiler::start()
</span><span class="cx"> {
</span><span class="cx">     LockHolder locker(m_lock);
</span><ins>+    start(locker);
+}
+
+void SamplingProfiler::start(const LockHolder&amp; locker)
+{
+    ASSERT(m_lock.isLocked());
</ins><span class="cx">     m_isActive = true;
</span><span class="cx">     dispatchIfNecessary(locker);
</span><span class="cx"> }
</span><span class="lines">@@ -412,6 +418,12 @@
</span><span class="cx"> void SamplingProfiler::stop()
</span><span class="cx"> {
</span><span class="cx">     LockHolder locker(m_lock);
</span><ins>+    stop(locker);
+}
+
+void SamplingProfiler::stop(const LockHolder&amp;)
+{
+    ASSERT(m_lock.isLocked());
</ins><span class="cx">     m_isActive = false;
</span><span class="cx">     reportStats();
</span><span class="cx"> }
</span><span class="lines">@@ -469,48 +481,143 @@
</span><span class="cx"> void SamplingProfiler::clearData()
</span><span class="cx"> {
</span><span class="cx">     LockHolder locker(m_lock);
</span><ins>+    clearData(locker);
+}
+
+void SamplingProfiler::clearData(const LockHolder&amp;)
+{
+    ASSERT(m_lock.isLocked());
</ins><span class="cx">     m_stackTraces.clear();
</span><span class="cx">     m_seenExecutables.clear();
</span><span class="cx">     m_indexOfNextStackTraceToVerify = 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String displayName(const SamplingProfiler::StackFrame&amp; stackFrame)
</del><ins>+String SamplingProfiler::StackFrame::displayName()
</ins><span class="cx"> {
</span><del>-    if (stackFrame.frameType == FrameType::Unknown)
-        return ASCIILiteral(&quot;&lt;unknown&gt;&quot;);
-    if (stackFrame.frameType == FrameType::Host)
-        return ASCIILiteral(&quot;&lt;host&gt;&quot;);
-    RELEASE_ASSERT(stackFrame.frameType != FrameType::UnverifiedCallee);
</del><ins>+    if (frameType == FrameType::Unknown)
+        return ASCIILiteral(&quot;(unknown)&quot;);
+    if (frameType == FrameType::Host)
+        return ASCIILiteral(&quot;(host)&quot;);
+    RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee);
</ins><span class="cx"> 
</span><del>-    ExecutableBase* executable = stackFrame.u.verifiedExecutable;
</del><ins>+    ExecutableBase* executable = u.verifiedExecutable;
</ins><span class="cx">     if (executable-&gt;isHostFunction())
</span><del>-        return ASCIILiteral(&quot;&lt;host&gt;&quot;);
</del><ins>+        return static_cast&lt;NativeExecutable*&gt;(executable)-&gt;name();
</ins><span class="cx"> 
</span><ins>+    if (executable-&gt;isFunctionExecutable())
+        return static_cast&lt;FunctionExecutable*&gt;(executable)-&gt;inferredName().string();
+    if (executable-&gt;isProgramExecutable() || executable-&gt;isEvalExecutable())
+        return ASCIILiteral(&quot;(program)&quot;);
+    if (executable-&gt;isModuleProgramExecutable())
+        return ASCIILiteral(&quot;(module)&quot;);
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return String();
+}
+
+String SamplingProfiler::StackFrame::displayNameForJSONTests()
+{
+    if (frameType == FrameType::Unknown)
+        return ASCIILiteral(&quot;(unknown)&quot;);
+    if (frameType == FrameType::Host)
+        return ASCIILiteral(&quot;(host)&quot;);
+    RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee);
+
+    ExecutableBase* executable = u.verifiedExecutable;
+    if (executable-&gt;isHostFunction())
+        return static_cast&lt;NativeExecutable*&gt;(executable)-&gt;name();
+
</ins><span class="cx">     if (executable-&gt;isFunctionExecutable()) {
</span><span class="cx">         String result = static_cast&lt;FunctionExecutable*&gt;(executable)-&gt;inferredName().string();
</span><del>-        if (!result.isEmpty())
-            return result;
-        return ASCIILiteral(&quot;&lt;anonymous-function&gt;&quot;);
</del><ins>+        if (result.isEmpty())
+            return ASCIILiteral(&quot;(anonymous function)&quot;);
+        return result;
</ins><span class="cx">     }
</span><span class="cx">     if (executable-&gt;isEvalExecutable())
</span><del>-        return ASCIILiteral(&quot;&lt;eval&gt;&quot;);
</del><ins>+        return ASCIILiteral(&quot;(eval)&quot;);
</ins><span class="cx">     if (executable-&gt;isProgramExecutable())
</span><del>-        return ASCIILiteral(&quot;&lt;global&gt;&quot;);
</del><ins>+        return ASCIILiteral(&quot;(program)&quot;);
</ins><span class="cx">     if (executable-&gt;isModuleProgramExecutable())
</span><del>-        return ASCIILiteral(&quot;&lt;module&gt;&quot;);
</del><ins>+        return ASCIILiteral(&quot;(module)&quot;);
</ins><span class="cx"> 
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><del>-    return &quot;&quot;;
</del><ins>+    return String();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-String SamplingProfiler::stacktracesAsJSON()
</del><ins>+int SamplingProfiler::StackFrame::startLine()
</ins><span class="cx"> {
</span><del>-    m_lock.lock();
</del><ins>+    if (frameType == FrameType::Unknown || frameType == FrameType::Host)
+        return -1;
+    RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee);
+
+    ExecutableBase* executable = u.verifiedExecutable;
+    if (executable-&gt;isHostFunction())
+        return -1;
+    return static_cast&lt;ScriptExecutable*&gt;(executable)-&gt;firstLine();
+}
+
+unsigned SamplingProfiler::StackFrame::startColumn()
+{
+    if (frameType == FrameType::Unknown || frameType == FrameType::Host)
+        return -1;
+    RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee);
+
+    ExecutableBase* executable = u.verifiedExecutable;
+    if (executable-&gt;isHostFunction())
+        return -1;
+
+    return static_cast&lt;ScriptExecutable*&gt;(executable)-&gt;startColumn();
+}
+
+intptr_t SamplingProfiler::StackFrame::sourceID()
+{
+    if (frameType == FrameType::Unknown || frameType == FrameType::Host)
+        return -1;
+    RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee);
+
+    ExecutableBase* executable = u.verifiedExecutable;
+    if (executable-&gt;isHostFunction())
+        return -1;
+
+    return static_cast&lt;ScriptExecutable*&gt;(executable)-&gt;sourceID();
+}
+
+String SamplingProfiler::StackFrame::url()
+{
+    if (frameType == FrameType::Unknown || frameType == FrameType::Host)
+        return emptyString();
+    RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee);
+
+    ExecutableBase* executable = u.verifiedExecutable;
+    if (executable-&gt;isHostFunction())
+        return emptyString();
+
+    String url = static_cast&lt;ScriptExecutable*&gt;(executable)-&gt;sourceURL();
+    if (url.isEmpty())
+        return static_cast&lt;ScriptExecutable*&gt;(executable)-&gt;source().provider()-&gt;sourceURL(); // Fall back to sourceURL directive.
+    return url;
+}
+
+Vector&lt;SamplingProfiler::StackTrace&gt;&amp; SamplingProfiler::stackTraces(const LockHolder&amp;)
+{
+    ASSERT(m_lock.isLocked());
</ins><span class="cx">     {
</span><span class="cx">         HeapIterationScope heapIterationScope(m_vm.heap);
</span><span class="cx">         processUnverifiedStackTraces();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    return m_stackTraces;
+}
+
+String SamplingProfiler::stackTracesAsJSON()
+{
+    LockHolder locker(m_lock);
+
+    {
+        HeapIterationScope heapIterationScope(m_vm.heap);
+        processUnverifiedStackTraces();
+    }
+
</ins><span class="cx">     StringBuilder json;
</span><span class="cx">     json.appendLiteral(&quot;[&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -519,14 +626,14 @@
</span><span class="cx">         if (loopedOnce)
</span><span class="cx">             json.appendLiteral(&quot;,&quot;);
</span><span class="cx">     };
</span><del>-    for (const StackTrace&amp; stackTrace : m_stackTraces) {
</del><ins>+    for (StackTrace&amp; stackTrace : m_stackTraces) {
</ins><span class="cx">         comma();
</span><span class="cx">         json.appendLiteral(&quot;[&quot;);
</span><span class="cx">         loopedOnce = false;
</span><del>-        for (const StackFrame&amp; stackFrame : stackTrace.frames) {
</del><ins>+        for (StackFrame&amp; stackFrame : stackTrace.frames) {
</ins><span class="cx">             comma();
</span><span class="cx">             json.appendLiteral(&quot;\&quot;&quot;);
</span><del>-            json.append(displayName(stackFrame));
</del><ins>+            json.append(stackFrame.displayNameForJSONTests());
</ins><span class="cx">             json.appendLiteral(&quot;\&quot;&quot;);
</span><span class="cx">             loopedOnce = true;
</span><span class="cx">         }
</span><span class="lines">@@ -536,8 +643,6 @@
</span><span class="cx"> 
</span><span class="cx">     json.appendLiteral(&quot;]&quot;);
</span><span class="cx"> 
</span><del>-    m_lock.unlock();
-
</del><span class="cx">     return json.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSamplingProfilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">         Host, 
</span><span class="cx">         Unknown 
</span><span class="cx">     };
</span><ins>+
</ins><span class="cx">     struct StackFrame {
</span><span class="cx">         StackFrame(FrameType frameType, EncodedJSValue callee)
</span><span class="cx">             : frameType(frameType)
</span><span class="lines">@@ -72,7 +73,15 @@
</span><span class="cx">             EncodedJSValue unverifiedCallee;
</span><span class="cx">             ExecutableBase* verifiedExecutable;
</span><span class="cx">         } u;
</span><ins>+
+        String displayName();
+        String displayNameForJSONTests(); // Used for JSC stress tests because they want the &quot;(anonymous function)&quot; string for anonymous functions and they want &quot;(eval)&quot; for eval'd code.
+        int startLine();
+        unsigned startColumn();
+        intptr_t sourceID();
+        String url();
</ins><span class="cx">     };
</span><ins>+
</ins><span class="cx">     struct StackTrace {
</span><span class="cx">         bool needsVerification;
</span><span class="cx">         double timestamp;
</span><span class="lines">@@ -88,13 +97,18 @@
</span><span class="cx">     Lock&amp; getLock() { return m_lock; }
</span><span class="cx">     void setTimingInterval(std::chrono::microseconds interval) { m_timingInterval = interval; }
</span><span class="cx">     JS_EXPORT_PRIVATE void start();
</span><ins>+    void start(const LockHolder&amp;);
</ins><span class="cx">     void stop();
</span><del>-    const Vector&lt;StackTrace&gt;&amp; stackTraces() const { return m_stackTraces; }
-    JS_EXPORT_PRIVATE String stacktracesAsJSON();
</del><ins>+    void stop(const LockHolder&amp;);
+    Vector&lt;StackTrace&gt;&amp; stackTraces(const LockHolder&amp;);
+    JS_EXPORT_PRIVATE String stackTracesAsJSON();
</ins><span class="cx">     JS_EXPORT_PRIVATE void noticeCurrentThreadAsJSCExecutionThread();
</span><span class="cx">     void noticeCurrentThreadAsJSCExecutionThread(const LockHolder&amp;);
</span><span class="cx">     JS_EXPORT_PRIVATE void clearData();
</span><ins>+    void clearData(const LockHolder&amp;);
</ins><span class="cx">     void processUnverifiedStackTraces(); // You should call this only after acquiring the lock.
</span><ins>+    double totalTime(const LockHolder&amp;) { return m_totalTime; }
+    void setStopWatch(const LockHolder&amp;, Ref&lt;Stopwatch&gt;&amp;&amp; stopwatch) { m_stopwatch = WTFMove(stopwatch); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void dispatchIfNecessary(const LockHolder&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssamplingprofilersamplingProfilerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/sampling-profiler/samplingProfiler.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/sampling-profiler/samplingProfiler.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/tests/stress/sampling-profiler/samplingProfiler.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx">     // stack trace should be top-down array with the deepest
</span><span class="cx">     // call frame at index 0.
</span><span class="cx">     if (isRunFromRunTest)
</span><del>-        stackTrace = [...stackTrace, &quot;runTest&quot;, &quot;&lt;global&gt;&quot;];
</del><ins>+        stackTrace = [...stackTrace, &quot;runTest&quot;, &quot;(program)&quot;];
</ins><span class="cx">     else
</span><span class="cx">         stackTrace = [...stackTrace];
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssamplingprofileranonymousfunctionjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-anonymous-function.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-anonymous-function.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-anonymous-function.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -18,5 +18,5 @@
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    runTest(baz, [&quot;&lt;anonymous-function&gt;&quot;, &quot;foo&quot;, &quot;baz&quot;]);
</del><ins>+    runTest(baz, [&quot;(anonymous function)&quot;, &quot;foo&quot;, &quot;baz&quot;]);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssamplingprofilerbasicjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-basic.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-basic.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/JavaScriptCore/tests/stress/sampling-profiler-basic.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -17,7 +17,7 @@
</span><span class="cx">     function nothing(x) { return x; }
</span><span class="cx">     noInline(nothing);
</span><span class="cx"> 
</span><del>-    runTest(foo, [&quot;&lt;host&gt;&quot;, &quot;bar&quot;, &quot;foo&quot;]);
</del><ins>+    runTest(foo, [&quot;(host)&quot;, &quot;bar&quot;, &quot;foo&quot;]);
</ins><span class="cx"> 
</span><span class="cx">     function top() { 
</span><span class="cx">         let x = 0;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2016-01-20  Saam barati  &lt;sbarati at apple.com&gt;
+
+        Web Inspector: Hook the sampling profiler into the Timelines UI
+        https://bugs.webkit.org/show_bug.cgi?id=152766
+        &lt;rdar://problem/24066360&gt;
+
+        Reviewed by Joseph Pecoraro.
+
+        The main change in this patch is to swap in the SamplingProfiler
+        in place of the LegacyProfiler. To do this, we've created a data
+        structure called CallingContextTree which aggregates the SamplingProfiler's
+        data into an easy to manage tree. To see how the data structure works,
+        consider the following program:
+        ```
+        function bar() { // run code here for a long time. }
+        function baz() { // run code here for a long time. }
+        function foo() { bar(); baz(); }
+        foo();
+        ```
+        From this program, we will create a tree like this:
+                        (program)
+                            |
+                            |
+                           foo
+                           | |
+                          /   \
+                         /     \
+                        bar     baz
+        
+        From this type of tree, we can easily create a CPUProfile payload
+        object. Because the Timelines UI knows how to interact with the
+        CPUProfile object and display it, we currently map the tree to this object
+        to make it trivially easy to display the SamplingProfiler's data. In the future,
+        we may want to find ways to work directly with the CallingContextTree instead
+        of mapping it into another object.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Controllers/TimelineManager.js:
+        * UserInterface/Main.html:
+        * UserInterface/Models/CallingContextTree.js: Added.
+        * UserInterface/Models/ScriptInstrument.js:
+        * UserInterface/Protocol/ScriptProfilerObserver.js:
+        * UserInterface/TestStub.html:
+        * UserInterface/Views/ScriptTimelineView.js:
+
</ins><span class="cx"> 2016-01-19  Joseph Pecoraro  &lt;pecoraro at apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Uncaught exception when logging an Error object
</span></span></pre></div>
<a id="trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -544,6 +544,7 @@
</span><span class="cx"> localizedStrings[&quot;Reveal in Original Resource&quot;] = &quot;Reveal in Original Resource&quot;;
</span><span class="cx"> localizedStrings[&quot;Right&quot;] = &quot;Right&quot;;
</span><span class="cx"> localizedStrings[&quot;Role&quot;] = &quot;Role&quot;;
</span><ins>+localizedStrings[&quot;Samples&quot;] = &quot;Samples&quot;;
</ins><span class="cx"> localizedStrings[&quot;Scheme&quot;] = &quot;Scheme&quot;;
</span><span class="cx"> localizedStrings[&quot;Scope Chain&quot;] = &quot;Scope Chain&quot;;
</span><span class="cx"> localizedStrings[&quot;Script&quot;] = &quot;Script&quot;;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -45,6 +45,8 @@
</span><span class="cx">         this._webTimelineScriptRecordsExpectingScriptProfilerEvents = null;
</span><span class="cx">         this._scriptProfilerRecords = null;
</span><span class="cx"> 
</span><ins>+        this._callingContextTree = null;
+
</ins><span class="cx">         this.reset();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -682,15 +684,23 @@
</span><span class="cx">             this._addRecord(record);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    scriptProfilerTrackingCompleted(profiles)
</del><ins>+    scriptProfilerTrackingCompleted(samples)
</ins><span class="cx">     {
</span><span class="cx">         console.assert(!this._webTimelineScriptRecordsExpectingScriptProfilerEvents || this._scriptProfilerRecords.length &gt;= this._webTimelineScriptRecordsExpectingScriptProfilerEvents.length);
</span><span class="cx"> 
</span><del>-        // Associate the profiles with the ScriptProfiler created records.
-        if (profiles) {
-            console.assert(this._scriptProfilerRecords.length === profiles.length, this._scriptProfilerRecords.length, profiles.length);
-            for (let i = 0; i &lt; this._scriptProfilerRecords.length; ++i)
-                this._scriptProfilerRecords[i].profilePayload = profiles[i];
</del><ins>+        if (samples) {
+            if (!this._callingContextTree)
+                this._callingContextTree = new WebInspector.CallingContextTree;
+
+            // Associate the stackTraces with the ScriptProfiler created records.
+            let stackTraces = samples.stackTraces;
+            for (let i = 0; i &lt; stackTraces.length; i++)
+                this._callingContextTree.updateTreeWithStackTrace(stackTraces[i]);
+
+            for (let i = 0; i &lt; this._scriptProfilerRecords.length; ++i) {
+                let record = this._scriptProfilerRecords[i];
+                record.profilePayload = this._callingContextTree.toCPUProfilePayload(record.startTime, record.endTime);
+            }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Associate the ScriptProfiler created records with Web Timeline records.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -269,6 +269,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/BackForwardEntry.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Branch.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Breakpoint.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/CallingContextTree.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/CSSCompletions.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CSSKeywordCompletions.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CSSMedia.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreejs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js (0 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -0,0 +1,278 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. 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 INC. AND ITS CONTRIBUTORS ``AS IS''
+ * 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 INC. 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.
+ */
+
+WebInspector.CallingContextTree = class CallingContextTree extends WebInspector.Object
+{
+    constructor()
+    {
+        super();
+
+        this._root = new WebInspector.CCTNode(-1, -1, -1, &quot;&lt;root&gt;&quot;, null);
+        this._totalNumberOfSamples = 0;
+    }
+
+    // Public
+
+    get totalNumberOfSamples() { return this._totalNumberOfSamples; }
+    
+    updateTreeWithStackTrace({timestamp, stackFrames})
+    {
+        this._totalNumberOfSamples++;
+        let node = this._root;
+        node.addTimestamp(timestamp);
+        for (let i = stackFrames.length; i--; ) {
+            let stackFrame = stackFrames[i];
+            node = node.findOrMakeChild(stackFrame);
+            node.addTimestamp(timestamp);
+        }
+    }
+
+    toCPUProfilePayload(startTime, endTime)
+    {
+        let cpuProfile = {};
+        let roots = [];
+        let numSamplesInTimeRange = this._root.filteredTimestamps(startTime, endTime).length;
+
+        this._root.forEachChild((child) =&gt; {
+            if (child.hasStackTraceInTimeRange(startTime, endTime))
+                roots.push(child.toCPUProfileNode(numSamplesInTimeRange, startTime, endTime)); 
+        });
+
+        cpuProfile.rootNodes = roots;
+        return cpuProfile;
+    }
+
+    forEachNode(callback)
+    {
+        this._root.forEachNode(callback);
+    }
+
+    // Testing.
+
+    static __test_makeTreeFromProtocolMessageObject(messageObject)
+    {
+        let tree = new WebInspector.CallingContextTree;
+        let stackTraces = messageObject.params.samples.stackTraces;
+        for (let i = 0; i &lt; stackTraces.length; i++)
+            tree.updateTreeWithStackTrace(stackTraces[i]);
+        return tree;
+    }
+
+    __test_matchesStackTrace(stackTrace)
+    {
+        // StackTrace should have top frame first in the array and bottom frame last.
+        // We don't look for a match that traces down the tree from the root; instead,
+        // we match by looking at all the leafs, and matching while walking up the tree
+        // towards the root. If we successfully make the walk, we've got a match that
+        // suffices for a particular test. A successful match doesn't mean we actually
+        // walk all the way up to the root; it just means we didn't fail while walking
+        // in the direction of the root.
+        let leaves = this.__test_buildLeafLinkedLists();
+
+        outer:
+        for (let node of leaves) {
+            for (let stackNode of stackTrace) {
+                for (let propertyName of Object.getOwnPropertyNames(stackNode)) {
+                    if (stackNode[propertyName] !== node[propertyName])
+                        continue outer;
+                }
+                node = node.parent;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    __test_buildLeafLinkedLists()
+    {
+        let result = [];
+        let parent = null;
+        this._root.__test_buildLeafLinkedLists(parent, result);
+        return result;
+    }
+};
+
+WebInspector.CCTNode = class CCTNode extends WebInspector.Object
+{
+    constructor(sourceID, line, column, name, url)
+    {
+        super();
+
+        this._children = {};
+        this._sourceID = sourceID;
+        this._line = line;
+        this._column = column;
+        this._name = name;
+        this._url = url;
+        this._timestamps = [];
+        this._uid = WebInspector.CCTNode.__uid++;
+    }
+
+    // Static and Private
+
+    static _hash(stackFrame)
+    {
+        return stackFrame.name + &quot;:&quot; + stackFrame.sourceID + &quot;:&quot; + stackFrame.line + &quot;:&quot; + stackFrame.column;
+    }
+
+    // Public
+
+    get sourceID() { return this._sourceID; }
+    get line() { return this._line; }
+    get column() { return this._column; }
+    get name() { return this._name; }
+    get uid() { return this._uid; }
+    get url() { return this._url; }
+
+    hasStackTraceInTimeRange(startTime, endTime)
+    {
+        console.assert(startTime &lt;= endTime);
+        if (startTime &gt; endTime)
+            return false;
+
+        let timestamps = this._timestamps;
+        let length = timestamps.length;
+        if (!length)
+            return false;
+
+        let index = timestamps.lowerBound(startTime);
+        if (index === length)
+            return false;
+        console.assert(startTime &lt;= timestamps[index]);
+
+        let hasTimestampInRange = timestamps[index] &lt;= endTime;
+        return hasTimestampInRange;
+    }
+
+    filteredTimestamps(startTime, endTime)
+    {
+        let index = this._timestamps.lowerBound(startTime); // The left-most (smallest) item that is &gt;= startTime.
+        let result = [];
+        for (; index &lt; this._timestamps.length; index++) {
+            let timestamp = this._timestamps[index];
+            console.assert(startTime &lt;= timestamp);
+            if (!(timestamp &lt;= endTime))
+                break;
+            result.push(timestamp);
+        }
+        return result;
+    }
+
+    hasChildren()
+    {
+        return !!Object.getOwnPropertyNames(this._children).length;
+    }
+
+    findOrMakeChild(stackFrame)
+    {
+        let hash = WebInspector.CCTNode._hash(stackFrame);
+        let node = this._children[hash];
+        if (node)
+            return node;
+        node = new WebInspector.CCTNode(stackFrame.sourceID, stackFrame.line, stackFrame.column, stackFrame.name, stackFrame.url);
+        this._children[hash] = node;
+        return node;
+    }
+
+    addTimestamp(timestamp)
+    {
+        console.assert(!this._timestamps.length || this._timestamps.lastValue &lt;= timestamp, &quot;Expected timestamps to be added in sorted, increasing, order.&quot;);
+        this._timestamps.push(timestamp);
+    }
+
+    forEachChild(callback)
+    {
+        for (let propertyName of Object.getOwnPropertyNames(this._children))
+            callback(this._children[propertyName]);
+    }
+
+    forEachNode(callback)
+    {
+        callback(this);
+        this.forEachChild(function(child) {
+            child.forEachNode(callback);
+        });
+    }
+
+    toCPUProfileNode(numSamples, startTime, endTime)
+    {
+        let children = [];
+        this.forEachChild((child) =&gt; {
+            if (child.hasStackTraceInTimeRange(startTime, endTime))
+                children.push(child.toCPUProfileNode(numSamples, startTime, endTime));
+        });
+        let cpuProfileNode = {
+            id: this._uid,
+            functionName: this._name,
+            url: this._url,
+            lineNumber: this._line,
+            columnNumber: this._column,
+            children: children
+        };
+
+        let timestamps = [];
+        let frameStartTime = Number.MAX_VALUE;
+        let frameEndTime = Number.MIN_VALUE;
+        for (let i = 0; i &lt; this._timestamps.length; i++) {
+            let timestamp = this._timestamps[i];
+            if (startTime &lt;= timestamp &amp;&amp; timestamp &lt;= endTime) {
+                timestamps.push(timestamp);
+                frameStartTime = Math.min(frameStartTime, timestamp);
+                frameEndTime = Math.max(frameEndTime, timestamp);
+            }
+        }
+
+        cpuProfileNode.callInfo = {
+            callCount: timestamps.length, // Totally not callCount, but oh well, this makes life easier because of field names.
+            startTime: frameStartTime,
+            endTime: frameEndTime,
+            totalTime: (timestamps.length / numSamples) * (endTime - startTime)
+        };
+
+        return cpuProfileNode;
+    }
+
+    // Testing.
+
+    __test_buildLeafLinkedLists(parent, result)
+    {
+        let linkedListNode = {
+            name: this._name,
+            url: this._url,
+            parent: parent
+        };
+        if (this.hasChildren()) {
+            this.forEachChild((child) =&gt; {
+                child.__test_buildLeafLinkedLists(linkedListNode, result);
+            });
+        } else {
+            // We're a leaf.
+            result.push(linkedListNode);
+        }
+    }
+};
+
+WebInspector.CCTNode.__uid = 0;
+
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScriptInstrumentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptInstrument.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -41,9 +41,9 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // FIXME: Make this some UI visible option.
</span><del>-        const includeProfiles = true;
</del><ins>+        const includeSamples = true;
</ins><span class="cx"> 
</span><del>-        ScriptProfilerAgent.startTracking(includeProfiles);
</del><ins>+        ScriptProfilerAgent.startTracking(includeSamples);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     stopInstrumentation()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolScriptProfilerObserverjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/ScriptProfilerObserver.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -37,8 +37,8 @@
</span><span class="cx">         WebInspector.timelineManager.scriptProfilerTrackingUpdated(event);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    trackingComplete(profiles)
</del><ins>+    trackingComplete(samples)
</ins><span class="cx">     {
</span><del>-        WebInspector.timelineManager.scriptProfilerTrackingCompleted(profiles);
</del><ins>+        WebInspector.timelineManager.scriptProfilerTrackingCompleted(samples);
</ins><span class="cx">     }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTestStubhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TestStub.html (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TestStub.html	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/UserInterface/TestStub.html	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -33,7 +33,10 @@
</span><span class="cx">     &lt;script src=&quot;Base/LinkedList.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/ListMultimap.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/Object.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Base/Utilities.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><ins>+    &lt;script src=&quot;Models/CallingContextTree.js&quot;&gt;&lt;/script&gt;
+
</ins><span class="cx">     &lt;script src=&quot;Test/TestSuite.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Test/TestHarness.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Test/ProtocolTestHarness.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsScriptTimelineViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineView.js (195375 => 195376)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineView.js	2016-01-20 21:49:09 UTC (rev 195375)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineView.js	2016-01-20 21:51:00 UTC (rev 195376)
</span><span class="lines">@@ -38,7 +38,13 @@
</span><span class="cx">         columns.location.title = WebInspector.UIString(&quot;Location&quot;);
</span><span class="cx">         columns.location.width = &quot;15%&quot;;
</span><span class="cx"> 
</span><del>-        columns.callCount.title = WebInspector.UIString(&quot;Calls&quot;);
</del><ins>+        let isSamplingProfiler = !!window.ScriptProfilerAgent;
+        if (isSamplingProfiler)
+            columns.callCount.title = WebInspector.UIString(&quot;Samples&quot;);
+        else {
+            // COMPATIBILITY(iOS 9): ScriptProfilerAgent did not exist yet, we had call counts, not samples.
+            columns.callCount.title = WebInspector.UIString(&quot;Calls&quot;);
+        }
</ins><span class="cx">         columns.callCount.width = &quot;5%&quot;;
</span><span class="cx">         columns.callCount.aligned = &quot;right&quot;;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>


More information about the webkit-changes mailing list