<!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>[211642] trunk/Source/JavaScriptCore</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/211642">211642</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2017-02-03 12:00:53 -0800 (Fri, 03 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>When OSR entering to the baseline JIT from the LLInt for a ProgramCodeBlock we can skip compiling a lot of the program
https://bugs.webkit.org/show_bug.cgi?id=167725
&lt;rdar://problem/30339082&gt;

Reviewed by Michael Saboff.

We often want to baseline compile ProgramCode once we hit a loop in the LLInt.
However, some programs execute a non-trivial amount of code before the loop.
This code can never be executed again because ProgramCodeBlocks never run more
than once. We're wasting time and memory by compiling code that is unreachable
from the OSR entry destination. This patch fixes this by only compiling code
that is reachable from the OSR entry destination.

This is a speedup on Kraken/ai-astar for devices with limited CPUs (I've been
testing on devices with 2 CPUs). On ai-astar, we were spending 50-100ms compiling
a huge ProgramCodeBlock in the baseline JIT where the majority of the code
would never execute. If this compilation was kicked off on the main thread,
then we'd be stalled for a long time. If it were started on the baseline JITs
background compilation thread, we'd still waste 50-100ms in that thread, causing
all other baseline compilations to happen on the main thread.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
* interpreter/Interpreter.h:
* jit/JIT.cpp:
(JSC::JIT::JIT):
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
(JSC::JIT::compile):
* jit/JITWorklist.cpp:
(JSC::JITWorklist::Plan::Plan):
(JSC::JITWorklist::Plan::compileNow):
(JSC::JITWorklist::compileLater):
(JSC::JITWorklist::compileNow):
* jit/JITWorklist.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Completion.cpp:
(JSC::evaluate):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpreterh">trunk/Source/JavaScriptCore/interpreter/Interpreter.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="#trunkSourceJavaScriptCorejitJITWorklistcpp">trunk/Source/JavaScriptCore/jit/JITWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITWorklisth">trunk/Source/JavaScriptCore/jit/JITWorklist.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCompletioncpp">trunk/Source/JavaScriptCore/runtime/Completion.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2017-02-03  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        When OSR entering to the baseline JIT from the LLInt for a ProgramCodeBlock we can skip compiling a lot of the program
+        https://bugs.webkit.org/show_bug.cgi?id=167725
+        &lt;rdar://problem/30339082&gt;
+
+        Reviewed by Michael Saboff.
+
+        We often want to baseline compile ProgramCode once we hit a loop in the LLInt.
+        However, some programs execute a non-trivial amount of code before the loop.
+        This code can never be executed again because ProgramCodeBlocks never run more
+        than once. We're wasting time and memory by compiling code that is unreachable
+        from the OSR entry destination. This patch fixes this by only compiling code
+        that is reachable from the OSR entry destination.
+
+        This is a speedup on Kraken/ai-astar for devices with limited CPUs (I've been
+        testing on devices with 2 CPUs). On ai-astar, we were spending 50-100ms compiling
+        a huge ProgramCodeBlock in the baseline JIT where the majority of the code
+        would never execute. If this compilation was kicked off on the main thread,
+        then we'd be stalled for a long time. If it were started on the baseline JITs
+        background compilation thread, we'd still waste 50-100ms in that thread, causing
+        all other baseline compilations to happen on the main thread.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeProgram):
+        * interpreter/Interpreter.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::JIT):
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        (JSC::JIT::compile):
+        * jit/JITWorklist.cpp:
+        (JSC::JITWorklist::Plan::Plan):
+        (JSC::JITWorklist::Plan::compileNow):
+        (JSC::JITWorklist::compileLater):
+        (JSC::JITWorklist::compileNow):
+        * jit/JITWorklist.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::jitCompileAndSetHeuristics):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/Completion.cpp:
+        (JSC::evaluate):
+
</ins><span class="cx"> 2017-02-03  Csaba Osztrogonác  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed typo fix after r211630.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -727,12 +727,16 @@
</span><span class="cx">     return returnValue;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
</del><ins>+JSValue Interpreter::executeProgram(const SourceCode&amp; source, CallFrame* callFrame, JSObject* thisObj)
</ins><span class="cx"> {
</span><span class="cx">     JSScope* scope = thisObj-&gt;globalObject()-&gt;globalScope();
</span><span class="cx">     VM&amp; vm = *scope-&gt;vm();
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><ins>+    ProgramExecutable* program = ProgramExecutable::create(callFrame, source);
+    ASSERT(throwScope.exception() || program);
+    RETURN_IF_EXCEPTION(throwScope, { });
+
</ins><span class="cx">     ASSERT(!throwScope.exception());
</span><span class="cx">     ASSERT(!vm.isCollectorBusyOnCurrentThread());
</span><span class="cx">     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.h (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx"> 
</span><span class="cx">         bool isOpcode(Opcode);
</span><span class="cx"> 
</span><del>-        JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj);
</del><ins>+        JSValue executeProgram(const SourceCode&amp;, CallFrame*, JSObject* thisObj);
</ins><span class="cx">         JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&amp;, JSValue thisValue, const ArgList&amp;);
</span><span class="cx">         JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&amp;, const ArgList&amp;, JSValue newTarget);
</span><span class="cx">         JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, JSScope*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;BytecodeGraph.h&quot;
</ins><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;CodeBlockWithJITType.h&quot;
</span><span class="cx"> #include &quot;DFGCapabilities.h&quot;
</span><span class="lines">@@ -42,11 +43,13 @@
</span><span class="cx"> #include &quot;MaxFrameExtentForSlowPathCall.h&quot;
</span><span class="cx"> #include &quot;PCToCodeOriginMap.h&quot;
</span><span class="cx"> #include &quot;ProfilerDatabase.h&quot;
</span><ins>+#include &quot;ProgramCodeBlock.h&quot;
</ins><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><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="cx"> #include &lt;wtf/CryptographicallyRandomNumber.h&gt;
</span><ins>+#include &lt;wtf/GraphNodeWorklist.h&gt;
</ins><span class="cx"> #include &lt;wtf/SimpleStats.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using namespace std;
</span><span class="lines">@@ -74,7 +77,7 @@
</span><span class="cx">     return jit.privateCompileCTINativeCall(vm, func);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JIT::JIT(VM* vm, CodeBlock* codeBlock)
</del><ins>+JIT::JIT(VM* vm, CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
</ins><span class="cx">     : JSInterfaceJIT(vm, codeBlock)
</span><span class="cx">     , m_interpreter(vm-&gt;interpreter)
</span><span class="cx">     , m_labels(codeBlock ? codeBlock-&gt;numberOfInstructions() : 0)
</span><span class="lines">@@ -87,6 +90,7 @@
</span><span class="cx">     , m_pcToCodeOriginMapBuilder(*vm)
</span><span class="cx">     , m_canBeOptimized(false)
</span><span class="cx">     , m_shouldEmitProfiling(false)
</span><ins>+    , m_loopOSREntryBytecodeOffset(loopOSREntryBytecodeOffset)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -147,14 +151,18 @@
</span><span class="cx"> 
</span><span class="cx"> #define DEFINE_SLOW_OP(name) \
</span><span class="cx">     case op_##name: { \
</span><del>-        JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_##name); \
-        slowPathCall.call(); \
</del><ins>+        if (m_bytecodeOffset &gt;= startBytecodeOffset) { \
+            JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_##name); \
+            slowPathCall.call(); \
+        } \
</ins><span class="cx">         NEXT_OPCODE(op_##name); \
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #define DEFINE_OP(name) \
</span><span class="cx">     case name: { \
</span><del>-        emit_##name(currentInstruction); \
</del><ins>+        if (m_bytecodeOffset &gt;= startBytecodeOffset) { \
+            emit_##name(currentInstruction); \
+        } \
</ins><span class="cx">         NEXT_OPCODE(name); \
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -177,7 +185,42 @@
</span><span class="cx"> 
</span><span class="cx">     m_callLinkInfoIndex = 0;
</span><span class="cx"> 
</span><ins>+    unsigned startBytecodeOffset = 0;
+    if (m_loopOSREntryBytecodeOffset &amp;&amp; m_codeBlock-&gt;inherits(*m_codeBlock-&gt;vm(), ProgramCodeBlock::info())) {
+        // We can only do this optimization because we execute ProgramCodeBlock's exactly once.
+        // This optimization would be invalid otherwise. When the LLInt determines it wants to
+        // do OSR entry into the baseline JIT in a loop, it will pass in the bytecode offset it
+        // was executing at when it kicked off our compilation. We only need to compile code for
+        // anything reachable from that bytecode offset.
+
+        // We only bother building the bytecode graph if it could save time and executable
+        // memory. We pick an arbitrary offset where we deem this is profitable.
+        if (m_loopOSREntryBytecodeOffset &gt;= 200) {
+            // As a simplification, we don't find all bytecode ranges that are unreachable.
+            // Instead, we just find the minimum bytecode offset that is reachable, and
+            // compile code from that bytecode offset onwards.
+
+            BytecodeGraph&lt;CodeBlock&gt; graph(m_codeBlock, m_instructions);
+            BytecodeBasicBlock* block = graph.findBasicBlockForBytecodeOffset(m_loopOSREntryBytecodeOffset);
+            RELEASE_ASSERT(block);
+
+            GraphNodeWorklist&lt;BytecodeBasicBlock*&gt; worklist;
+            startBytecodeOffset = UINT_MAX;
+            worklist.push(block);
+            while (BytecodeBasicBlock* block = worklist.pop()) {
+                startBytecodeOffset = std::min(startBytecodeOffset, block-&gt;leaderOffset());
+                worklist.pushAll(block-&gt;successors());
+            }
+        }
+    }
+
</ins><span class="cx">     for (m_bytecodeOffset = 0; m_bytecodeOffset &lt; instructionCount; ) {
</span><ins>+        if (m_bytecodeOffset == startBytecodeOffset &amp;&amp; startBytecodeOffset &gt; 0) {
+            // We've proven all bytecode instructions up until here are unreachable.
+            // Let's ensure that by crashing if it's ever hit.
+            breakpoint();
+        }
+
</ins><span class="cx">         if (m_disassembler)
</span><span class="cx">             m_disassembler-&gt;setForBytecodeMainPath(m_bytecodeOffset, label());
</span><span class="cx">         Instruction* currentInstruction = instructionsBegin + m_bytecodeOffset;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -191,7 +191,7 @@
</span><span class="cx">         static const int patchPutByIdDefaultOffset = 256;
</span><span class="cx"> 
</span><span class="cx">     public:
</span><del>-        JIT(VM*, CodeBlock* = 0);
</del><ins>+        JIT(VM*, CodeBlock* = 0, unsigned loopOSREntryBytecodeOffset = 0);
</ins><span class="cx">         ~JIT();
</span><span class="cx"> 
</span><span class="cx">         void compileWithoutLinking(JITCompilationEffort);
</span><span class="lines">@@ -199,9 +199,9 @@
</span><span class="cx"> 
</span><span class="cx">         void doMainThreadPreparationBeforeCompile();
</span><span class="cx">         
</span><del>-        static CompilationResult compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort)
</del><ins>+        static CompilationResult compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort, unsigned bytecodeOffset = 0)
</ins><span class="cx">         {
</span><del>-            return JIT(vm, codeBlock).privateCompile(effort);
</del><ins>+            return JIT(vm, codeBlock, bytecodeOffset).privateCompile(effort);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         static void compileGetByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
</span><span class="lines">@@ -966,6 +966,7 @@
</span><span class="cx">         bool m_canBeOptimized;
</span><span class="cx">         bool m_canBeOptimizedOrInlined;
</span><span class="cx">         bool m_shouldEmitProfiling;
</span><ins>+        unsigned m_loopOSREntryBytecodeOffset { 0 };
</ins><span class="cx">     } JIT_CLASS_ALIGNMENT;
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITWorklist.cpp (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -36,9 +36,9 @@
</span><span class="cx"> 
</span><span class="cx"> class JITWorklist::Plan : public ThreadSafeRefCounted&lt;JITWorklist::Plan&gt; {
</span><span class="cx"> public:
</span><del>-    Plan(CodeBlock* codeBlock)
</del><ins>+    Plan(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
</ins><span class="cx">         : m_codeBlock(codeBlock)
</span><del>-        , m_jit(codeBlock-&gt;vm(), codeBlock)
</del><ins>+        , m_jit(codeBlock-&gt;vm(), codeBlock, loopOSREntryBytecodeOffset)
</ins><span class="cx">     {
</span><span class="cx">         m_jit.doMainThreadPreparationBeforeCompile();
</span><span class="cx">     }
</span><span class="lines">@@ -83,9 +83,9 @@
</span><span class="cx">         return m_isFinishedCompiling;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    static void compileNow(CodeBlock* codeBlock)
</del><ins>+    static void compileNow(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
</ins><span class="cx">     {
</span><del>-        Plan plan(codeBlock);
</del><ins>+        Plan plan(codeBlock, loopOSREntryBytecodeOffset);
</ins><span class="cx">         plan.compileInThread();
</span><span class="cx">         plan.finalize();
</span><span class="cx">     }
</span><span class="lines">@@ -219,7 +219,7 @@
</span><span class="cx">     finalizePlans(myPlans);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JITWorklist::compileLater(CodeBlock* codeBlock)
</del><ins>+void JITWorklist::compileLater(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
</ins><span class="cx"> {
</span><span class="cx">     DeferGC deferGC(codeBlock-&gt;vm()-&gt;heap);
</span><span class="cx">     RELEASE_ASSERT(codeBlock-&gt;jitType() == JITCode::InterpreterThunk);
</span><span class="lines">@@ -230,7 +230,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (!Options::useConcurrentJIT()) {
</span><del>-        Plan::compileNow(codeBlock);
</del><ins>+        Plan::compileNow(codeBlock, loopOSREntryBytecodeOffset);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -244,7 +244,7 @@
</span><span class="cx">         
</span><span class="cx">         if (m_numAvailableThreads) {
</span><span class="cx">             m_planned.add(codeBlock);
</span><del>-            RefPtr&lt;Plan&gt; plan = adoptRef(new Plan(codeBlock));
</del><ins>+            RefPtr&lt;Plan&gt; plan = adoptRef(new Plan(codeBlock, loopOSREntryBytecodeOffset));
</ins><span class="cx">             m_plans.append(plan);
</span><span class="cx">             m_queue.append(plan);
</span><span class="cx">             m_condition-&gt;notifyAll(locker);
</span><span class="lines">@@ -268,10 +268,10 @@
</span><span class="cx">     // This works around the issue. If the concurrent JIT thread is convoyed, we revert to main
</span><span class="cx">     // thread compiles. This is probably not as good as if we had multiple JIT threads. Maybe we
</span><span class="cx">     // can do that someday.
</span><del>-    Plan::compileNow(codeBlock);
</del><ins>+    Plan::compileNow(codeBlock, loopOSREntryBytecodeOffset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JITWorklist::compileNow(CodeBlock* codeBlock)
</del><ins>+void JITWorklist::compileNow(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
</ins><span class="cx"> {
</span><span class="cx">     DeferGC deferGC(codeBlock-&gt;vm()-&gt;heap);
</span><span class="cx">     if (codeBlock-&gt;jitType() != JITCode::InterpreterThunk)
</span><span class="lines">@@ -298,7 +298,7 @@
</span><span class="cx">     codeBlock-&gt;resetJITData();
</span><span class="cx">     
</span><span class="cx">     // OK, just compile it.
</span><del>-    JIT::compile(codeBlock-&gt;vm(), codeBlock, JITCompilationMustSucceed);
</del><ins>+    JIT::compile(codeBlock-&gt;vm(), codeBlock, JITCompilationMustSucceed, loopOSREntryBytecodeOffset);
</ins><span class="cx">     codeBlock-&gt;ownerScriptExecutable()-&gt;installCode(codeBlock);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWorklisth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITWorklist.h (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWorklist.h        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/jit/JITWorklist.h        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -53,9 +53,9 @@
</span><span class="cx">     bool completeAllForVM(VM&amp;); // Return true if any JIT work happened.
</span><span class="cx">     void poll(VM&amp;);
</span><span class="cx">     
</span><del>-    void compileLater(CodeBlock*);
</del><ins>+    void compileLater(CodeBlock*, unsigned loopOSREntryBytecodeOffset = 0);
</ins><span class="cx">     
</span><del>-    void compileNow(CodeBlock*);
</del><ins>+    void compileNow(CodeBlock*, unsigned loopOSREntryBytecodeOffset = 0);
</ins><span class="cx">     
</span><span class="cx">     static JITWorklist* instance();
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -322,7 +322,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Returns true if we should try to OSR.
</span><del>-inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
</del><ins>+inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec, unsigned loopOSREntryBytecodeOffset = 0)
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     DeferGCForAWhile deferGC(vm.heap); // My callers don't set top callframe, so we don't want to GC here at all.
</span><span class="lines">@@ -346,7 +346,7 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     case JITCode::InterpreterThunk: {
</span><del>-        JITWorklist::instance()-&gt;compileLater(codeBlock);
</del><ins>+        JITWorklist::instance()-&gt;compileLater(codeBlock, loopOSREntryBytecodeOffset);
</ins><span class="cx">         return codeBlock-&gt;jitType() == JITCode::BaselineJIT;
</span><span class="cx">     }
</span><span class="cx">     default:
</span><span class="lines">@@ -422,12 +422,14 @@
</span><span class="cx">             codeBlock-&gt;llintExecuteCounter(), &quot;\n&quot;);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    unsigned loopOSREntryBytecodeOffset = pc - codeBlock-&gt;instructions().begin();
+
</ins><span class="cx">     if (!shouldJIT(exec, codeBlock)) {
</span><span class="cx">         codeBlock-&gt;dontJITAnytimeSoon();
</span><span class="cx">         LLINT_RETURN_TWO(0, 0);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (!jitCompileAndSetHeuristics(codeBlock, exec))
</del><ins>+    if (!jitCompileAndSetHeuristics(codeBlock, exec, loopOSREntryBytecodeOffset))
</ins><span class="cx">         LLINT_RETURN_TWO(0, 0);
</span><span class="cx">     
</span><span class="cx">     CODEBLOCK_LOG_EVENT(codeBlock, &quot;osrEntry&quot;, (&quot;at bc#&quot;, pc - codeBlock-&gt;instructions().begin()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCompletioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Completion.cpp (211641 => 211642)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Completion.cpp        2017-02-03 19:53:37 UTC (rev 211641)
+++ trunk/Source/JavaScriptCore/runtime/Completion.cpp        2017-02-03 20:00:53 UTC (rev 211642)
</span><span class="lines">@@ -96,18 +96,10 @@
</span><span class="cx"> 
</span><span class="cx">     CodeProfiling profile(source);
</span><span class="cx"> 
</span><del>-    ProgramExecutable* program = ProgramExecutable::create(exec, source);
-    ASSERT(scope.exception() || program);
-    if (!program) {
-        returnedException = scope.exception();
-        scope.clearException();
-        return jsUndefined();
-    }
-
</del><span class="cx">     if (!thisValue || thisValue.isUndefinedOrNull())
</span><span class="cx">         thisValue = exec-&gt;vmEntryGlobalObject();
</span><span class="cx">     JSObject* thisObj = jsCast&lt;JSObject*&gt;(thisValue.toThis(exec, NotStrictMode));
</span><del>-    JSValue result = exec-&gt;interpreter()-&gt;execute(program, exec, thisObj);
</del><ins>+    JSValue result = exec-&gt;interpreter()-&gt;executeProgram(source, exec, thisObj);
</ins><span class="cx"> 
</span><span class="cx">     if (scope.exception()) {
</span><span class="cx">         returnedException = scope.exception();
</span></span></pre>
</div>
</div>

</body>
</html>