<!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>[160573] 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/160573">160573</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2013-12-13 16:39:45 -0800 (Fri, 13 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fix exception handling for the LLINT.
https://bugs.webkit.org/show_bug.cgi?id=125672.

Reviewed by Geoffrey Garen.

The baseline JIT exception handling is still broken.

* JavaScriptCore.order:
* llint/LLIntSlowPaths.cpp:
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
- updated the 32bit file with some of the changes to keep track with the 64bit
  one though it doesn't build yet. The build failure will clearly tell us some of
  the things that need to be fixed later.
* llint/LowLevelInterpreter64.asm:
- Called restoreStackPointerAfterCall() in op_catch and nativeCallTrampoline to
  restore the appropriate stack pointer.
- Renamed the restoreStackPointerAfterJSCall() macro to restoreStackPointerAfterCall
  because we also need to call it after a call to a native / host function.
- Removed llint_throw_from_native_call because it no longer does anything useful.
- Moved call to functionEpilogue() in nativeCallTrampoline before the exception
  check because we should have returned from the native / host function already.

  The Interpreter::unwind() code also relies on this. The VM will unwind and &quot;pop&quot;
  JS frames, but will stop at host frames. The host frame should pop itself. Then,
  we call Interpreter::unwind() again to continue for caller frames further up
  the stack.

- Removed the check for the sentinel frame in handleUncaughtException because
  we're guaranteed to be at the frame above the sentinel frame.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreJavaScriptCoreorder">branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.order</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathsh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h</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 (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2013-12-13  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Fix exception handling for the LLINT.
+        https://bugs.webkit.org/show_bug.cgi?id=125672.
+
+        Reviewed by Geoffrey Garen.
+
+        The baseline JIT exception handling is still broken.
+
+        * JavaScriptCore.order:
+        * llint/LLIntSlowPaths.cpp:
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        - updated the 32bit file with some of the changes to keep track with the 64bit
+          one though it doesn't build yet. The build failure will clearly tell us some of
+          the things that need to be fixed later.
+        * llint/LowLevelInterpreter64.asm:
+        - Called restoreStackPointerAfterCall() in op_catch and nativeCallTrampoline to
+          restore the appropriate stack pointer.
+        - Renamed the restoreStackPointerAfterJSCall() macro to restoreStackPointerAfterCall
+          because we also need to call it after a call to a native / host function.
+        - Removed llint_throw_from_native_call because it no longer does anything useful.
+        - Moved call to functionEpilogue() in nativeCallTrampoline before the exception
+          check because we should have returned from the native / host function already.
+
+          The Interpreter::unwind() code also relies on this. The VM will unwind and &quot;pop&quot;
+          JS frames, but will stop at host frames. The host frame should pop itself. Then,
+          we call Interpreter::unwind() again to continue for caller frames further up
+          the stack.
+
+        - Removed the check for the sentinel frame in handleUncaughtException because
+          we're guaranteed to be at the frame above the sentinel frame.
+
</ins><span class="cx"> 2013-12-13  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         jsCStack:REGRESSION: &quot;print(“My object: “ + { });” crashes LLINT in op_call
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreJavaScriptCoreorder"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.order (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.order        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.order        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -4981,7 +4981,6 @@
</span><span class="cx"> _llint_slow_path_debug
</span><span class="cx"> _llint_slow_path_profile_will_call
</span><span class="cx"> _llint_slow_path_profile_did_call
</span><del>-_llint_throw_from_native_call
</del><span class="cx"> _llint_begin
</span><span class="cx"> _llint_program_prologue
</span><span class="cx"> _llint_eval_prologue
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -1307,13 +1307,6 @@
</span><span class="cx">     LLINT_END();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(throw_from_native_call)
-{
-    LLINT_BEGIN();
-    ASSERT(vm.exception());
-    LLINT_END();
-}
-
</del><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN_NO_SET_PC();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -118,7 +118,6 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_debug);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_will_call);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_did_call);
</span><del>-LLINT_SLOW_PATH_HIDDEN_DECL(throw_from_native_call);
</del><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_exception);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -276,7 +276,7 @@
</span><span class="cx">     else
</span><span class="cx">         move calleeFramePtr, sp
</span><span class="cx">         call LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
</span><del>-        restoreStackPointerAfterJSCall()
</del><ins>+        restoreStackPointerAfterCall()
</ins><span class="cx">         dispatchAfterCall()
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="lines">@@ -290,7 +290,7 @@
</span><span class="cx">             else
</span><span class="cx">                 addp CallerFrameAndPCSize, t1, sp
</span><span class="cx">                 call callee
</span><del>-                restoreStackPointerAfterJSCall()
</del><ins>+                restoreStackPointerAfterCall()
</ins><span class="cx">                 dispatchAfterCall()
</span><span class="cx">             end
</span><span class="cx">         end)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -343,11 +343,23 @@
</span><span class="cx">     call temp
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro doHandleUncaughtException(extraStackSpace)
</del><span class="cx"> _handleUncaughtException:
</span><del>-    functionEpilogue(extraStackSpace)
</del><ins>+    loadp ScopeChain[cfr], t3
+    andp MarkedBlockMask, t3
+    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
+    loadp VM::callFrameForThrow[t3], cfr
+
+    # So far, we've unwound the stack to the frame just below the sentinel frame.
+    # We need to pop to the sentinel frame and do the necessary clean up for
+    # returning to the caller C frame.
+    loadp CallerFrame[cfr], cfr
+
+    loadp Callee[cfr], t3 # VM.topCallFrame
+    loadp ScopeChain[cfr], t6
+    storep t6, [t3]
+
+    callToJavaScriptEpilogue()
</ins><span class="cx">     ret
</span><del>-end
</del><span class="cx"> 
</span><span class="cx"> macro doReturnFromHostFunction(extraStackSpace)
</span><span class="cx">     functionEpilogue(extraStackSpace)
</span><span class="lines">@@ -2129,12 +2141,13 @@
</span><span class="cx">     else
</span><span class="cx">         error
</span><span class="cx">     end
</span><del>-    bineq VM::m_exception + TagOffset[t3], EmptyValueTag, .exception
</del><ins>+    bineq VM::m_exception + TagOffset[t3], EmptyValueTag, .handleException
</ins><span class="cx">     ret
</span><del>-.exception:
</del><ins>+
+.handleException:
</ins><span class="cx">     preserveReturnAddressAfterCall(t1) # This is really only needed on X86
</span><del>-    loadi ArgumentCount + TagOffset[cfr], PC
-    callSlowPath(_llint_throw_from_native_call)
</del><ins>+    storep cfr, VM::topCallFrame[t3]
+    restoreStackPointerAfterCall()
</ins><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> end
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (160572 => 160573)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-13 23:59:14 UTC (rev 160572)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-14 00:39:45 UTC (rev 160573)
</span><span class="lines">@@ -141,7 +141,7 @@
</span><span class="cx">     subp cfr, t1, sp
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro restoreStackPointerAfterJSCall()
</del><ins>+macro restoreStackPointerAfterCall()
</ins><span class="cx">     loadp CodeBlock[cfr], t1
</span><span class="cx">     loadi CodeBlock::m_numCalleeRegisters[t1], t1
</span><span class="cx">     lshiftp 3, t1
</span><span class="lines">@@ -280,10 +280,11 @@
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><span class="cx">     loadp VM::callFrameForThrow[t3], cfr
</span><span class="cx"> 
</span><del>-    bpeq CodeBlock[cfr], 1, .calleeFramePopped
</del><ins>+    # So far, we've unwound the stack to the frame just below the sentinel frame.
+    # We need to pop to the sentinel frame and do the necessary clean up for
+    # returning to the caller C frame.
</ins><span class="cx">     loadp CallerFrame[cfr], cfr
</span><span class="cx"> 
</span><del>-.calleeFramePopped:
</del><span class="cx">     loadp Callee[cfr], t3 # VM.topCallFrame
</span><span class="cx">     loadp ScopeChain[cfr], t6
</span><span class="cx">     storep t6, [t3]
</span><span class="lines">@@ -1852,6 +1853,8 @@
</span><span class="cx">     andp MarkedBlockMask, t3
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><span class="cx">     loadp VM::callFrameForThrow[t3], cfr
</span><ins>+    restoreStackPointerAfterCall()
+
</ins><span class="cx">     loadp CodeBlock[cfr], PB
</span><span class="cx">     loadp CodeBlock::m_instructions[PB], PB
</span><span class="cx">     loadp VM::targetInterpreterPCForThrow[t3], PC
</span><span class="lines">@@ -1956,19 +1959,14 @@
</span><span class="cx">         error
</span><span class="cx">     end
</span><span class="cx"> 
</span><del>-    btqnz VM::m_exception[t3], .exception
</del><span class="cx">     functionEpilogue()
</span><ins>+
+    btqnz VM::m_exception[t3], .handleException
</ins><span class="cx">     ret
</span><del>-.exception:
-    if X86_64
-        pop t1
-    end
-    loadi ArgumentCount + TagOffset[cfr], PC
-    loadp CodeBlock[cfr], PB
-    loadp CodeBlock::m_vm[PB], t0
-    loadp CodeBlock::m_instructions[PB], PB
-    storep cfr, VM::topCallFrame[t0]
-    callSlowPath(_llint_throw_from_native_call)
</del><ins>+
+.handleException:
+    storep cfr, VM::topCallFrame[t3]
+    restoreStackPointerAfterCall()
</ins><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> end
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>