<!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>[160808] branches/jsCStack/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/160808">160808</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2013-12-18 16:48:54 -0800 (Wed, 18 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack: Fix LLINT to baseline JIT OSR.
https://bugs.webkit.org/show_bug.cgi?id=125957.

Reviewed by Michael Saboff.

1. In LLINT prologue code, when taking the OSR path, we don't actually
   need the OSR slow path function to return the new stackPointer value.
   Instead, the OSR prep code in the prologue needs to restore the
   previous sp because we are going to jump to the prologue of the
   target codeBlock, which will assume that the stack pointer to be
   pointing to the top of the caller frame.

   To do this, we simply set stackPointer to the &quot;new&quot; callFrameRegister
   before we pop the &quot;old&quot; callFrame address into the callFrameRegister.

2. In the LLINT checkSwitchToJITForLoop() macro, if we're going to take
   the OSR path, we'll need to set the stackPointer to the new topOfFrame
   for the target codeBlock. Hence, we make llint_loop_osr return
   exec-&gt;topOfFrame() for this purpose.

3. Previously, CallFrame::topOfFrame() (renamed from CallFrame::frameExtent())
   would return the address of the slot past the top of the frame. It now
   returns the slot at the top of the frame as it should.

* interpreter/CallFrame.cpp:
(JSC::CallFrame::topOfFrameInternal):
* interpreter/CallFrame.h:
(JSC::ExecState::topOfFrame):
* interpreter/JSStack.cpp:
(JSC::JSStack::disableErrorStackReserve):
* interpreter/JSStackInlines.h:
(JSC::JSStack::getTopOfFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::entryOSR):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterCallFramecpp">branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterCallFrameh">branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackcpp">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2013-12-18  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        CStack: Fix LLINT to baseline JIT OSR.
+        https://bugs.webkit.org/show_bug.cgi?id=125957.
+
+        Reviewed by Michael Saboff.
+
+        1. In LLINT prologue code, when taking the OSR path, we don't actually
+           need the OSR slow path function to return the new stackPointer value.
+           Instead, the OSR prep code in the prologue needs to restore the
+           previous sp because we are going to jump to the prologue of the
+           target codeBlock, which will assume that the stack pointer to be
+           pointing to the top of the caller frame.
+
+           To do this, we simply set stackPointer to the &quot;new&quot; callFrameRegister
+           before we pop the &quot;old&quot; callFrame address into the callFrameRegister.
+
+        2. In the LLINT checkSwitchToJITForLoop() macro, if we're going to take
+           the OSR path, we'll need to set the stackPointer to the new topOfFrame
+           for the target codeBlock. Hence, we make llint_loop_osr return
+           exec-&gt;topOfFrame() for this purpose.
+
+        3. Previously, CallFrame::topOfFrame() (renamed from CallFrame::frameExtent())
+           would return the address of the slot past the top of the frame. It now
+           returns the slot at the top of the frame as it should.
+
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::topOfFrameInternal):
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::topOfFrame):
+        * interpreter/JSStack.cpp:
+        (JSC::JSStack::disableErrorStackReserve):
+        * interpreter/JSStackInlines.h:
+        (JSC::JSStack::getTopOfFrame):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::entryOSR):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
</ins><span class="cx"> 2013-12-18  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CStack Branch: getHostCallReturnValue shouldn't pop the callFrame
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterCallFramecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.cpp (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.cpp        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.cpp        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -116,11 +116,11 @@
</span><span class="cx">     return CodeOrigin(locationAsBytecodeOffset());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Register* CallFrame::frameExtentInternal()
</del><ins>+Register* CallFrame::topOfFrameInternal()
</ins><span class="cx"> {
</span><span class="cx">     CodeBlock* codeBlock = this-&gt;codeBlock();
</span><span class="cx">     ASSERT(codeBlock);
</span><del>-    return registers() + virtualRegisterForLocal(codeBlock-&gt;frameRegisterCount()).offset();
</del><ins>+    return registers() + virtualRegisterForLocal(codeBlock-&gt;frameRegisterCount() - 1).offset();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSGlobalObject* CallFrame::vmEntryGlobalObject()
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterCallFrameh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.h (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.h        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/CallFrame.h        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -177,15 +177,13 @@
</span><span class="cx">         // CodeOrigin(0) if we're in native code.
</span><span class="cx">         CodeOrigin codeOrigin();
</span><span class="cx"> 
</span><del>-        Register* frameExtent()
</del><ins>+        Register* topOfFrame()
</ins><span class="cx">         {
</span><span class="cx">             if (isVMEntrySentinel() || !codeBlock())
</span><del>-                return registers() - 1;
-            return frameExtentInternal();
</del><ins>+                return registers();
+            return topOfFrameInternal();
</ins><span class="cx">         }
</span><span class="cx">     
</span><del>-        Register* frameExtentInternal();
-
</del><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx">         Instruction* currentVPC() const
</span><span class="cx">         {
</span><span class="lines">@@ -319,6 +317,8 @@
</span><span class="cx">         ExecState();
</span><span class="cx">         ~ExecState();
</span><span class="cx"> 
</span><ins>+        Register* topOfFrameInternal();
+
</ins><span class="cx">         // The following are for internal use in debugging and verification
</span><span class="cx">         // code only and not meant as an API for general usage:
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -170,7 +170,7 @@
</span><span class="cx">     // enabled the reserve was not previously in use. Hence, it is safe to
</span><span class="cx">     // shrink back to that m_useableEnd.
</span><span class="cx">     if (m_end &lt; m_useableEnd) {
</span><del>-        ASSERT(m_topCallFrame-&gt;frameExtent() &gt;= m_useableEnd);
</del><ins>+        ASSERT(m_topCallFrame-&gt;topOfFrame() &gt; m_useableEnd);
</ins><span class="cx">         shrink(m_useableEnd);
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -37,7 +37,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (UNLIKELY(!frame))
</span><span class="cx">         return getBaseOfStack();
</span><del>-    return frame-&gt;frameExtent();
</del><ins>+    return frame-&gt;topOfFrame() - 1;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline Register* JSStack::getTopOfStack()
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -332,15 +332,15 @@
</span><span class="cx">     
</span><span class="cx">     if (!shouldJIT(exec)) {
</span><span class="cx">         codeBlock-&gt;dontJITAnytimeSoon();
</span><del>-        LLINT_RETURN_TWO(0, exec);
</del><ins>+        LLINT_RETURN_TWO(0, 0);
</ins><span class="cx">     }
</span><span class="cx">     if (!jitCompileAndSetHeuristics(codeBlock, exec))
</span><del>-        LLINT_RETURN_TWO(0, exec);
</del><ins>+        LLINT_RETURN_TWO(0, 0);
</ins><span class="cx">     
</span><span class="cx">     if (kind == Prologue)
</span><del>-        LLINT_RETURN_TWO(codeBlock-&gt;jitCode()-&gt;executableAddress(), exec);
</del><ins>+        LLINT_RETURN_TWO(codeBlock-&gt;jitCode()-&gt;executableAddress(), 0);
</ins><span class="cx">     ASSERT(kind == ArityCheck);
</span><del>-    LLINT_RETURN_TWO(codeBlock-&gt;jitCodeWithArityCheck().executableAddress(), exec);
</del><ins>+    LLINT_RETURN_TWO(codeBlock-&gt;jitCodeWithArityCheck().executableAddress(), 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LLINT_SLOW_PATH_DECL(entry_osr)
</span><span class="lines">@@ -380,11 +380,11 @@
</span><span class="cx">     
</span><span class="cx">     if (!shouldJIT(exec)) {
</span><span class="cx">         codeBlock-&gt;dontJITAnytimeSoon();
</span><del>-        LLINT_RETURN_TWO(0, exec);
</del><ins>+        LLINT_RETURN_TWO(0, 0);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (!jitCompileAndSetHeuristics(codeBlock, exec))
</span><del>-        LLINT_RETURN_TWO(0, exec);
</del><ins>+        LLINT_RETURN_TWO(0, 0);
</ins><span class="cx">     
</span><span class="cx">     ASSERT(codeBlock-&gt;jitType() == JITCode::BaselineJIT);
</span><span class="cx">     
</span><span class="lines">@@ -397,7 +397,7 @@
</span><span class="cx">     void* jumpTarget = codeBlock-&gt;jitCode()-&gt;executableAddressAtOffset(mapping-&gt;m_machineCodeOffset);
</span><span class="cx">     ASSERT(jumpTarget);
</span><span class="cx">     
</span><del>-    LLINT_RETURN_TWO(jumpTarget, exec);
</del><ins>+    LLINT_RETURN_TWO(jumpTarget, exec-&gt;topOfFrame());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LLINT_SLOW_PATH_DECL(replace)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -366,9 +366,9 @@
</span><span class="cx">         baddis 5, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t1], .continue
</span><span class="cx">         cCall2(osrSlowPath, cfr, PC)
</span><span class="cx">         btpz t0, .recover
</span><del>-        # FIXME: Turn off OSR entry
-        # pop cfr # pop the callerFrame since we will jump to a function that wants to save it
-        # jmp t0
</del><ins>+        move cfr, sp # restore the previous sp
+        pop cfr # pop the callerFrame since we will jump to a function that wants to save it
+        jmp t0
</ins><span class="cx">     .recover:
</span><span class="cx">         codeBlockGetter(t1)
</span><span class="cx">     .continue:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -407,8 +407,8 @@
</span><span class="cx">         macro ()
</span><span class="cx">             storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">             cCall2(_llint_loop_osr, cfr, PC)
</span><del>-            move t1, cfr
</del><span class="cx">             btpz t0, .recover
</span><ins>+            move t1, sp
</ins><span class="cx">             jmp t0
</span><span class="cx">         .recover:
</span><span class="cx">             loadi ArgumentCount + TagOffset[cfr], PC
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (160807 => 160808)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-19 00:48:54 UTC (rev 160808)
</span><span class="lines">@@ -349,10 +349,9 @@
</span><span class="cx">             storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">             prepareStateForCCall()
</span><span class="cx">             cCall2(_llint_loop_osr, cfr, PC)
</span><del>-            move t1, cfr
</del><span class="cx">             btpz t0, .recover
</span><del>-            # FIXME: CStack - Turn OSR entry back on
-            # jmp t0
</del><ins>+            move t1, sp
+            jmp t0
</ins><span class="cx">         .recover:
</span><span class="cx">             move t3, PB
</span><span class="cx">             loadi ArgumentCount + TagOffset[cfr], PC
</span></span></pre>
</div>
</div>

</body>
</html>