<!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>[172867] 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/172867">172867</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2014-08-22 12:54:30 -0700 (Fri, 22 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION(<a href="http://trac.webkit.org/projects/webkit/changeset/163179">r163179</a>): Sporadic crash in js/dom/line-column-numbers.html test
https://bugs.webkit.org/show_bug.cgi?id=136111

Reviewed by Filip Pizlo.

The problem was that we weren't properly handling VM::topVMEntryFrame in two ways.

First in the case where we get an exception of a stack overflow during setup of the direct
callee frame of a VM entry frame, we need to throw the exception in the caller's frame.
This requires unrolling topVMEntryFrame while creating the exception object.  This is
accomplished with the renamed NativeCallFrameTracerWithRestore object.  As part of this,
split the JIT rollback exception handling to call a new helper,
callLookupExceptionHandlerFromCallerFrame, which will unroll the callFrame and VMEntryFrame.

Second, when we unwind to find a handler, we also need to unwind topVMCallFrame for the
case where we end up (re)throwing another exception after entering the catch block, but
before another vmEntry call.  Added VM::vmEntryFrameForThrow as a way similar to
VM::callFrameForThrow to pass the appropriate VMENtryFrame to the catch block.


* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* ftl/FTLCompile.cpp:
(JSC::FTL::fixFunctionBasedOnStackMaps):
* jit/JIT.cpp:
(JSC::JIT::privateCompileExceptionHandlers):
Split out the unroll cases to use the new helper callLookupExceptionHandlerFromCallerFrame()
to unwind both the callFrame and topVMEntryFrame.

* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::Interpreter::unwind):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
Added VMEntryFrame as another component to unwind.

* interpreter/Interpreter.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
Renamed and changed to save and restore topCallFrame and topVMEntryFrame around the setting of
both values.

* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::gotoNextFrame):
(JSC::StackVisitor::readNonInlinedFrame):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::vmEntryFrame):
Added code to unwind the VMEntryFrame.

* jit/CCallHelpers.h:
(JSC::CCallHelpers::jumpToExceptionHandler): Updated comment to indicate that the value
the handler should use for VM::topEntryFrame is in VM::vmEntryFrameForThrow.

* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_catch):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_catch):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
Added code to update VM::topVMEntryFrame from VM::vmEntryFrameForThrowOffset.

* jit/JITOperations.cpp:
* jit/JITOperations.h:
(JSC::operationThrowStackOverflowError):
(JSC::operationCallArityCheck):
(JSC::operationConstructArityCheck):

* runtime/VM.h:
(JSC::VM::vmEntryFrameForThrowOffset):
(JSC::VM::topVMEntryFrameOffset):
Added as the side channel to return the topVMEntryFrame that the handler should use.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</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="#trunkSourceJavaScriptCoreinterpreterStackVisitorcpp">trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterStackVisitorh">trunk/Source/JavaScriptCore/interpreter/StackVisitor.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitCCallHelpersh">trunk/Source/JavaScriptCore/jit/CCallHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITExceptionscpp">trunk/Source/JavaScriptCore/jit/JITExceptions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -1,3 +1,79 @@
</span><ins>+2014-08-21  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        REGRESSION(r163179): Sporadic crash in js/dom/line-column-numbers.html test
+        https://bugs.webkit.org/show_bug.cgi?id=136111
+
+        Reviewed by Filip Pizlo.
+
+        The problem was that we weren't properly handling VM::topVMEntryFrame in two ways.
+
+        First in the case where we get an exception of a stack overflow during setup of the direct
+        callee frame of a VM entry frame, we need to throw the exception in the caller's frame.
+        This requires unrolling topVMEntryFrame while creating the exception object.  This is
+        accomplished with the renamed NativeCallFrameTracerWithRestore object.  As part of this,
+        split the JIT rollback exception handling to call a new helper,
+        callLookupExceptionHandlerFromCallerFrame, which will unroll the callFrame and VMEntryFrame.
+
+        Second, when we unwind to find a handler, we also need to unwind topVMCallFrame for the
+        case where we end up (re)throwing another exception after entering the catch block, but
+        before another vmEntry call.  Added VM::vmEntryFrameForThrow as a way similar to
+        VM::callFrameForThrow to pass the appropriate VMENtryFrame to the catch block.
+
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileExceptionHandlers):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::fixFunctionBasedOnStackMaps):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileExceptionHandlers):
+        Split out the unroll cases to use the new helper callLookupExceptionHandlerFromCallerFrame()
+        to unwind both the callFrame and topVMEntryFrame.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::UnwindFunctor):
+        (JSC::UnwindFunctor::operator()):
+        (JSC::Interpreter::unwind):
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        Added VMEntryFrame as another component to unwind.
+
+        * interpreter/Interpreter.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+        (JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
+        (JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
+        Renamed and changed to save and restore topCallFrame and topVMEntryFrame around the setting of
+        both values.
+
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::gotoNextFrame):
+        (JSC::StackVisitor::readNonInlinedFrame):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::vmEntryFrame):
+        Added code to unwind the VMEntryFrame.
+
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::jumpToExceptionHandler): Updated comment to indicate that the value
+        the handler should use for VM::topEntryFrame is in VM::vmEntryFrameForThrow.
+
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_catch):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        Added code to update VM::topVMEntryFrame from VM::vmEntryFrameForThrowOffset.
+
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        (JSC::operationThrowStackOverflowError):
+        (JSC::operationCallArityCheck):
+        (JSC::operationConstructArityCheck):
+
+        * runtime/VM.h:
+        (JSC::VM::vmEntryFrameForThrowOffset):
+        (JSC::VM::topVMEntryFrameOffset):
+        Added as the side channel to return the topVMEntryFrame that the handler should use.
+
</ins><span class="cx"> 2014-08-22  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Disable ENABLE_IOS_{GESTURE, TOUCH}_EVENTS, and temporarily disable ENABLE_TOUCH_EVENTS
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -116,35 +116,39 @@
</span><span class="cx"> 
</span><span class="cx"> void JITCompiler::compileExceptionHandlers()
</span><span class="cx"> {
</span><del>-    if (m_exceptionChecks.empty() &amp;&amp; m_exceptionChecksWithCallFrameRollback.empty())
-        return;
</del><ins>+    if (!m_exceptionChecksWithCallFrameRollback.empty()) {
+        m_exceptionChecksWithCallFrameRollback.link(this);
</ins><span class="cx"> 
</span><del>-    Jump doLookup;
</del><ins>+        // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</ins><span class="cx"> 
</span><del>-    if (!m_exceptionChecksWithCallFrameRollback.empty()) {
-        m_exceptionChecksWithCallFrameRollback.link(this);
-        emitGetCallerFrameFromCallFrameHeaderPtr(GPRInfo::argumentGPR1);
-        doLookup = jump();
</del><ins>+#if CPU(X86)
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
+#endif
+        m_calls.append(CallLinkRecord(call(), lookupExceptionHandlerFromCallerFrame));
+
+        jumpToExceptionHandler();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_exceptionChecks.empty())
</del><ins>+    if (!m_exceptionChecks.empty()) {
</ins><span class="cx">         m_exceptionChecks.link(this);
</span><span class="cx"> 
</span><del>-    // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
-    move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</del><ins>+        // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</ins><span class="cx"> 
</span><del>-    if (doLookup.isSet())
-        doLookup.link(this);
-
-    move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
-
</del><span class="cx"> #if CPU(X86)
</span><del>-    // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
-    poke(GPRInfo::argumentGPR0);
-    poke(GPRInfo::argumentGPR1, 1);
</del><ins>+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
</ins><span class="cx"> #endif
</span><del>-    m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
-    jumpToExceptionHandler();
</del><ins>+        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
+
+        jumpToExceptionHandler();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JITCompiler::link(LinkBuffer&amp; linkBuffer)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -285,24 +285,28 @@
</span><span class="cx">         
</span><span class="cx">         // At this point it's perfectly fair to just blow away all state and restore the
</span><span class="cx">         // JS JIT view of the universe.
</span><ins>+        checkJIT.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
+        checkJIT.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister);
+
+        checkJIT.move(MacroAssembler::TrustedImmPtr(&amp;vm), GPRInfo::argumentGPR0);
</ins><span class="cx">         checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</span><ins>+        MacroAssembler::Call callLookupExceptionHandler = checkJIT.call();
+        checkJIT.jumpToExceptionHandler();
</ins><span class="cx"> 
</span><del>-        MacroAssembler::Label exceptionContinueArg1Set = checkJIT.label();
</del><ins>+        stackOverflowException = checkJIT.label();
</ins><span class="cx">         checkJIT.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
</span><span class="cx">         checkJIT.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister);
</span><span class="cx"> 
</span><span class="cx">         checkJIT.move(MacroAssembler::TrustedImmPtr(&amp;vm), GPRInfo::argumentGPR0);
</span><del>-        MacroAssembler::Call call = checkJIT.call();
</del><ins>+        checkJIT.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+        MacroAssembler::Call callLookupExceptionHandlerFromCallerFrame = checkJIT.call();
</ins><span class="cx">         checkJIT.jumpToExceptionHandler();
</span><span class="cx"> 
</span><del>-        stackOverflowException = checkJIT.label();
-        checkJIT.emitGetCallerFrameFromCallFrameHeaderPtr(GPRInfo::argumentGPR1);
-        checkJIT.jump(exceptionContinueArg1Set);
-
</del><span class="cx">         OwnPtr&lt;LinkBuffer&gt; linkBuffer = adoptPtr(new LinkBuffer(
</span><span class="cx">             vm, checkJIT, codeBlock, JITCompilationMustSucceed));
</span><del>-        linkBuffer-&gt;link(call, FunctionPtr(lookupExceptionHandler));
-        
</del><ins>+        linkBuffer-&gt;link(callLookupExceptionHandler, FunctionPtr(lookupExceptionHandler));
+        linkBuffer-&gt;link(callLookupExceptionHandlerFromCallerFrame, FunctionPtr(lookupExceptionHandlerFromCallerFrame));
+
</ins><span class="cx">         state.finalizer-&gt;handleExceptionsLinkBuffer = linkBuffer.release();
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -645,8 +645,9 @@
</span><span class="cx"> 
</span><span class="cx"> class UnwindFunctor {
</span><span class="cx"> public:
</span><del>-    UnwindFunctor(CallFrame*&amp; callFrame, bool isTermination, CodeBlock*&amp; codeBlock, HandlerInfo*&amp; handler)
-        : m_callFrame(callFrame)
</del><ins>+    UnwindFunctor(VMEntryFrame*&amp; vmEntryFrame, CallFrame*&amp; callFrame, bool isTermination, CodeBlock*&amp; codeBlock, HandlerInfo*&amp; handler)
+        : m_vmEntryFrame(vmEntryFrame)
+        , m_callFrame(callFrame)
</ins><span class="cx">         , m_isTermination(isTermination)
</span><span class="cx">         , m_codeBlock(codeBlock)
</span><span class="cx">         , m_handler(handler)
</span><span class="lines">@@ -656,6 +657,7 @@
</span><span class="cx">     StackVisitor::Status operator()(StackVisitor&amp; visitor)
</span><span class="cx">     {
</span><span class="cx">         VM&amp; vm = m_callFrame-&gt;vm();
</span><ins>+        m_vmEntryFrame = visitor-&gt;vmEntryFrame();
</ins><span class="cx">         m_callFrame = visitor-&gt;callFrame();
</span><span class="cx">         m_codeBlock = visitor-&gt;codeBlock();
</span><span class="cx">         unsigned bytecodeOffset = visitor-&gt;bytecodeOffset();
</span><span class="lines">@@ -673,13 +675,14 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    VMEntryFrame*&amp; m_vmEntryFrame;
</ins><span class="cx">     CallFrame*&amp; m_callFrame;
</span><span class="cx">     bool m_isTermination;
</span><span class="cx">     CodeBlock*&amp; m_codeBlock;
</span><span class="cx">     HandlerInfo*&amp; m_handler;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*&amp; callFrame, JSValue&amp; exceptionValue)
</del><ins>+NEVER_INLINE HandlerInfo* Interpreter::unwind(VMEntryFrame*&amp; vmEntryFrame, CallFrame*&amp; callFrame, JSValue&amp; exceptionValue)
</ins><span class="cx"> {
</span><span class="cx">     CodeBlock* codeBlock = callFrame-&gt;codeBlock();
</span><span class="cx">     ASSERT(codeBlock);
</span><span class="lines">@@ -724,7 +727,7 @@
</span><span class="cx">     HandlerInfo* handler = 0;
</span><span class="cx">     VM&amp; vm = callFrame-&gt;vm();
</span><span class="cx">     ASSERT(callFrame == vm.topCallFrame);
</span><del>-    UnwindFunctor functor(callFrame, isTermination, codeBlock, handler);
</del><ins>+    UnwindFunctor functor(vmEntryFrame, callFrame, isTermination, codeBlock, handler);
</ins><span class="cx">     callFrame-&gt;iterate(functor);
</span><span class="cx">     if (!handler)
</span><span class="cx">         return 0;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.h (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -175,18 +175,33 @@
</span><span class="cx">         {
</span><span class="cx">             ASSERT(vm);
</span><span class="cx">             ASSERT(callFrame);
</span><del>-            ASSERT(callFrame &lt; vm-&gt;topVMEntryFrame);
</del><span class="cx">             vm-&gt;topCallFrame = callFrame;
</span><span class="cx">         }
</span><ins>+    };
</ins><span class="cx"> 
</span><del>-        ALWAYS_INLINE NativeCallFrameTracer(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame)
</del><ins>+    class NativeCallFrameTracerWithRestore {
+    public:
+        ALWAYS_INLINE NativeCallFrameTracerWithRestore(VM* vm, VMEntryFrame* vmEntryFrame, CallFrame* callFrame)
+            : m_vm(vm)
</ins><span class="cx">         {
</span><span class="cx">             ASSERT(vm);
</span><span class="cx">             ASSERT(callFrame);
</span><del>-            ASSERT(callFrame &lt; vmEntryFrame);
</del><ins>+            m_savedTopVMEntryFrame = vm-&gt;topVMEntryFrame;
+            m_savedTopCallFrame = vm-&gt;topCallFrame;
</ins><span class="cx">             vm-&gt;topVMEntryFrame = vmEntryFrame;
</span><span class="cx">             vm-&gt;topCallFrame = callFrame;
</span><span class="cx">         }
</span><ins>+
+        ALWAYS_INLINE ~NativeCallFrameTracerWithRestore()
+        {
+            m_vm-&gt;topVMEntryFrame = m_savedTopVMEntryFrame;
+            m_vm-&gt;topCallFrame = m_savedTopCallFrame;
+        }
+
+    private:
+        VM* m_vm;
+        VMEntryFrame* m_savedTopVMEntryFrame;
+        CallFrame* m_savedTopCallFrame;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class Interpreter {
</span><span class="lines">@@ -236,7 +251,7 @@
</span><span class="cx">         
</span><span class="cx">         SamplingTool* sampler() { return m_sampler.get(); }
</span><span class="cx"> 
</span><del>-        NEVER_INLINE HandlerInfo* unwind(CallFrame*&amp;, JSValue&amp;);
</del><ins>+        NEVER_INLINE HandlerInfo* unwind(VMEntryFrame*&amp;, CallFrame*&amp;, JSValue&amp;);
</ins><span class="cx">         NEVER_INLINE void debug(CallFrame*, DebugHookID);
</span><span class="cx">         JSString* stackTraceAsString(ExecState*, Vector&lt;StackFrame&gt;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterStackVisitorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -61,10 +61,11 @@
</span><span class="cx">         InlineCallFrame* inlineCallFrame = m_frame.inlineCallFrame();
</span><span class="cx">         CodeOrigin* callerCodeOrigin = &amp;inlineCallFrame-&gt;caller;
</span><span class="cx">         readInlinedFrame(m_frame.callFrame(), callerCodeOrigin);
</span><del>-
-    } else
</del><ins>+        return;
+    }
</ins><span class="cx"> #endif // ENABLE(DFG_JIT)
</span><del>-        readFrame(m_frame.callerFrame());
</del><ins>+    m_frame.m_VMEntryFrame = m_frame.m_CallerVMEntryFrame;
+    readFrame(m_frame.callerFrame());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StackVisitor::readFrame(CallFrame* callFrame)
</span><span class="lines">@@ -116,9 +117,9 @@
</span><span class="cx"> {
</span><span class="cx">     m_frame.m_callFrame = callFrame;
</span><span class="cx">     m_frame.m_argumentCountIncludingThis = callFrame-&gt;argumentCountIncludingThis();
</span><del>-    VMEntryFrame* currentVMEntryFrame = m_frame.m_VMEntryFrame;
-    m_frame.m_callerFrame = callFrame-&gt;callerFrame(m_frame.m_VMEntryFrame);
-    m_frame.m_callerIsVMEntryFrame = currentVMEntryFrame != m_frame.m_VMEntryFrame;
</del><ins>+    m_frame.m_CallerVMEntryFrame = m_frame.m_VMEntryFrame;
+    m_frame.m_callerFrame = callFrame-&gt;callerFrame(m_frame.m_CallerVMEntryFrame);
+    m_frame.m_callerIsVMEntryFrame = m_frame.m_CallerVMEntryFrame != m_frame.m_VMEntryFrame;
</ins><span class="cx">     m_frame.m_callee = callFrame-&gt;callee();
</span><span class="cx">     m_frame.m_scope = callFrame-&gt;scope();
</span><span class="cx">     m_frame.m_codeBlock = callFrame-&gt;codeBlock();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterStackVisitorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/StackVisitor.h (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/StackVisitor.h        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/interpreter/StackVisitor.h        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx"> 
</span><span class="cx">         Arguments* createArguments();
</span><span class="cx">         Arguments* existingArguments();
</span><ins>+        VMEntryFrame* vmEntryFrame() const { return m_VMEntryFrame; }
</ins><span class="cx">         CallFrame* callFrame() const { return m_callFrame; }
</span><span class="cx">         
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -97,6 +98,7 @@
</span><span class="cx">         size_t m_index;
</span><span class="cx">         size_t m_argumentCountIncludingThis;
</span><span class="cx">         VMEntryFrame* m_VMEntryFrame;
</span><ins>+        VMEntryFrame* m_CallerVMEntryFrame;
</ins><span class="cx">         CallFrame* m_callerFrame;
</span><span class="cx">         JSObject* m_callee;
</span><span class="cx">         JSScope* m_scope;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitCCallHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/CCallHelpers.h (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -1700,6 +1700,7 @@
</span><span class="cx">     void jumpToExceptionHandler()
</span><span class="cx">     {
</span><span class="cx">         // genericUnwind() leaves the handler CallFrame* in vm-&gt;callFrameForThrow,
</span><ins>+        // the topVMEntryFrame for the handler in vm-&gt;vmEntryFrameForThrow,
</ins><span class="cx">         // and the address of the handler in vm-&gt;targetMachinePCForThrow.
</span><span class="cx">         loadPtr(&amp;vm()-&gt;targetMachinePCForThrow, GPRInfo::regT1);
</span><span class="cx">         jump(GPRInfo::regT1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -722,35 +722,38 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::privateCompileExceptionHandlers()
</span><span class="cx"> {
</span><del>-    if (m_exceptionChecks.empty() &amp;&amp; m_exceptionChecksWithCallFrameRollback.empty())
-        return;
</del><ins>+    if (!m_exceptionChecksWithCallFrameRollback.empty()) {
+        m_exceptionChecksWithCallFrameRollback.link(this);
</ins><span class="cx"> 
</span><del>-    Jump doLookup;
</del><ins>+        // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
</ins><span class="cx"> 
</span><del>-    if (!m_exceptionChecksWithCallFrameRollback.empty()) {
-        m_exceptionChecksWithCallFrameRollback.link(this);
-        emitGetCallerFrameFromCallFrameHeaderPtr(GPRInfo::argumentGPR1);
-        doLookup = jump();
</del><ins>+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+
+#if CPU(X86)
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
+#endif
+        m_calls.append(CallRecord(call(), (unsigned)-1, FunctionPtr(lookupExceptionHandlerFromCallerFrame).value()));
+        jumpToExceptionHandler();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_exceptionChecks.empty())
</del><ins>+    if (!m_exceptionChecks.empty()) {
</ins><span class="cx">         m_exceptionChecks.link(this);
</span><del>-    
-    // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
-    move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</del><span class="cx"> 
</span><del>-    if (doLookup.isSet())
-        doLookup.link(this);
</del><ins>+        // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
</ins><span class="cx"> 
</span><del>-    move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
-
</del><span class="cx"> #if CPU(X86)
</span><del>-    // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
-    poke(GPRInfo::argumentGPR0);
-    poke(GPRInfo::argumentGPR1, 1);
</del><ins>+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
</ins><span class="cx"> #endif
</span><del>-    m_calls.append(CallRecord(call(), (unsigned)-1, FunctionPtr(lookupExceptionHandler).value()));
-    jumpToExceptionHandler();
</del><ins>+        m_calls.append(CallRecord(call(), (unsigned)-1, FunctionPtr(lookupExceptionHandler).value()));
+        jumpToExceptionHandler();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned JIT::frameRegisterCountFor(CodeBlock* codeBlock)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITExceptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITExceptions.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITExceptions.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/JITExceptions.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -48,7 +48,8 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT(exceptionValue);
</span><del>-    HandlerInfo* handler = vm-&gt;interpreter-&gt;unwind(callFrame, exceptionValue); // This may update callFrame.
</del><ins>+    VMEntryFrame* vmEntryFrame = vm-&gt;topVMEntryFrame;
+    HandlerInfo* handler = vm-&gt;interpreter-&gt;unwind(vmEntryFrame, callFrame, exceptionValue); // This may update vmEntryFrame and callFrame.
</ins><span class="cx"> 
</span><span class="cx">     void* catchRoutine;
</span><span class="cx">     Instruction* catchPCForInterpreter = 0;
</span><span class="lines">@@ -62,6 +63,7 @@
</span><span class="cx">     } else
</span><span class="cx">         catchRoutine = LLInt::getCodePtr(handleUncaughtException);
</span><span class="cx">     
</span><ins>+    vm-&gt;vmEntryFrameForThrow = vmEntryFrame;
</ins><span class="cx">     vm-&gt;callFrameForThrow = callFrame;
</span><span class="cx">     vm-&gt;targetMachinePCForThrow = catchRoutine;
</span><span class="cx">     vm-&gt;targetInterpreterPCForThrow = catchPCForInterpreter;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -532,6 +532,8 @@
</span><span class="cx"> {
</span><span class="cx">     move(TrustedImmPtr(m_vm), regT3);
</span><span class="cx">     load64(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
</span><ins>+    load64(Address(regT3, VM::vmEntryFrameForThrowOffset()), regT0);
+    store64(regT0, Address(regT3, VM::topVMEntryFrameOffset()));
</ins><span class="cx"> 
</span><span class="cx">     addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -813,6 +813,8 @@
</span><span class="cx">     move(TrustedImmPtr(m_vm), regT3);
</span><span class="cx">     // operationThrow returns the callFrame for the handler.
</span><span class="cx">     load32(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
</span><ins>+    load32(Address(regT3, VM::vmEntryFrameForThrowOffset()), regT0);
+    store32(regT0, Address(regT3, VM::topVMEntryFrameOffset()));
</ins><span class="cx"> 
</span><span class="cx">     addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -86,7 +86,7 @@
</span><span class="cx">     if (!callerFrame)
</span><span class="cx">         callerFrame = exec;
</span><span class="cx"> 
</span><del>-    NativeCallFrameTracer tracer(vm, vmEntryFrame, callerFrame);
</del><ins>+    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
</ins><span class="cx">     ErrorHandlingScope errorScope(*vm);
</span><span class="cx">     vm-&gt;throwException(callerFrame, createStackOverflowError(callerFrame));
</span><span class="cx"> }
</span><span class="lines">@@ -101,7 +101,7 @@
</span><span class="cx"> 
</span><span class="cx">     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &amp;stack, CodeForCall);
</span><span class="cx">     if (missingArgCount &lt; 0) {
</span><del>-        NativeCallFrameTracer tracer(vm, vmEntryFrame, callerFrame);
</del><ins>+        NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
</ins><span class="cx">         throwStackOverflowError(callerFrame);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx"> 
</span><span class="cx">     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &amp;stack, CodeForConstruct);
</span><span class="cx">     if (missingArgCount &lt; 0) {
</span><del>-        NativeCallFrameTracer tracer(vm, vmEntryFrame, callerFrame);
</del><ins>+        NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
</ins><span class="cx">         throwStackOverflowError(callerFrame);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1790,7 +1790,7 @@
</span><span class="cx">     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
</span><span class="cx">     vm-&gt;throwException(exec, exceptionValue);
</span><span class="cx"> 
</span><del>-    // Results stored out-of-band in vm.targetMachinePCForThrow &amp; vm.callFrameForThrow
</del><ins>+    // Results stored out-of-band in vm.targetMachinePCForThrow, vm.callFrameForThrow &amp; vm.vmEntryFrameForThrow
</ins><span class="cx">     genericUnwind(vm, exec, exceptionValue);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1838,6 +1838,21 @@
</span><span class="cx">     ASSERT(vm-&gt;targetMachinePCForThrow);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
+{
+    VMEntryFrame* vmEntryFrame = vm-&gt;topVMEntryFrame;
+    CallFrame* callerFrame = exec-&gt;callerFrame(vmEntryFrame);
+    ASSERT(callerFrame);
+
+    NativeCallFrameTracer tracer(vm, callerFrame);
+
+    JSValue exceptionValue = vm-&gt;exception();
+    ASSERT(exceptionValue);
+    
+    genericUnwind(vm, callerFrame, exceptionValue);
+    ASSERT(vm-&gt;targetMachinePCForThrow);
+}
+
</ins><span class="cx"> void JIT_OPERATION operationVMHandleException(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -205,6 +205,7 @@
</span><span class="cx"> // the return location from one of the calls out to one of the helper operations above.
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION lookupExceptionHandler(VM*, ExecState*) WTF_INTERNAL;
</span><ins>+void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM*, ExecState*) WTF_INTERNAL;
</ins><span class="cx"> void JIT_OPERATION operationVMHandleException(ExecState*) WTF_INTERNAL;
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationThrowStackOverflowError(ExecState*, CodeBlock*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -2048,6 +2048,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>+    loadp VM::vmEntryFrameForThrow[t3], t0
+    storep t0, VM::topVMEntryFrame[t3]
</ins><span class="cx">     restoreStackPointerAfterCall()
</span><span class="cx"> 
</span><span class="cx">     loadi VM::targetInterpreterPCForThrow[t3], PC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -1903,6 +1903,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>+    loadp VM::vmEntryFrameForThrow[t3], t0
+    storep t0, VM::topVMEntryFrame[t3]
</ins><span class="cx">     restoreStackPointerAfterCall()
</span><span class="cx"> 
</span><span class="cx">     loadp CodeBlock[cfr], PB
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (172866 => 172867)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-22 19:39:51 UTC (rev 172866)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-22 19:54:30 UTC (rev 172867)
</span><span class="lines">@@ -346,6 +346,16 @@
</span><span class="cx">             return OBJECT_OFFSETOF(VM, m_exception);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        static ptrdiff_t vmEntryFrameForThrowOffset()
+        {
+            return OBJECT_OFFSETOF(VM, vmEntryFrameForThrow);
+        }
+
+        static ptrdiff_t topVMEntryFrameOffset()
+        {
+            return OBJECT_OFFSETOF(VM, topVMEntryFrame);
+        }
+
</ins><span class="cx">         static ptrdiff_t callFrameForThrowOffset()
</span><span class="cx">         {
</span><span class="cx">             return OBJECT_OFFSETOF(VM, callFrameForThrow);
</span><span class="lines">@@ -401,6 +411,7 @@
</span><span class="cx"> 
</span><span class="cx">         JSValue hostCallReturnValue;
</span><span class="cx">         ExecState* newCallFrameReturnValue;
</span><ins>+        VMEntryFrame* vmEntryFrameForThrow;
</ins><span class="cx">         ExecState* callFrameForThrow;
</span><span class="cx">         void* targetMachinePCForThrow;
</span><span class="cx">         Instruction* targetInterpreterPCForThrow;
</span></span></pre>
</div>
</div>

</body>
</html>