<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[202157] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/202157">202157</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-06-16 21:48:47 -0700 (Thu, 16 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Baseline JIT should be concurrent
https://bugs.webkit.org/show_bug.cgi?id=158755

Reviewed by Geoffrey Garen.
        
Source/JavaScriptCore:

This makes the baseline JIT concurrent. We want it to be concurrent because it takes up
about 1% of PLT3 and 10% of JSBench (though the JSBench number might be down from recent
optimizations).
        
The idea is really simple: I separated the compile and link phases of JIT::privateCompile(),
and arranged to call the compile phase from another thread. This doesn't reuse the old
DFG::Worklist code, because that code does things we don't need (like compilation plan
cancellation to allow GC to interleave with compilations) and is structured in a way that
would have required more changes to the baseline JIT. Also, I think that code uses the wrong
API, and as a result, clients of that API have a bad time. For example, it's never clear who
has the responsibility of setting the JIT thresholds and the DFG::Worklist goes to great
lengths to try to help its client set those things correctly, but since it doesn't set them
directly, the client then has to have additional complex logic to combine what it learned
from the Worklist and what it knows to set the thresholds. This patch takes a simpler
approach: the JITWorklist takes complete control over scheduling compilations. It's like a
combination of DFG::Worklist and operationOptimize().
        
Because the baseline JIT runs quickly, we can take some shortcuts. The JITWorklist requires
that all of its plans complete before a GC begins. This ensures that we don't have to worry
about interactions between the concurrent baseline JIT and the GC.
        
I needed to do a bunch of minor changes to the JIT to handle the races that emerged. For
example, I needed to do things to opcodes that read profiling both in the main path code
generator and the slow path one. One trick I used was to create a copy of the instruction
stream and provide that for anyone interested in the original value of the profiles. Most
code still uses the CodeBlock's instruction stream because it may emit JIT code that points
at the stream.
        
This also fixes a LLInt bug in prototype caching. This bug was revealed by this change
because more of our LayoutTests now run in LLInt.
        
This looks like it might be a ~1% Octane speed-up (on command line) and a ~0.7% PLT3
speed-up. This also looks like a ~2% JSBench speed-up.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* debugger/Debugger.cpp:
(JSC::Debugger::setSteppingMode):
(JSC::Debugger::toggleBreakpoint):
(JSC::Debugger::clearBreakpoints):
(JSC::Debugger::clearDebuggerRequests):
* dfg/DFGOSRExitPreparation.cpp:
(JSC::DFG::prepareCodeOriginForOSRExit):
* heap/Heap.cpp:
(JSC::Heap::didFinishIterating):
(JSC::Heap::completeAllJITPlans):
(JSC::Heap::deleteAllCodeBlocks):
(JSC::Heap::collectImpl):
(JSC::Heap::completeAllDFGPlans): Deleted.
* heap/Heap.h:
* heap/HeapInlines.h:
(JSC::Heap::forEachCodeBlock):
* jit/JIT.cpp:
(JSC::JIT::emitNotifyWrite):
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::compileWithoutLinking):
(JSC::JIT::link):
(JSC::JIT::privateCompile):
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JIT.h:
(JSC::JIT::compile):
(JSC::JIT::getSlowCase):
(JSC::JIT::linkSlowCase):
(JSC::JIT::linkDummySlowCase):
* jit/JITInlines.h:
(JSC::JIT::emitTagBool):
(JSC::JIT::originalInstruction):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitSlow_op_put_to_scope):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitSlow_op_put_by_val):
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emitSlow_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitSlow_op_get_from_scope):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
* jit/JITWorklist.cpp: Added.
(JSC::JITWorklist::Plan::Plan):
(JSC::JITWorklist::Plan::compileInThread):
(JSC::JITWorklist::Plan::finalize):
(JSC::JITWorklist::Plan::codeBlock):
(JSC::JITWorklist::Plan::vm):
(JSC::JITWorklist::Plan::isFinishedCompiling):
(JSC::JITWorklist::Plan::isFinalized):
(JSC::JITWorklist::JITWorklist):
(JSC::JITWorklist::~JITWorklist):
(JSC::JITWorklist::completeAllForVM):
(JSC::JITWorklist::poll):
(JSC::JITWorklist::compileLater):
(JSC::JITWorklist::compileNow):
(JSC::JITWorklist::runThread):
(JSC::JITWorklist::finalizePlans):
(JSC::JITWorklist::instance):
* jit/JITWorklist.h: Added.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
(JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
* runtime/VM.cpp:
(JSC::VM::~VM):

Source/WTF:

The concurrent baseline JIT needs to be able to clone bytecode to get a consistent snapshot.
So, this adds such a method.

* wtf/RefCountedArray.h:
(WTF::RefCountedArray::RefCountedArray):
(WTF::RefCountedArray::clone):

Tools:

Need to disable concurrent JIT when running profiler tests. We should have been doing this
all along.

* Scripts/run-jsc-stress-tests:

LayoutTests:

This change revealed a latent bug in the LLInt.  The non-llint version of this new test
would usually fail because it was still in LLInt.  This new test always fails.

* js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.html: Added.
* js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint-expected.txt: Added.
* js/dom/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggercpp">trunk/Source/JavaScriptCore/debugger/Debugger.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitPreparationcpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapInlinesh">trunk/Source/JavaScriptCore/heap/HeapInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCallcpp">trunk/Source/JavaScriptCore/jit/JITCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlinesh">trunk/Source/JavaScriptCore/jit/JITInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfRefCountedArrayh">trunk/Source/WTF/wtf/RefCountedArray.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsrunjscstresstests">trunk/Tools/Scripts/run-jsc-stress-tests</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsdomprototypechaincachingwithimpuregetownpropertyslottrapsllintexpectedtxt">trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomprototypechaincachingwithimpuregetownpropertyslottrapsllinthtml">trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.html</a></li>
<li><a href="#trunkLayoutTestsjsdomscripttestsprototypechaincachingwithimpuregetownpropertyslottrapsllintjs">trunk/LayoutTests/js/dom/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITWorklistcpp">trunk/Source/JavaScriptCore/jit/JITWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITWorklisth">trunk/Source/JavaScriptCore/jit/JITWorklist.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/LayoutTests/ChangeLog        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-06-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Baseline JIT should be concurrent
+        https://bugs.webkit.org/show_bug.cgi?id=158755
+
+        Reviewed by Geoffrey Garen.
+        
+        This change revealed a latent bug in the LLInt.  The non-llint version of this new test
+        would usually fail because it was still in LLInt.  This new test always fails.
+
+        * js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.html: Added.
+        * js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint-expected.txt: Added.
+        * js/dom/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js: Added.
+
</ins><span class="cx"> 2016-06-16  Frederic Wang  &lt;fwang@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add separate MathOperator for selection/measuring/drawing of stretchy operators
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomprototypechaincachingwithimpuregetownpropertyslottrapsllintexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint-expected.txt (0 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint-expected.txt        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+Tests what happens when you make prototype chain accesses with impure GetOwnPropertySlot traps in the way.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;function&quot;
+PASS typeof result is &quot;object&quot;
+PASS typeof result is &quot;object&quot;
+PASS typeof result is &quot;object&quot;
+PASS typeof result is &quot;object&quot;
+PASS typeof result is &quot;object&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsdomprototypechaincachingwithimpuregetownpropertyslottrapsllinthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.html (0 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.html                                (rev 0)
+++ trunk/LayoutTests/js/dom/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.html        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsdomscripttestsprototypechaincachingwithimpuregetownpropertyslottrapsllintjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/dom/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js (0 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js                                (rev 0)
+++ trunk/LayoutTests/js/dom/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps-llint.js        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+description(
+&quot;Tests what happens when you make prototype chain accesses with impure GetOwnPropertySlot traps in the way.&quot;
+);
+
+var doc = document;
+
+var expected = &quot;\&quot;function\&quot;&quot;;
+for (var i = 0; i &lt; 40; ++i) {
+    if (i == 35) {
+        var img = new Image();
+        img.name = &quot;getElementsByTagName&quot;;
+        document.body.appendChild(img);
+        expected = &quot;\&quot;object\&quot;&quot;;
+    }
+    var result = doc.getElementsByTagName;
+    shouldBe(&quot;typeof result&quot;, expected);
+}
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -555,6 +555,7 @@
</span><span class="cx">     jit/JITSubGenerator.cpp
</span><span class="cx">     jit/JITThunks.cpp
</span><span class="cx">     jit/JITToDFGDeferredCompilationCallback.cpp
</span><ins>+    jit/JITWorklist.cpp
</ins><span class="cx">     jit/PCToCodeOriginMap.cpp
</span><span class="cx">     jit/PolymorphicCallStubRoutine.cpp
</span><span class="cx">     jit/Reg.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1,3 +1,116 @@
</span><ins>+2016-06-14  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Baseline JIT should be concurrent
+        https://bugs.webkit.org/show_bug.cgi?id=158755
+
+        Reviewed by Geoffrey Garen.
+        
+        This makes the baseline JIT concurrent. We want it to be concurrent because it takes up
+        about 1% of PLT3 and 10% of JSBench (though the JSBench number might be down from recent
+        optimizations).
+        
+        The idea is really simple: I separated the compile and link phases of JIT::privateCompile(),
+        and arranged to call the compile phase from another thread. This doesn't reuse the old
+        DFG::Worklist code, because that code does things we don't need (like compilation plan
+        cancellation to allow GC to interleave with compilations) and is structured in a way that
+        would have required more changes to the baseline JIT. Also, I think that code uses the wrong
+        API, and as a result, clients of that API have a bad time. For example, it's never clear who
+        has the responsibility of setting the JIT thresholds and the DFG::Worklist goes to great
+        lengths to try to help its client set those things correctly, but since it doesn't set them
+        directly, the client then has to have additional complex logic to combine what it learned
+        from the Worklist and what it knows to set the thresholds. This patch takes a simpler
+        approach: the JITWorklist takes complete control over scheduling compilations. It's like a
+        combination of DFG::Worklist and operationOptimize().
+        
+        Because the baseline JIT runs quickly, we can take some shortcuts. The JITWorklist requires
+        that all of its plans complete before a GC begins. This ensures that we don't have to worry
+        about interactions between the concurrent baseline JIT and the GC.
+        
+        I needed to do a bunch of minor changes to the JIT to handle the races that emerged. For
+        example, I needed to do things to opcodes that read profiling both in the main path code
+        generator and the slow path one. One trick I used was to create a copy of the instruction
+        stream and provide that for anyone interested in the original value of the profiles. Most
+        code still uses the CodeBlock's instruction stream because it may emit JIT code that points
+        at the stream.
+        
+        This also fixes a LLInt bug in prototype caching. This bug was revealed by this change
+        because more of our LayoutTests now run in LLInt.
+        
+        This looks like it might be a ~1% Octane speed-up (on command line) and a ~0.7% PLT3
+        speed-up. This also looks like a ~2% JSBench speed-up.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::setSteppingMode):
+        (JSC::Debugger::toggleBreakpoint):
+        (JSC::Debugger::clearBreakpoints):
+        (JSC::Debugger::clearDebuggerRequests):
+        * dfg/DFGOSRExitPreparation.cpp:
+        (JSC::DFG::prepareCodeOriginForOSRExit):
+        * heap/Heap.cpp:
+        (JSC::Heap::didFinishIterating):
+        (JSC::Heap::completeAllJITPlans):
+        (JSC::Heap::deleteAllCodeBlocks):
+        (JSC::Heap::collectImpl):
+        (JSC::Heap::completeAllDFGPlans): Deleted.
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::forEachCodeBlock):
+        * jit/JIT.cpp:
+        (JSC::JIT::emitNotifyWrite):
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        (JSC::JIT::compileWithoutLinking):
+        (JSC::JIT::link):
+        (JSC::JIT::privateCompile):
+        (JSC::JIT::privateCompileExceptionHandlers):
+        * jit/JIT.h:
+        (JSC::JIT::compile):
+        (JSC::JIT::getSlowCase):
+        (JSC::JIT::linkSlowCase):
+        (JSC::JIT::linkDummySlowCase):
+        * jit/JITInlines.h:
+        (JSC::JIT::emitTagBool):
+        (JSC::JIT::originalInstruction):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitSlow_op_put_by_val):
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emitSlow_op_resolve_scope):
+        (JSC::JIT::emit_op_get_from_scope):
+        (JSC::JIT::emitSlow_op_get_from_scope):
+        (JSC::JIT::emit_op_put_to_scope):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        * jit/JITWorklist.cpp: Added.
+        (JSC::JITWorklist::Plan::Plan):
+        (JSC::JITWorklist::Plan::compileInThread):
+        (JSC::JITWorklist::Plan::finalize):
+        (JSC::JITWorklist::Plan::codeBlock):
+        (JSC::JITWorklist::Plan::vm):
+        (JSC::JITWorklist::Plan::isFinishedCompiling):
+        (JSC::JITWorklist::Plan::isFinalized):
+        (JSC::JITWorklist::JITWorklist):
+        (JSC::JITWorklist::~JITWorklist):
+        (JSC::JITWorklist::completeAllForVM):
+        (JSC::JITWorklist::poll):
+        (JSC::JITWorklist::compileLater):
+        (JSC::JITWorklist::compileNow):
+        (JSC::JITWorklist::runThread):
+        (JSC::JITWorklist::finalizePlans):
+        (JSC::JITWorklist::instance):
+        * jit/JITWorklist.h: Added.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::jitCompileAndSetHeuristics):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::tryCachePutToScopeGlobal):
+        (JSC::CommonSlowPaths::tryCacheGetFromScopeGlobal):
+        * runtime/VM.cpp:
+        (JSC::VM::~VM):
+
</ins><span class="cx"> 2016-06-16  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: console.profile should use the new Sampling Profiler
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1978,6 +1978,8 @@
</span><span class="cx">                 C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; };
</span><ins>+                DC0184191D10C1890057B053 /* JITWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0184181D10C1870057B053 /* JITWorklist.h */; };
+                DC01841A1D10C18C0057B053 /* JITWorklist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC0184171D10C1870057B053 /* JITWorklist.cpp */; };
</ins><span class="cx">                 DC17E8171C9C91D6008A6AB3 /* ShadowChicken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */; };
</span><span class="cx">                 DC17E8181C9C91D9008A6AB3 /* ShadowChicken.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -4195,6 +4197,8 @@
</span><span class="cx">                 D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPreciseLocalClobberize.h; path = dfg/DFGPreciseLocalClobberize.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                DC0184171D10C1870057B053 /* JITWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITWorklist.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                DC0184181D10C1870057B053 /* JITWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITWorklist.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowChicken.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChicken.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChickenInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5071,6 +5075,8 @@
</span><span class="cx">                                 0F5EF91C16878F78003E5C25 /* JITThunks.h */,
</span><span class="cx">                                 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */,
</span><span class="cx">                                 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */,
</span><ins>+                                DC0184171D10C1870057B053 /* JITWorklist.cpp */,
+                                DC0184181D10C1870057B053 /* JITWorklist.h */,
</ins><span class="cx">                                 A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
</span><span class="cx">                                 A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
</span><span class="cx">                                 792CB3471C4EED5C00D13AF3 /* PCToCodeOriginMap.cpp */,
</span><span class="lines">@@ -7858,6 +7864,7 @@
</span><span class="cx">                                 90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
</span><span class="cx">                                 0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
</span><span class="cx">                                 7C008CE7187631B600955C24 /* Microtask.h in Headers */,
</span><ins>+                                DC0184191D10C1890057B053 /* JITWorklist.h in Headers */,
</ins><span class="cx">                                 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */,
</span><span class="cx">                                 C4703CD7192844CC0013FBEA /* models.py in Headers */,
</span><span class="cx">                                 E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */,
</span><span class="lines">@@ -9158,6 +9165,7 @@
</span><span class="cx">                                 E3EF88741B66DF23003F26CB /* JSPropertyNameIterator.cpp in Sources */,
</span><span class="cx">                                 862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */,
</span><span class="cx">                                 A552C37F1ADDB8FE00139726 /* JSRemoteInspector.cpp in Sources */,
</span><ins>+                                DC01841A1D10C18C0057B053 /* JITWorklist.cpp in Sources */,
</ins><span class="cx">                                 9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */,
</span><span class="cx">                                 14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
</span><span class="cx">                                 A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -238,6 +238,8 @@
</span><span class="cx">         out.print(&quot; (DidTryToEnterInLoop)&quot;);
</span><span class="cx">     if (ownerScriptExecutable()-&gt;isStrictMode())
</span><span class="cx">         out.print(&quot; (StrictMode)&quot;);
</span><ins>+    if (m_didFailJITCompilation)
+        out.print(&quot; (JITFail)&quot;);
</ins><span class="cx">     if (this-&gt;jitType() == JITCode::BaselineJIT &amp;&amp; m_didFailFTLCompilation)
</span><span class="cx">         out.print(&quot; (FTLFail)&quot;);
</span><span class="cx">     if (this-&gt;jitType() == JITCode::BaselineJIT &amp;&amp; m_hasBeenCompiledWithFTL)
</span><span class="lines">@@ -1836,6 +1838,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
</span><span class="cx"> #endif
</span><ins>+    , m_didFailJITCompilation(false)
</ins><span class="cx">     , m_didFailFTLCompilation(false)
</span><span class="cx">     , m_hasBeenCompiledWithFTL(false)
</span><span class="cx">     , m_isConstructor(other.m_isConstructor)
</span><span class="lines">@@ -1901,6 +1904,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
</span><span class="cx"> #endif
</span><ins>+    , m_didFailJITCompilation(false)
</ins><span class="cx">     , m_didFailFTLCompilation(false)
</span><span class="cx">     , m_hasBeenCompiledWithFTL(false)
</span><span class="cx">     , m_isConstructor(unlinkedCodeBlock-&gt;isConstructor())
</span><span class="lines">@@ -2392,6 +2396,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     , m_capabilityLevelState(DFG::CannotCompile)
</span><span class="cx"> #endif
</span><ins>+    , m_didFailJITCompilation(false)
</ins><span class="cx">     , m_didFailFTLCompilation(false)
</span><span class="cx">     , m_hasBeenCompiledWithFTL(false)
</span><span class="cx">     , m_isConstructor(false)
</span><span class="lines">@@ -3885,7 +3890,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset)
</del><ins>+ArrayProfile* CodeBlock::getArrayProfile(const ConcurrentJITLocker&amp;, unsigned bytecodeOffset)
</ins><span class="cx"> {
</span><span class="cx">     for (unsigned i = 0; i &lt; m_arrayProfiles.size(); ++i) {
</span><span class="cx">         if (m_arrayProfiles[i].bytecodeOffset() == bytecodeOffset)
</span><span class="lines">@@ -3894,14 +3899,38 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ArrayProfile* CodeBlock::getOrAddArrayProfile(unsigned bytecodeOffset)
</del><ins>+ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset)
</ins><span class="cx"> {
</span><del>-    ArrayProfile* result = getArrayProfile(bytecodeOffset);
</del><ins>+    ConcurrentJITLocker locker(m_lock);
+    return getArrayProfile(locker, bytecodeOffset);
+}
+
+ArrayProfile* CodeBlock::addArrayProfile(const ConcurrentJITLocker&amp;, unsigned bytecodeOffset)
+{
+    m_arrayProfiles.append(ArrayProfile(bytecodeOffset));
+    return &amp;m_arrayProfiles.last();
+}
+
+ArrayProfile* CodeBlock::addArrayProfile(unsigned bytecodeOffset)
+{
+    ConcurrentJITLocker locker(m_lock);
+    return addArrayProfile(locker, bytecodeOffset);
+}
+
+ArrayProfile* CodeBlock::getOrAddArrayProfile(const ConcurrentJITLocker&amp; locker, unsigned bytecodeOffset)
+{
+    ArrayProfile* result = getArrayProfile(locker, bytecodeOffset);
</ins><span class="cx">     if (result)
</span><span class="cx">         return result;
</span><del>-    return addArrayProfile(bytecodeOffset);
</del><ins>+    return addArrayProfile(locker, bytecodeOffset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ArrayProfile* CodeBlock::getOrAddArrayProfile(unsigned bytecodeOffset)
+{
+    ConcurrentJITLocker locker(m_lock);
+    return getOrAddArrayProfile(locker, bytecodeOffset);
+}
+
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> Vector&lt;CodeOrigin, 0, UnsafeVectorOverflow&gt;&amp; CodeBlock::codeOrigins()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -461,12 +461,11 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); }
</span><span class="cx">     const ArrayProfileVector&amp; arrayProfiles() { return m_arrayProfiles; }
</span><del>-    ArrayProfile* addArrayProfile(unsigned bytecodeOffset)
-    {
-        m_arrayProfiles.append(ArrayProfile(bytecodeOffset));
-        return &amp;m_arrayProfiles.last();
-    }
</del><ins>+    ArrayProfile* addArrayProfile(const ConcurrentJITLocker&amp;, unsigned bytecodeOffset);
+    ArrayProfile* addArrayProfile(unsigned bytecodeOffset);
+    ArrayProfile* getArrayProfile(const ConcurrentJITLocker&amp;, unsigned bytecodeOffset);
</ins><span class="cx">     ArrayProfile* getArrayProfile(unsigned bytecodeOffset);
</span><ins>+    ArrayProfile* getOrAddArrayProfile(const ConcurrentJITLocker&amp;, unsigned bytecodeOffset);
</ins><span class="cx">     ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset);
</span><span class="cx"> 
</span><span class="cx">     // Exception handling support
</span><span class="lines">@@ -868,6 +867,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_allTransitionsHaveBeenMarked : 1; // Initialized and used on every GC.
</span><span class="cx"> 
</span><ins>+    bool m_didFailJITCompilation : 1;
</ins><span class="cx">     bool m_didFailFTLCompilation : 1;
</span><span class="cx">     bool m_hasBeenCompiledWithFTL : 1;
</span><span class="cx">     bool m_isConstructor : 1;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/Debugger.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/Debugger.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/debugger/Debugger.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -212,7 +212,7 @@
</span><span class="cx">     if (mode == m_steppingMode)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_vm.heap.completeAllDFGPlans();
</del><ins>+    m_vm.heap.completeAllJITPlans();
</ins><span class="cx"> 
</span><span class="cx">     m_steppingMode = mode;
</span><span class="cx">     SetSteppingModeFunctor functor(this, mode);
</span><span class="lines">@@ -313,7 +313,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Debugger::toggleBreakpoint(Breakpoint&amp; breakpoint, Debugger::BreakpointState enabledOrNot)
</span><span class="cx"> {
</span><del>-    m_vm.heap.completeAllDFGPlans();
</del><ins>+    m_vm.heap.completeAllJITPlans();
</ins><span class="cx"> 
</span><span class="cx">     ToggleBreakpointFunctor functor(this, breakpoint, enabledOrNot);
</span><span class="cx">     m_vm.heap.forEachCodeBlock(functor);
</span><span class="lines">@@ -487,7 +487,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Debugger::clearBreakpoints()
</span><span class="cx"> {
</span><del>-    m_vm.heap.completeAllDFGPlans();
</del><ins>+    m_vm.heap.completeAllJITPlans();
</ins><span class="cx"> 
</span><span class="cx">     m_topBreakpointID = noBreakpointID;
</span><span class="cx">     m_breakpointIDToBreakpoint.clear();
</span><span class="lines">@@ -517,7 +517,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Debugger::clearDebuggerRequests(JSGlobalObject* globalObject)
</span><span class="cx"> {
</span><del>-    m_vm.heap.completeAllDFGPlans();
</del><ins>+    m_vm.heap.completeAllJITPlans();
</ins><span class="cx"> 
</span><span class="cx">     ClearDebuggerRequestsFunctor functor(globalObject);
</span><span class="cx">     m_vm.heap.forEachCodeBlock(functor);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitPreparationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;Executable.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JITCode.h&quot;
</span><ins>+#include &quot;JITWorklist.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -43,12 +44,7 @@
</span><span class="cx">     
</span><span class="cx">     for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame-&gt;directCaller) {
</span><span class="cx">         CodeBlock* codeBlock = codeOrigin.inlineCallFrame-&gt;baselineCodeBlock.get();
</span><del>-        if (codeBlock-&gt;jitType() == JSC::JITCode::BaselineJIT)
-            continue;
-
-        ASSERT(codeBlock-&gt;jitType() == JSC::JITCode::InterpreterThunk);
-        JIT::compile(&amp;vm, codeBlock, JITCompilationMustSucceed);
-        codeBlock-&gt;ownerScriptExecutable()-&gt;installCode(codeBlock);
</del><ins>+        JITWorklist::instance()-&gt;compileNow(codeBlock);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;HeapVerifier.h&quot;
</span><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><ins>+#include &quot;JITWorklist.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="lines">@@ -519,8 +520,11 @@
</span><span class="cx">     m_objectSpace.didFinishIterating();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::completeAllDFGPlans()
</del><ins>+void Heap::completeAllJITPlans()
</ins><span class="cx"> {
</span><ins>+#if ENABLE(JIT)
+    JITWorklist::instance()-&gt;completeAllForVM(*m_vm);
+#endif // ENABLE(JIT)
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     DFG::completeAllPlansForVM(*m_vm);
</span><span class="cx"> #endif
</span><span class="lines">@@ -1045,7 +1049,7 @@
</span><span class="cx">     RELEASE_ASSERT(!m_vm-&gt;entryScope);
</span><span class="cx">     ASSERT(m_operationInProgress == NoOperation);
</span><span class="cx"> 
</span><del>-    completeAllDFGPlans();
</del><ins>+    completeAllJITPlans();
</ins><span class="cx"> 
</span><span class="cx">     for (ExecutableBase* executable : m_executables)
</span><span class="cx">         executable-&gt;clearCode();
</span><span class="lines">@@ -1141,6 +1145,13 @@
</span><span class="cx">         vm()-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;GC&quot;));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if ENABLE(JIT)
+    {
+        DeferGCForAWhile awhile(*this);
+        JITWorklist::instance()-&gt;completeAllForVM(*m_vm);
+    }
+#endif // ENABLE(JIT)
+
</ins><span class="cx">     vm()-&gt;shadowChicken().update(*vm(), vm()-&gt;topCallFrame);
</span><span class="cx"> 
</span><span class="cx">     RELEASE_ASSERT(!m_deferralDepth);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -171,7 +171,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE void collect(HeapOperation collectionType = AnyCollection);
</span><span class="cx">     bool collectIfNecessaryOrDefer(); // Returns true if it did collect.
</span><span class="cx"> 
</span><del>-    void completeAllDFGPlans();
</del><ins>+    void completeAllJITPlans();
</ins><span class="cx">     
</span><span class="cx">     // Use this API to report non-GC memory referenced by GC objects. Be sure to
</span><span class="cx">     // call both of these functions: Calling only one may trigger catastropic
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapInlines.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapInlines.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/heap/HeapInlines.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx"> template&lt;typename Functor&gt; inline void Heap::forEachCodeBlock(Functor&amp; functor)
</span><span class="cx"> {
</span><span class="cx">     // We don't know the full set of CodeBlocks until compilation has terminated.
</span><del>-    completeAllDFGPlans();
</del><ins>+    completeAllJITPlans();
</ins><span class="cx"> 
</span><span class="cx">     return m_codeBlocks.iterate&lt;Functor&gt;(functor);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> #include &quot;ResultType.h&quot;
</span><span class="cx"> #include &quot;SlowPathCall.h&quot;
</span><span class="cx"> #include &quot;StackAlignment.h&quot;
</span><ins>+#include &quot;SuperSampler.h&quot;
</ins><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="cx"> #include &lt;wtf/CryptographicallyRandomNumber.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -108,8 +109,10 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emitNotifyWrite(WatchpointSet* set)
</span><span class="cx"> {
</span><del>-    if (!set || set-&gt;state() == IsInvalidated)
</del><ins>+    if (!set || set-&gt;state() == IsInvalidated) {
+        addSlowCase(Jump());
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">     
</span><span class="cx">     addSlowCase(branch8(NotEqual, AbsoluteAddress(set-&gt;addressOfState()), TrustedImm32(IsInvalidated)));
</span><span class="cx"> }
</span><span class="lines">@@ -155,11 +158,14 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::privateCompileMainPass()
</span><span class="cx"> {
</span><ins>+    if (false)
+        dataLog(&quot;Compiling &quot;, *m_codeBlock, &quot;\n&quot;);
+    
</ins><span class="cx">     jitAssertTagsInPlace();
</span><span class="cx">     jitAssertArgumentCountSane();
</span><span class="cx">     
</span><span class="cx">     Instruction* instructionsBegin = m_codeBlock-&gt;instructions().begin();
</span><del>-    unsigned instructionCount = m_codeBlock-&gt;instructions().size();
</del><ins>+    unsigned instructionCount = m_instructions.size();
</ins><span class="cx"> 
</span><span class="cx">     m_callLinkInfoIndex = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -501,11 +507,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-CompilationResult JIT::privateCompile(JITCompilationEffort effort)
</del><ins>+void JIT::compileWithoutLinking(JITCompilationEffort effort)
</ins><span class="cx"> {
</span><span class="cx">     double before = 0;
</span><span class="cx">     if (UNLIKELY(computeCompileTimes()))
</span><span class="cx">         before = monotonicallyIncreasingTimeMS();
</span><ins>+    
+    {
+        ConcurrentJITLocker locker(m_codeBlock-&gt;m_lock);
+        m_instructions = m_codeBlock-&gt;instructions().clone();
+    }
</ins><span class="cx"> 
</span><span class="cx">     DFG::CapabilityLevel level = m_codeBlock-&gt;capabilityLevel();
</span><span class="cx">     switch (level) {
</span><span class="lines">@@ -538,8 +549,6 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_codeBlock-&gt;setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters()); // Might be able to remove as this is probably already set to this value.
-
</del><span class="cx">     // This ensures that we have the most up to date type information when performing typecheck optimizations for op_profile_type.
</span><span class="cx">     if (m_vm-&gt;typeProfiler())
</span><span class="cx">         m_vm-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;Preparing for JIT compilation.&quot;));
</span><span class="lines">@@ -601,6 +610,8 @@
</span><span class="cx"> 
</span><span class="cx">     emitSaveCalleeSaves();
</span><span class="cx">     emitMaterializeTagCheckRegisters();
</span><ins>+    
+    RELEASE_ASSERT(!JITCode::isJIT(m_codeBlock-&gt;jitType()));
</ins><span class="cx"> 
</span><span class="cx">     privateCompileMainPass();
</span><span class="cx">     privateCompileLinkPass();
</span><span class="lines">@@ -616,9 +627,8 @@
</span><span class="cx">         addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
</span><span class="cx">     callOperationWithCallFrameRollbackOnException(operationThrowStackOverflowError, m_codeBlock);
</span><span class="cx"> 
</span><del>-    Label arityCheck;
</del><span class="cx">     if (m_codeBlock-&gt;codeType() == FunctionCode) {
</span><del>-        arityCheck = label();
</del><ins>+        m_arityCheck = label();
</ins><span class="cx">         store8(TrustedImm32(0), &amp;m_codeBlock-&gt;m_shouldAlwaysBeInlined);
</span><span class="cx">         emitFunctionPrologue();
</span><span class="cx">         emitPutToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
</span><span class="lines">@@ -652,11 +662,31 @@
</span><span class="cx">         m_disassembler-&gt;setEndOfCode(label());
</span><span class="cx">     m_pcToCodeOriginMapBuilder.appendItem(label(), PCToCodeOriginMapBuilder::defaultCodeOrigin());
</span><span class="cx"> 
</span><ins>+    m_linkBuffer = std::unique_ptr&lt;LinkBuffer&gt;(new LinkBuffer(*m_vm, *this, m_codeBlock, effort));
</ins><span class="cx"> 
</span><del>-    LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock, effort);
</del><ins>+    double after;
+    if (UNLIKELY(computeCompileTimes())) {
+        after = monotonicallyIncreasingTimeMS();
+
+        if (Options::reportTotalCompileTimes())
+            totalBaselineCompileTime += after - before;
+    }
+    if (UNLIKELY(reportCompileTimes())) {
+        CString codeBlockName = toCString(*m_codeBlock);
+        
+        dataLog(&quot;Optimized &quot;, codeBlockName, &quot; with Baseline JIT into &quot;, m_linkBuffer-&gt;size(), &quot; bytes in &quot;, after - before, &quot; ms.\n&quot;);
+    }
+}
+
+CompilationResult JIT::link()
+{
+    LinkBuffer&amp; patchBuffer = *m_linkBuffer;
+    
</ins><span class="cx">     if (patchBuffer.didFailToAllocate())
</span><span class="cx">         return CompilationFailed;
</span><span class="cx"> 
</span><ins>+    m_codeBlock-&gt;setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters()); // Might be able to remove as this is probably already set to this value.
+
</ins><span class="cx">     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
</span><span class="cx">     for (unsigned i = 0; i &lt; m_switches.size(); ++i) {
</span><span class="cx">         SwitchRecord record = m_switches[i];
</span><span class="lines">@@ -738,7 +768,7 @@
</span><span class="cx"> 
</span><span class="cx">     MacroAssemblerCodePtr withArityCheck;
</span><span class="cx">     if (m_codeBlock-&gt;codeType() == FunctionCode)
</span><del>-        withArityCheck = patchBuffer.locationOf(arityCheck);
</del><ins>+        withArityCheck = patchBuffer.locationOf(m_arityCheck);
</ins><span class="cx"> 
</span><span class="cx">     if (Options::dumpDisassembly()) {
</span><span class="cx">         m_disassembler-&gt;dump(patchBuffer);
</span><span class="lines">@@ -759,25 +789,12 @@
</span><span class="cx">     
</span><span class="cx">     m_vm-&gt;machineCodeBytesPerBytecodeWordForBaselineJIT.add(
</span><span class="cx">         static_cast&lt;double&gt;(result.size()) /
</span><del>-        static_cast&lt;double&gt;(m_codeBlock-&gt;instructions().size()));
</del><ins>+        static_cast&lt;double&gt;(m_instructions.size()));
</ins><span class="cx"> 
</span><span class="cx">     m_codeBlock-&gt;shrinkToFit(CodeBlock::LateShrink);
</span><span class="cx">     m_codeBlock-&gt;setJITCode(
</span><span class="cx">         adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT)));
</span><span class="cx"> 
</span><del>-    double after;
-    if (UNLIKELY(computeCompileTimes())) {
-        after = monotonicallyIncreasingTimeMS();
-
-        if (Options::reportTotalCompileTimes())
-            totalBaselineCompileTime += after - before;
-    }
-    if (UNLIKELY(reportCompileTimes())) {
-        CString codeBlockName = toCString(*m_codeBlock);
-        
-        dataLog(&quot;Optimized &quot;, codeBlockName, &quot; with Baseline JIT into &quot;, patchBuffer.size(), &quot; bytes in &quot;, after - before, &quot; ms.\n&quot;);
-    }
-
</del><span class="cx"> #if ENABLE(JIT_VERBOSE)
</span><span class="cx">     dataLogF(&quot;JIT generated code for %p at [%p, %p).\n&quot;, m_codeBlock, result.executableMemory()-&gt;start(), result.executableMemory()-&gt;end());
</span><span class="cx"> #endif
</span><span class="lines">@@ -785,6 +802,12 @@
</span><span class="cx">     return CompilationSuccessful;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CompilationResult JIT::privateCompile(JITCompilationEffort effort)
+{
+    compileWithoutLinking(effort);
+    return link();
+}
+
</ins><span class="cx"> void JIT::privateCompileExceptionHandlers()
</span><span class="cx"> {
</span><span class="cx">     if (!m_exceptionChecksWithCallFrameRollback.empty()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -194,6 +194,12 @@
</span><span class="cx">         static const int patchPutByIdDefaultOffset = 256;
</span><span class="cx"> 
</span><span class="cx">     public:
</span><ins>+        JIT(VM*, CodeBlock* = 0);
+        ~JIT();
+
+        void compileWithoutLinking(JITCompilationEffort);
+        CompilationResult link();
+        
</ins><span class="cx">         static CompilationResult compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort)
</span><span class="cx">         {
</span><span class="cx">             return JIT(vm, codeBlock).privateCompile(effort);
</span><span class="lines">@@ -256,9 +262,6 @@
</span><span class="cx">         JS_EXPORT_PRIVATE static HashMap&lt;CString, double&gt; compileTimeStats();
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        JIT(VM*, CodeBlock* = 0);
-        ~JIT();
-
</del><span class="cx">         void privateCompileMainPass();
</span><span class="cx">         void privateCompileLinkPass();
</span><span class="cx">         void privateCompileSlowCases();
</span><span class="lines">@@ -713,7 +716,8 @@
</span><span class="cx">         }
</span><span class="cx">         void linkSlowCase(Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="cx">         {
</span><del>-            iter-&gt;from.link(this);
</del><ins>+            if (iter-&gt;from.isSet())
+                iter-&gt;from.link(this);
</ins><span class="cx">             ++iter;
</span><span class="cx">         }
</span><span class="cx">         void linkDummySlowCase(Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="lines">@@ -908,8 +912,15 @@
</span><span class="cx"> 
</span><span class="cx">         static bool reportCompileTimes();
</span><span class="cx">         static bool computeCompileTimes();
</span><ins>+        
+        // If you need to check the value of an instruction multiple times and the instruction is
+        // part of a LLInt inline cache, then you want to use this. It will give you the value of
+        // the instruction at the start of JITing.
+        Instruction* copiedInstruction(Instruction*);
</ins><span class="cx"> 
</span><span class="cx">         Interpreter* m_interpreter;
</span><ins>+        
+        RefCountedArray&lt;Instruction&gt; m_instructions;
</ins><span class="cx"> 
</span><span class="cx">         Vector&lt;CallRecord&gt; m_calls;
</span><span class="cx">         Vector&lt;Label&gt; m_labels;
</span><span class="lines">@@ -930,6 +941,9 @@
</span><span class="cx">         unsigned m_putByIdIndex;
</span><span class="cx">         unsigned m_byValInstructionIndex;
</span><span class="cx">         unsigned m_callLinkInfoIndex;
</span><ins>+        
+        Label m_arityCheck;
+        std::unique_ptr&lt;LinkBuffer&gt; m_linkBuffer;
</ins><span class="cx"> 
</span><span class="cx">         std::unique_ptr&lt;JITDisassembler&gt; m_disassembler;
</span><span class="cx">         RefPtr&lt;Profiler::Compilation&gt; m_compilation;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/jit/JITCall.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -125,9 +125,13 @@
</span><span class="cx"> 
</span><span class="cx">     load64(Address(stackPointerRegister, sizeof(Register) * JSStack::Callee - sizeof(CallerFrameAndPC)), regT0);
</span><span class="cx">     move(TrustedImmPtr(info), regT2);
</span><del>-    MacroAssemblerCodeRef virtualThunk = virtualThunkFor(m_vm, *info);
-    info-&gt;setSlowStub(createJITStubRoutine(virtualThunk, *m_vm, nullptr, true));
-    emitNakedCall(virtualThunk.code());
</del><ins>+    Call call = emitNakedCall();
+    addLinkTask(
+        [=] (LinkBuffer&amp; linkBuffer) {
+            MacroAssemblerCodeRef virtualThunk = virtualThunkFor(m_vm, *info);
+            info-&gt;setSlowStub(createJITStubRoutine(virtualThunk, *m_vm, nullptr, true));
+            linkBuffer.link(call, CodeLocationLabel(virtualThunk.code()));
+        });
</ins><span class="cx">     addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
</span><span class="cx">     checkStackPointerAlignment();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlines.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlines.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/jit/JITInlines.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1355,6 +1355,12 @@
</span><span class="cx">     or32(TrustedImm32(static_cast&lt;int32_t&gt;(ValueFalse)), reg);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline Instruction* JIT::copiedInstruction(Instruction* inst)
+{
+    ASSERT(inst &gt;= m_codeBlock-&gt;instructions().begin() &amp;&amp; inst &lt; m_codeBlock-&gt;instructions().end());
+    return m_instructions.begin() + (inst - m_codeBlock-&gt;instructions().begin());
+}
+
</ins><span class="cx"> #endif // USE(JSVALUE32_64)
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -466,7 +466,7 @@
</span><span class="cx">     int base = currentInstruction[1].u.operand;
</span><span class="cx">     int property = currentInstruction[2].u.operand;
</span><span class="cx">     int value = currentInstruction[3].u.operand;
</span><del>-    ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
</del><ins>+    JITArrayMode mode = m_byValCompilationInfo[m_byValInstructionIndex].arrayMode;
</ins><span class="cx">     ByValInfo* byValInfo = m_byValCompilationInfo[m_byValInstructionIndex].byValInfo;
</span><span class="cx"> 
</span><span class="cx">     linkSlowCaseIfNotJSCell(iter, base); // base cell check
</span><span class="lines">@@ -476,7 +476,6 @@
</span><span class="cx">     
</span><span class="cx">     linkSlowCase(iter); // out of bounds
</span><span class="cx">     
</span><del>-    JITArrayMode mode = chooseArrayMode(profile);
</del><span class="cx">     switch (mode) {
</span><span class="cx">     case JITInt32:
</span><span class="cx">     case JITDouble:
</span><span class="lines">@@ -730,7 +729,7 @@
</span><span class="cx"> {
</span><span class="cx">     int dst = currentInstruction[1].u.operand;
</span><span class="cx">     int scope = currentInstruction[2].u.operand;
</span><del>-    ResolveType resolveType = static_cast&lt;ResolveType&gt;(currentInstruction[4].u.operand);
</del><ins>+    ResolveType resolveType = static_cast&lt;ResolveType&gt;(copiedInstruction(currentInstruction)[4].u.operand);
</ins><span class="cx">     unsigned depth = currentInstruction[5].u.operand;
</span><span class="cx"> 
</span><span class="cx">     auto emitCode = [&amp;] (ResolveType resolveType) {
</span><span class="lines">@@ -805,7 +804,7 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emitSlow_op_resolve_scope(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="cx"> {
</span><del>-    ResolveType resolveType = static_cast&lt;ResolveType&gt;(currentInstruction[4].u.operand);
</del><ins>+    ResolveType resolveType = static_cast&lt;ResolveType&gt;(copiedInstruction(currentInstruction)[4].u.operand);
</ins><span class="cx">     if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar || resolveType == GlobalLexicalVar || resolveType == ModuleVar)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -849,7 +848,7 @@
</span><span class="cx"> {
</span><span class="cx">     int dst = currentInstruction[1].u.operand;
</span><span class="cx">     int scope = currentInstruction[2].u.operand;
</span><del>-    ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</del><ins>+    ResolveType resolveType = GetPutInfo(copiedInstruction(currentInstruction)[4].u.operand).resolveType();
</ins><span class="cx">     Structure** structureSlot = currentInstruction[5].u.structure.slot();
</span><span class="cx">     uintptr_t* operandSlot = reinterpret_cast&lt;uintptr_t*&gt;(&amp;currentInstruction[6].u.pointer);
</span><span class="cx"> 
</span><span class="lines">@@ -944,7 +943,7 @@
</span><span class="cx"> void JIT::emitSlow_op_get_from_scope(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="cx"> {
</span><span class="cx">     int dst = currentInstruction[1].u.operand;
</span><del>-    ResolveType resolveType = GetPutInfo(currentInstruction[4].u.operand).resolveType();
</del><ins>+    ResolveType resolveType = GetPutInfo(copiedInstruction(currentInstruction)[4].u.operand).resolveType();
</ins><span class="cx"> 
</span><span class="cx">     if (resolveType == GlobalVar || resolveType == ClosureVar)
</span><span class="cx">         return;
</span><span class="lines">@@ -998,7 +997,7 @@
</span><span class="cx"> {
</span><span class="cx">     int scope = currentInstruction[1].u.operand;
</span><span class="cx">     int value = currentInstruction[3].u.operand;
</span><del>-    GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
</del><ins>+    GetPutInfo getPutInfo = GetPutInfo(copiedInstruction(currentInstruction)[4].u.operand);
</ins><span class="cx">     ResolveType resolveType = getPutInfo.resolveType();
</span><span class="cx">     Structure** structureSlot = currentInstruction[5].u.structure.slot();
</span><span class="cx">     uintptr_t* operandSlot = reinterpret_cast&lt;uintptr_t*&gt;(&amp;currentInstruction[6].u.pointer);
</span><span class="lines">@@ -1095,15 +1094,15 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
</span><span class="cx"> {
</span><del>-    GetPutInfo getPutInfo = GetPutInfo(currentInstruction[4].u.operand);
</del><ins>+    GetPutInfo getPutInfo = GetPutInfo(copiedInstruction(currentInstruction)[4].u.operand);
</ins><span class="cx">     ResolveType resolveType = getPutInfo.resolveType();
</span><span class="cx">     unsigned linkCount = 0;
</span><span class="cx">     if (resolveType != GlobalVar &amp;&amp; resolveType != ClosureVar &amp;&amp; resolveType != LocalClosureVar &amp;&amp; resolveType != GlobalLexicalVar)
</span><span class="cx">         linkCount++;
</span><del>-    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks 
-         || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks 
-         || resolveType == LocalClosureVar)
-        &amp;&amp; currentInstruction[5].u.watchpointSet-&gt;state() != IsInvalidated)
</del><ins>+    if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks 
+        || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks 
+        || resolveType == ClosureVar || resolveType == ClosureVarWithVarInjectionChecks
+        || resolveType == LocalClosureVar)
</ins><span class="cx">         linkCount++;
</span><span class="cx">     if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks)
</span><span class="cx">         linkCount++; // bad structure
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1102,9 +1102,10 @@
</span><span class="cx">     unsigned linkCount = 0;
</span><span class="cx">     if (resolveType != GlobalVar &amp;&amp; resolveType != ClosureVar &amp;&amp; resolveType != LocalClosureVar &amp;&amp; resolveType != GlobalLexicalVar)
</span><span class="cx">         linkCount++;
</span><del>-    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar
-        || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)
-        &amp;&amp; currentInstruction[5].u.watchpointSet-&gt;state() != IsInvalidated)
</del><ins>+    if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks 
+        || resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks 
+        || resolveType == ClosureVar || resolveType == ClosureVarWithVarInjectionChecks
+        || resolveType == LocalClosureVar)
</ins><span class="cx">         linkCount++;
</span><span class="cx">     if (!isInitialization(getPutInfo.initializationMode()) &amp;&amp; (resolveType == GlobalLexicalVar || resolveType == GlobalLexicalVarWithVarInjectionChecks)) // TDZ check.
</span><span class="cx">         linkCount++;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWorklistcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/JITWorklist.cpp (0 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWorklist.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -0,0 +1,285 @@
</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. ``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
+ * 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. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;JITWorklist.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;JIT.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;VMInlines.h&quot;
+
+namespace JSC {
+
+class JITWorklist::Plan : public ThreadSafeRefCounted&lt;JITWorklist::Plan&gt; {
+public:
+    Plan(CodeBlock* codeBlock)
+        : m_codeBlock(codeBlock)
+        , m_jit(codeBlock-&gt;vm(), codeBlock)
+    {
+    }
+    
+    void compileInThread()
+    {
+        m_jit.compileWithoutLinking(JITCompilationCanFail);
+        
+        LockHolder locker(m_lock);
+        m_isFinishedCompiling = true;
+    }
+    
+    void finalize()
+    {
+        CompilationResult result = m_jit.link();
+        switch (result) {
+        case CompilationFailed:
+            CODEBLOCK_LOG_EVENT(m_codeBlock, &quot;delayJITCompile&quot;, (&quot;compilation failed&quot;));
+            if (Options::verboseOSR())
+                dataLogF(&quot;    JIT compilation failed.\n&quot;);
+            m_codeBlock-&gt;dontJITAnytimeSoon();
+            m_codeBlock-&gt;m_didFailJITCompilation = true;
+            return;
+        case CompilationSuccessful:
+            if (Options::verboseOSR())
+                dataLogF(&quot;    JIT compilation successful.\n&quot;);
+            m_codeBlock-&gt;ownerScriptExecutable()-&gt;installCode(m_codeBlock);
+            m_codeBlock-&gt;jitSoon();
+            return;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return;
+        }
+        
+        LockHolder locker(m_lock);
+        m_isFinalized = true;
+    }
+    
+    CodeBlock* codeBlock() { return m_codeBlock; }
+    VM* vm() { return m_codeBlock-&gt;vm(); }
+    
+    bool isFinishedCompiling()
+    {
+        LockHolder locker(m_lock);
+        return m_isFinishedCompiling;
+    }
+    bool isFinalized()
+    {
+        LockHolder locker(m_lock);
+        return m_isFinalized;
+    }
+    
+private:
+    CodeBlock* m_codeBlock;
+    JIT m_jit;
+    Lock m_lock;
+    bool m_isFinishedCompiling { false };
+    bool m_isFinalized { false };
+};
+
+JITWorklist::JITWorklist()
+{
+    createThread(&quot;JIT Worklist Worker Thread&quot;, [this] () { runThread(); });
+}
+
+JITWorklist::~JITWorklist()
+{
+    UNREACHABLE_FOR_PLATFORM();
+}
+
+void JITWorklist::completeAllForVM(VM&amp; vm)
+{
+    DeferGC deferGC(vm.heap);
+    for (;;) {
+        Vector&lt;RefPtr&lt;Plan&gt;, 32&gt; myPlans;
+        {
+            LockHolder locker(m_lock);
+            for (;;) {
+                bool didFindUnfinishedPlan = false;
+                m_plans.removeAllMatching(
+                    [&amp;] (RefPtr&lt;Plan&gt;&amp; plan) {
+                        if (plan-&gt;vm() != &amp;vm)
+                            return false;
+                        if (!plan-&gt;isFinishedCompiling()) {
+                            didFindUnfinishedPlan = true;
+                            return false;
+                        }
+                        myPlans.append(WTFMove(plan));
+                        return true;
+                    });
+                
+                // If we found plans then we should finalize them now.
+                if (!myPlans.isEmpty())
+                    break;
+                
+                // If we don't find plans, then we're either done or we need to wait, depending on
+                // whether we found some unfinished plans.
+                if (!didFindUnfinishedPlan)
+                    return;
+                
+                m_condition.wait(m_lock);
+            }
+        }
+        
+        finalizePlans(myPlans);
+    }
+}
+
+void JITWorklist::poll(VM&amp; vm)
+{
+    DeferGC deferGC(vm.heap);
+    Plans myPlans;
+    {
+        LockHolder locker(m_lock);
+        m_plans.removeAllMatching(
+            [&amp;] (RefPtr&lt;Plan&gt;&amp; plan) {
+                if (plan-&gt;vm() != &amp;vm)
+                    return false;
+                if (!plan-&gt;isFinishedCompiling())
+                    return false;
+                myPlans.append(WTFMove(plan));
+                return true;
+            });
+    }
+    
+    finalizePlans(myPlans);
+}
+
+void JITWorklist::compileLater(CodeBlock* codeBlock)
+{
+    DeferGC deferGC(codeBlock-&gt;vm()-&gt;heap);
+    RELEASE_ASSERT(codeBlock-&gt;jitType() == JITCode::InterpreterThunk);
+    
+    if (codeBlock-&gt;m_didFailJITCompilation) {
+        codeBlock-&gt;dontJITAnytimeSoon();
+        return;
+    }
+    
+    if (!Options::useConcurrentJIT()) {
+        Plan plan(codeBlock);
+        plan.compileInThread();
+        plan.finalize();
+        return;
+    }
+    
+    codeBlock-&gt;jitSoon();
+    
+    Plans myPlans;
+    LockHolder locker(m_lock);
+    
+    if (!m_planned.add(codeBlock).isNewEntry)
+        return;
+    
+    RefPtr&lt;Plan&gt; plan = adoptRef(new Plan(codeBlock));
+    m_plans.append(plan);
+    m_queue.append(plan);
+    m_condition.notifyAll();
+}
+
+void JITWorklist::compileNow(CodeBlock* codeBlock)
+{
+    // If this ever happens, we'll have a bad time because the baseline JIT does not clean up its
+    // changes to the CodeBlock after a failed compilation.
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=158806
+    RELEASE_ASSERT(!codeBlock-&gt;m_didFailJITCompilation);
+    
+    DeferGC deferGC(codeBlock-&gt;vm()-&gt;heap);
+    if (codeBlock-&gt;jitType() != JITCode::InterpreterThunk)
+        return;
+    
+    bool isPlanned;
+    {
+        LockHolder locker(m_lock);
+        isPlanned = m_planned.contains(codeBlock);
+    }
+    
+    if (isPlanned) {
+        RELEASE_ASSERT(Options::useConcurrentJIT());
+        // This is expensive, but probably good enough.
+        completeAllForVM(*codeBlock-&gt;vm());
+    }
+    
+    // Now it might be compiled!
+    if (codeBlock-&gt;jitType() != JITCode::InterpreterThunk)
+        return;
+    
+    // OK, just compile it.
+    JIT::compile(codeBlock-&gt;vm(), codeBlock, JITCompilationMustSucceed);
+    codeBlock-&gt;ownerScriptExecutable()-&gt;installCode(codeBlock);
+}
+
+void JITWorklist::runThread()
+{
+    for (;;) {
+        Plans myPlans;
+        {
+            LockHolder locker(m_lock);
+            while (m_queue.isEmpty())
+                m_condition.wait(m_lock);
+            
+            // This is a fun way to dequeue. I don't know if it's any better or worse than dequeuing
+            // one thing at a time.
+            myPlans = WTFMove(m_queue);
+        }
+        
+        RELEASE_ASSERT(!myPlans.isEmpty());
+        
+        for (RefPtr&lt;Plan&gt;&amp; plan : myPlans) {
+            plan-&gt;compileInThread();
+            plan = nullptr;
+            
+            // Make sure that the main thread realizes that we just compiled something. Notifying
+            // a WTF condition is basically free if nobody is waiting.
+            LockHolder locker(m_lock);
+            m_condition.notifyAll();
+        }
+    }
+}
+
+void JITWorklist::finalizePlans(Plans&amp; myPlans)
+{
+    for (RefPtr&lt;Plan&gt;&amp; plan : myPlans) {
+        plan-&gt;finalize();
+        
+        LockHolder locker(m_lock);
+        m_planned.remove(plan-&gt;codeBlock());
+    }
+}
+
+JITWorklist* JITWorklist::instance()
+{
+    static JITWorklist* worklist;
+    static std::once_flag once;
+    std::call_once(
+        once,
+        [] {
+            worklist = new JITWorklist();
+        });
+    return worklist;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWorklisth"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/JITWorklist.h (0 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWorklist.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/JITWorklist.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -0,0 +1,83 @@
</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. ``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
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JITWorklist_h
+#define JITWorklist_h
+
+#if ENABLE(JIT)
+
+#include &lt;wtf/Condition.h&gt;
+#include &lt;wtf/FastMalloc.h&gt;
+#include &lt;wtf/HashSet.h&gt;
+#include &lt;wtf/Lock.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/RefPtr.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+class CodeBlock;
+class VM;
+
+class JITWorklist {
+    WTF_MAKE_NONCOPYABLE(JITWorklist);
+    WTF_MAKE_FAST_ALLOCATED;
+
+    class Plan;
+    typedef Vector&lt;RefPtr&lt;Plan&gt;, 32&gt; Plans;
+    
+public:
+    ~JITWorklist();
+    
+    void completeAllForVM(VM&amp;);
+    void poll(VM&amp;);
+    
+    void compileLater(CodeBlock*);
+    
+    void compileNow(CodeBlock*);
+    
+    static JITWorklist* instance();
+    
+private:
+    JITWorklist();
+    
+    NO_RETURN void runThread();
+    
+    void finalizePlans(Plans&amp;);
+    
+    Plans m_queue;
+    Plans m_plans;
+    HashSet&lt;CodeBlock*&gt; m_planned;
+    
+    Lock m_lock;
+    Condition m_condition; // We use One True Condition for everything because that's easier.
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITWorklist_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JITExceptions.h&quot;
</span><ins>+#include &quot;JITWorklist.h&quot;
</ins><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="lines">@@ -326,6 +327,8 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    JITWorklist::instance()-&gt;poll(vm);
+    
</ins><span class="cx">     switch (codeBlock-&gt;jitType()) {
</span><span class="cx">     case JITCode::BaselineJIT: {
</span><span class="cx">         if (Options::verboseOSR())
</span><span class="lines">@@ -334,24 +337,8 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     case JITCode::InterpreterThunk: {
</span><del>-        CompilationResult result = JIT::compile(&amp;vm, codeBlock, JITCompilationCanFail);
-        switch (result) {
-        case CompilationFailed:
-            CODEBLOCK_LOG_EVENT(codeBlock, &quot;delayJITCompile&quot;, (&quot;compilation failed&quot;));
-            if (Options::verboseOSR())
-                dataLogF(&quot;    JIT compilation failed.\n&quot;);
-            codeBlock-&gt;dontJITAnytimeSoon();
-            return false;
-        case CompilationSuccessful:
-            if (Options::verboseOSR())
-                dataLogF(&quot;    JIT compilation successful.\n&quot;);
-            codeBlock-&gt;ownerScriptExecutable()-&gt;installCode(codeBlock);
-            codeBlock-&gt;jitSoon();
-            return true;
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            return false;
-        }
</del><ins>+        JITWorklist::instance()-&gt;compileLater(codeBlock);
+        return codeBlock-&gt;jitType() == JITCode::BaselineJIT;
</ins><span class="cx">     }
</span><span class="cx">     default:
</span><span class="cx">         dataLog(&quot;Unexpected code block in LLInt: &quot;, *codeBlock, &quot;\n&quot;);
</span><span class="lines">@@ -589,6 +576,9 @@
</span><span class="cx"> 
</span><span class="cx">     if (structure-&gt;typeInfo().prohibitsPropertyCaching())
</span><span class="cx">         return;
</span><ins>+    
+    if (structure-&gt;needImpurePropertyWatchpoint())
+        return;
</ins><span class="cx"> 
</span><span class="cx">     if (structure-&gt;isDictionary()) {
</span><span class="cx">         if (structure-&gt;hasBeenFlattenedBefore())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -783,6 +783,7 @@
</span><span class="cx">         if (resolvedScope-&gt;isGlobalObject()) {
</span><span class="cx">             JSGlobalObject* globalObject = jsCast&lt;JSGlobalObject*&gt;(resolvedScope);
</span><span class="cx">             if (globalObject-&gt;hasProperty(exec, ident)) {
</span><ins>+                ConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock);
</ins><span class="cx">                 if (resolveType == UnresolvedProperty)
</span><span class="cx">                     pc[4].u.operand = GlobalProperty;
</span><span class="cx">                 else
</span><span class="lines">@@ -792,6 +793,7 @@
</span><span class="cx">             }
</span><span class="cx">         } else if (resolvedScope-&gt;isGlobalLexicalEnvironment()) {
</span><span class="cx">             JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast&lt;JSGlobalLexicalEnvironment*&gt;(resolvedScope);
</span><ins>+            ConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock);
</ins><span class="cx">             if (resolveType == UnresolvedProperty)
</span><span class="cx">                 pc[4].u.operand = GlobalLexicalVar;
</span><span class="cx">             else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -104,6 +104,7 @@
</span><span class="cx">             ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
</span><span class="cx">             resolveType = newResolveType;
</span><span class="cx">             getPutInfo = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode());
</span><ins>+            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
</ins><span class="cx">             pc[4].u.operand = getPutInfo.operand();
</span><span class="cx">         } else if (scope-&gt;isGlobalLexicalEnvironment()) {
</span><span class="cx">             JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast&lt;JSGlobalLexicalEnvironment*&gt;(scope);
</span><span class="lines">@@ -111,6 +112,7 @@
</span><span class="cx">             pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
</span><span class="cx">             SymbolTableEntry entry = globalLexicalEnvironment-&gt;symbolTable()-&gt;get(ident.impl());
</span><span class="cx">             ASSERT(!entry.isNull());
</span><ins>+            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
</ins><span class="cx">             pc[5].u.watchpointSet = entry.watchpointSet();
</span><span class="cx">             pc[6].u.pointer = static_cast&lt;void*&gt;(globalLexicalEnvironment-&gt;variableAt(entry.scopeOffset()).slot());
</span><span class="cx">         }
</span><span class="lines">@@ -146,13 +148,15 @@
</span><span class="cx">         if (scope-&gt;isGlobalObject()) {
</span><span class="cx">             ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalProperty : GlobalPropertyWithVarInjectionChecks;
</span><span class="cx">             resolveType = newResolveType; // Allow below caching mechanism to kick in.
</span><ins>+            ConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock);
</ins><span class="cx">             pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
</span><span class="cx">         } else if (scope-&gt;isGlobalLexicalEnvironment()) {
</span><span class="cx">             JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast&lt;JSGlobalLexicalEnvironment*&gt;(scope);
</span><span class="cx">             ResolveType newResolveType = resolveType == UnresolvedProperty ? GlobalLexicalVar : GlobalLexicalVarWithVarInjectionChecks;
</span><del>-            pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
</del><span class="cx">             SymbolTableEntry entry = globalLexicalEnvironment-&gt;symbolTable()-&gt;get(ident.impl());
</span><span class="cx">             ASSERT(!entry.isNull());
</span><ins>+            ConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock);
+            pc[4].u.operand = GetPutInfo(getPutInfo.resolveMode(), newResolveType, getPutInfo.initializationMode()).operand();
</ins><span class="cx">             pc[5].u.watchpointSet = entry.watchpointSet();
</span><span class="cx">             pc[6].u.pointer = static_cast&lt;void*&gt;(globalLexicalEnvironment-&gt;variableAt(entry.scopeOffset()).slot());
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> #include &quot;InferredTypeTable.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JITCode.h&quot;
</span><ins>+#include &quot;JITWorklist.h&quot;
</ins><span class="cx"> #include &quot;JSAPIValueWrapper.h&quot;
</span><span class="cx"> #include &quot;JSArray.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -342,6 +343,10 @@
</span><span class="cx">     }
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><span class="cx">     
</span><ins>+#if ENABLE(JIT)
+    JITWorklist::instance()-&gt;completeAllForVM(*this);
+#endif // ENABLE(JIT)
+
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     // Make sure concurrent compilations are done, but don't install them, since there is
</span><span class="cx">     // no point to doing so.
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/WTF/ChangeLog        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-06-14  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Baseline JIT should be concurrent
+        https://bugs.webkit.org/show_bug.cgi?id=158755
+
+        Reviewed by Geoffrey Garen.
+        
+        The concurrent baseline JIT needs to be able to clone bytecode to get a consistent snapshot.
+        So, this adds such a method.
+
+        * wtf/RefCountedArray.h:
+        (WTF::RefCountedArray::RefCountedArray):
+        (WTF::RefCountedArray::clone):
+
</ins><span class="cx"> 2016-06-16  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         No need to ref connection in lambda inside NetworkResourceLoader::tryStoreAsCacheEntry()
</span></span></pre></div>
<a id="trunkSourceWTFwtfRefCountedArrayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/RefCountedArray.h (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/RefCountedArray.h        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Source/WTF/wtf/RefCountedArray.h        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -72,6 +72,14 @@
</span><span class="cx">         VectorTypeOperations&lt;T&gt;::initialize(begin(), end());
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    RefCountedArray clone() const
+    {
+        RefCountedArray result(size());
+        for (unsigned i = size(); i--;)
+            result[i] = at(i);
+        return result;
+    }
+
</ins><span class="cx">     template&lt;size_t inlineCapacity, typename OverflowHandler&gt;
</span><span class="cx">     explicit RefCountedArray(const Vector&lt;T, inlineCapacity, OverflowHandler&gt;&amp; other)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Tools/ChangeLog        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-06-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Baseline JIT should be concurrent
+        https://bugs.webkit.org/show_bug.cgi?id=158755
+
+        Reviewed by Geoffrey Garen.
+        
+        Need to disable concurrent JIT when running profiler tests. We should have been doing this
+        all along.
+
+        * Scripts/run-jsc-stress-tests:
+
</ins><span class="cx"> 2016-06-16  Per Arne Vollan  &lt;pvollan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Win] Accessibility implementation unable to recurse through document (sometimes) to find named elements
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscstresstests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-stress-tests (202156 => 202157)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-stress-tests        2016-06-17 04:34:24 UTC (rev 202156)
+++ trunk/Tools/Scripts/run-jsc-stress-tests        2016-06-17 04:48:47 UTC (rev 202157)
</span><span class="lines">@@ -1001,10 +1001,10 @@
</span><span class="cx"> 
</span><span class="cx">     profilerOutput = uniqueFilename(&quot;.json&quot;)
</span><span class="cx">     if $canRunDisplayProfilerOutput
</span><del>-        addRunCommand(&quot;profiler&quot;, [&quot;ruby&quot;, (pathToHelpers + &quot;profiler-test-helper&quot;).to_s, (SCRIPTS_PATH + &quot;display-profiler-output&quot;).to_s, profilerOutput.to_s, pathToVM.to_s, &quot;-p&quot;, profilerOutput.to_s, $benchmark.to_s], silentOutputHandler, simpleErrorHandler)
</del><ins>+        addRunCommand(&quot;profiler&quot;, [&quot;ruby&quot;, (pathToHelpers + &quot;profiler-test-helper&quot;).to_s, (SCRIPTS_PATH + &quot;display-profiler-output&quot;).to_s, profilerOutput.to_s, pathToVM.to_s, &quot;--useConcurrentJIT=false&quot;, &quot;-p&quot;, profilerOutput.to_s, $benchmark.to_s], silentOutputHandler, simpleErrorHandler)
</ins><span class="cx">     else
</span><span class="cx">         puts &quot;Running simple version of #{$collectionName}/#{$benchmark} because some required Ruby features are unavailable.&quot;
</span><del>-        run(&quot;profiler-simple&quot;, &quot;-p&quot;, profilerOutput.to_s)
</del><ins>+        run(&quot;profiler-simple&quot;, &quot;--useConcurrentJIT=false&quot;, &quot;-p&quot;, profilerOutput.to_s)
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>