<!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>[160967] 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/160967">160967</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2013-12-21 11:25:09 -0800 (Sat, 21 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack: Update the VMEntryScope's stack limit when the VM enters/exits ErrorMode.
https://bugs.webkit.org/show_bug.cgi?id=126009.

Not yet reviewed.

1. Renamed JSStack::updateStackLimit() to setStackLimit() because that
   is what it actually does. We're going to repurpose the updateStackLimit
   name for another function.

2. Fixed a bug in setStackLimit() where setJSStackLimit() was called with
   the value of newEnd which points past the end of the stack. The fix is
   to add 1 to point at the last slot at top of the stack. This is what is
   the users of the jsStackLimit value expects.

3. Introduce the new JSStack::updateStackLimit() which is responsible for
   re-setting the current stack limit. updateStackLimit() will handle both
   cases of the JS stack being on the C stack or a separate stack.

   For the C stack case, JStack::updateStackLimit() will check if a
   VMEntryScope has been installed in the VM. If so, it will tell the
   VMEntryScope to do the real work of updating the stack limit. The
   VMEntryScope will take into account whether the VM's Interpreter is
   in an error handling mode or not when determining the amount of host
   zone space to reserve on the stack for computing the stack limit value.

4. Interpreter::ErrorHandlingMode now calls JSStack::updateStackLimit
   whenever it enters / exit error handling mode. This allows the stack
   limit to change with the error mode change.

5. A lot of places in the code were throwing StackOverflowErrors by
   creating and throwing the error themselves instead of using the
   throwStackOverflowError() helper function. As a result, the VM never
   got the chance to enter error mode. This is a bug and is now fixed by
   making all these sites use throwStackOverflowError() instead.

   For sites that can't use throwStackOverflowError(), I updated them to
   instantiate Interpreter::ErrorHandlingMode to set the error mode
   appropriately.

6. Made JSStack::enableErrorStackReserve() and disableErrorStackReserve()
   private. They are no longer called from outside of JSStack.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::ErrorHandlingMode::ErrorHandlingMode):
(JSC::Interpreter::ErrorHandlingMode::~ErrorHandlingMode):
(JSC::sizeFrameForVarargs):
* interpreter/JSStack.cpp:
(JSC::JSStack::JSStack):
(JSC::JSStack::growSlowCase):
(JSC::JSStack::updateStackLimit):
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
(JSC::JSStack::shrink):
(JSC::JSStack::setStackLimit):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* parser/ParserError.h:
(JSC::ParserError::toErrorObject):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/JSONObject.cpp:
(JSC::Walker::walk):
* runtime/StringRecursionChecker.cpp:
(JSC::StringRecursionChecker::throwStackOverflowError):
* runtime/VMEntryScope.cpp:
(JSC::VMEntryScope::VMEntryScope):
(JSC::VMEntryScope::updateStackLimit):
* runtime/VMEntryScope.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterInterpretercpp">branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackcpp">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITOperationscpp">branches/jsCStack/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreparserParserErrorh">branches/jsCStack/Source/JavaScriptCore/parser/ParserError.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeCommonSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeJSONObjectcpp">branches/jsCStack/Source/JavaScriptCore/runtime/JSONObject.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeStringRecursionCheckercpp">branches/jsCStack/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeVMEntryScopecpp">branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeVMEntryScopeh">branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -1,3 +1,75 @@
</span><ins>+2013-12-21  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        CStack: Update the VMEntryScope's stack limit when the VM enters/exits ErrorMode.
+        https://bugs.webkit.org/show_bug.cgi?id=126009.
+
+        Not yet reviewed.
+
+        1. Renamed JSStack::updateStackLimit() to setStackLimit() because that
+           is what it actually does. We're going to repurpose the updateStackLimit
+           name for another function.
+
+        2. Fixed a bug in setStackLimit() where setJSStackLimit() was called with
+           the value of newEnd which points past the end of the stack. The fix is
+           to add 1 to point at the last slot at top of the stack. This is what is
+           the users of the jsStackLimit value expects.
+
+        3. Introduce the new JSStack::updateStackLimit() which is responsible for
+           re-setting the current stack limit. updateStackLimit() will handle both
+           cases of the JS stack being on the C stack or a separate stack.
+
+           For the C stack case, JStack::updateStackLimit() will check if a
+           VMEntryScope has been installed in the VM. If so, it will tell the
+           VMEntryScope to do the real work of updating the stack limit. The
+           VMEntryScope will take into account whether the VM's Interpreter is
+           in an error handling mode or not when determining the amount of host
+           zone space to reserve on the stack for computing the stack limit value.
+
+        4. Interpreter::ErrorHandlingMode now calls JSStack::updateStackLimit
+           whenever it enters / exit error handling mode. This allows the stack
+           limit to change with the error mode change.
+
+        5. A lot of places in the code were throwing StackOverflowErrors by
+           creating and throwing the error themselves instead of using the
+           throwStackOverflowError() helper function. As a result, the VM never
+           got the chance to enter error mode. This is a bug and is now fixed by
+           making all these sites use throwStackOverflowError() instead.
+
+           For sites that can't use throwStackOverflowError(), I updated them to
+           instantiate Interpreter::ErrorHandlingMode to set the error mode
+           appropriately.
+
+        6. Made JSStack::enableErrorStackReserve() and disableErrorStackReserve()
+           private. They are no longer called from outside of JSStack.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::ErrorHandlingMode::ErrorHandlingMode):
+        (JSC::Interpreter::ErrorHandlingMode::~ErrorHandlingMode):
+        (JSC::sizeFrameForVarargs):
+        * interpreter/JSStack.cpp:
+        (JSC::JSStack::JSStack):
+        (JSC::JSStack::growSlowCase):
+        (JSC::JSStack::updateStackLimit):
+        * interpreter/JSStack.h:
+        * interpreter/JSStackInlines.h:
+        (JSC::JSStack::shrink):
+        (JSC::JSStack::setStackLimit):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * parser/ParserError.h:
+        (JSC::ParserError::toErrorObject):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/JSONObject.cpp:
+        (JSC::Walker::walk):
+        * runtime/StringRecursionChecker.cpp:
+        (JSC::StringRecursionChecker::throwStackOverflowError):
+        * runtime/VMEntryScope.cpp:
+        (JSC::VMEntryScope::VMEntryScope):
+        (JSC::VMEntryScope::updateStackLimit):
+        * runtime/VMEntryScope.h:
+
</ins><span class="cx"> 2013-12-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Register restoration thunk should restore the ArgumentCount after it restores registers
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -94,9 +94,8 @@
</span><span class="cx"> Interpreter::ErrorHandlingMode::ErrorHandlingMode(ExecState *exec)
</span><span class="cx">     : m_interpreter(*exec-&gt;interpreter())
</span><span class="cx"> {
</span><del>-    if (!m_interpreter.m_errorHandlingModeReentry)
-        m_interpreter.stack().enableErrorStackReserve();
</del><span class="cx">     m_interpreter.m_errorHandlingModeReentry++;
</span><ins>+    m_interpreter.stack().updateStackLimit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Interpreter::ErrorHandlingMode::~ErrorHandlingMode()
</span><span class="lines">@@ -104,7 +103,7 @@
</span><span class="cx">     m_interpreter.m_errorHandlingModeReentry--;
</span><span class="cx">     ASSERT(m_interpreter.m_errorHandlingModeReentry &gt;= 0);
</span><span class="cx">     if (!m_interpreter.m_errorHandlingModeReentry)
</span><del>-        m_interpreter.stack().disableErrorStackReserve();
</del><ins>+        m_interpreter.stack().updateStackLimit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue eval(CallFrame* callFrame)
</span><span class="lines">@@ -161,7 +160,7 @@
</span><span class="cx">         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
</span><span class="cx">         CallFrame* newCallFrame = CallFrame::create(callFrame-&gt;registers() - paddedCalleeFrameOffset);
</span><span class="cx">         if (argumentCountIncludingThis &gt; Arguments::MaxArguments + 1 || !stack-&gt;ensureCapacityFor(newCallFrame-&gt;registers())) {
</span><del>-            callFrame-&gt;vm().throwException(callFrame, createStackOverflowError(callFrame));
</del><ins>+            throwStackOverflowError(callFrame);
</ins><span class="cx">             return 0;
</span><span class="cx">         }
</span><span class="cx">         return newCallFrame;
</span><span class="lines">@@ -172,7 +171,7 @@
</span><span class="cx">         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
</span><span class="cx">         CallFrame* newCallFrame = CallFrame::create(callFrame-&gt;registers() - paddedCalleeFrameOffset);
</span><span class="cx">         if (!stack-&gt;ensureCapacityFor(newCallFrame-&gt;registers())) {
</span><del>-            callFrame-&gt;vm().throwException(callFrame, createStackOverflowError(callFrame));
</del><ins>+            throwStackOverflowError(callFrame);
</ins><span class="cx">             return 0;
</span><span class="cx">         }
</span><span class="cx">         return newCallFrame;
</span><span class="lines">@@ -189,7 +188,7 @@
</span><span class="cx">         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
</span><span class="cx">         CallFrame* newCallFrame = CallFrame::create(callFrame-&gt;registers() - paddedCalleeFrameOffset);
</span><span class="cx">         if (argCount &gt; Arguments::MaxArguments || !stack-&gt;ensureCapacityFor(newCallFrame-&gt;registers())) {
</span><del>-            callFrame-&gt;vm().throwException(callFrame, createStackOverflowError(callFrame));
</del><ins>+            throwStackOverflowError(callFrame);
</ins><span class="cx">             return 0;
</span><span class="cx">         }
</span><span class="cx">         return newCallFrame;
</span><span class="lines">@@ -201,7 +200,7 @@
</span><span class="cx">         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
</span><span class="cx">         CallFrame* newCallFrame = CallFrame::create(callFrame-&gt;registers() - paddedCalleeFrameOffset);
</span><span class="cx">         if (argCount &gt; Arguments::MaxArguments || !stack-&gt;ensureCapacityFor(newCallFrame-&gt;registers())) {
</span><del>-            callFrame-&gt;vm().throwException(callFrame, createStackOverflowError(callFrame));
</del><ins>+            throwStackOverflowError(callFrame);
</ins><span class="cx">             return 0;
</span><span class="cx">         }
</span><span class="cx">         return newCallFrame;
</span><span class="lines">@@ -212,7 +211,7 @@
</span><span class="cx">     unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
</span><span class="cx">     CallFrame* newCallFrame = CallFrame::create(callFrame-&gt;registers() - paddedCalleeFrameOffset);
</span><span class="cx">     if (argCount &gt; Arguments::MaxArguments || !stack-&gt;ensureCapacityFor(newCallFrame-&gt;registers())) {
</span><del>-        callFrame-&gt;vm().throwException(callFrame,  createStackOverflowError(callFrame));
</del><ins>+        throwStackOverflowError(callFrame);
</ins><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx">     return newCallFrame;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ConservativeRoots.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><ins>+#include &quot;VMEntryScope.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -50,7 +51,7 @@
</span><span class="cx">     ASSERT(capacity &amp;&amp; isPageAligned(capacity));
</span><span class="cx"> 
</span><span class="cx">     m_reservation = PageReservation::reserve(roundUpAllocationSize(capacity * sizeof(Register), commitSize), OSAllocator::JSVMStackPages);
</span><del>-    updateStackLimit(highAddress());
</del><ins>+    setStackLimit(highAddress());
</ins><span class="cx">     m_commitEnd = highAddress();
</span><span class="cx">     
</span><span class="cx">     m_lastStackTop = baseOfStack();
</span><span class="lines">@@ -73,7 +74,7 @@
</span><span class="cx">     // If we have already committed enough memory to satisfy this request,
</span><span class="cx">     // just update the end pointer and return.
</span><span class="cx">     if (newEnd &gt;= m_commitEnd) {
</span><del>-        updateStackLimit(newEnd);
</del><ins>+        setStackLimit(newEnd);
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -89,7 +90,7 @@
</span><span class="cx">     m_reservation.commit(reinterpret_cast&lt;char*&gt;(m_commitEnd) - delta, delta);
</span><span class="cx">     addToCommittedByteCount(delta);
</span><span class="cx">     m_commitEnd = reinterpret_cast_ptr&lt;Register*&gt;(reinterpret_cast&lt;char*&gt;(m_commitEnd) - delta);
</span><del>-    updateStackLimit(newEnd);
</del><ins>+    setStackLimit(newEnd);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -175,4 +176,16 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSStack::updateStackLimit()
+{
+#if ENABLE(LLINT_C_LOOP)
+    if (m_vm.interpreter-&gt;isInErrorHandlingMode())
+        enableErrorStackReserve();
+    else
+        disableErrorStackReserve();
+#endif
+    if (m_vm.entryScope)
+        m_vm.entryScope-&gt;updateStackLimit();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -83,6 +83,8 @@
</span><span class="cx">         
</span><span class="cx">         bool ensureCapacityFor(Register* newTopOfStack);
</span><span class="cx"> 
</span><ins>+        void updateStackLimit();
+
</ins><span class="cx">         void gatherConservativeRoots(ConservativeRoots&amp;);
</span><span class="cx">         void gatherConservativeRoots(ConservativeRoots&amp;, JITStubRoutineSet&amp;, CodeBlockSet&amp;);
</span><span class="cx">         void sanitizeStack();
</span><span class="lines">@@ -105,9 +107,6 @@
</span><span class="cx"> 
</span><span class="cx">         bool containsAddress(Register* address) { return (lowAddress() &lt;= address &amp;&amp; address &lt;= highAddress()); }
</span><span class="cx"> 
</span><del>-        void enableErrorStackReserve();
-        void disableErrorStackReserve();
-
</del><span class="cx"> #if ENABLE(DEBUG_JSSTACK)
</span><span class="cx">         void installFence(CallFrame*, const char *function = &quot;&quot;, int lineNo = 0);
</span><span class="cx">         void validateFence(CallFrame*, const char *function = &quot;&quot;, int lineNo = 0);
</span><span class="lines">@@ -152,8 +151,11 @@
</span><span class="cx">         void releaseExcessCapacity();
</span><span class="cx">         void addToCommittedByteCount(long);
</span><span class="cx"> 
</span><del>-        void updateStackLimit(Register* newEnd);
</del><ins>+        void setStackLimit(Register* newEnd);
</ins><span class="cx"> 
</span><ins>+        void enableErrorStackReserve();
+        void disableErrorStackReserve();
+
</ins><span class="cx">         VM&amp; m_vm;
</span><span class="cx">         Register* m_end;
</span><span class="cx">         Register* m_commitEnd;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -169,7 +169,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (newEnd &gt;= m_end)
</span><span class="cx">         return;
</span><del>-    updateStackLimit(newEnd);
</del><ins>+    setStackLimit(newEnd);
</ins><span class="cx">     if (m_end == baseOfStack() &amp;&amp; (m_commitEnd - baseOfStack()) &gt;= maxExcessCapacity)
</span><span class="cx">         releaseExcessCapacity();
</span><span class="cx"> }
</span><span class="lines">@@ -182,11 +182,11 @@
</span><span class="cx">     return growSlowCase(newEnd);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void JSStack::updateStackLimit(Register* newEnd)
</del><ins>+inline void JSStack::setStackLimit(Register* newEnd)
</ins><span class="cx"> {
</span><span class="cx">     m_end = newEnd;
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><del>-    m_vm.setJSStackLimit(newEnd);
</del><ins>+    m_vm.setJSStackLimit(newEnd + 1);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITOperations.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITOperations.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITOperations.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -79,6 +79,7 @@
</span><span class="cx">         callerFrame = exec;
</span><span class="cx"> 
</span><span class="cx">     NativeCallFrameTracer tracer(vm, callerFrame);
</span><ins>+    Interpreter::ErrorHandlingMode mode(callerFrame);
</ins><span class="cx">     vm-&gt;throwException(callerFrame, createStackOverflowError(callerFrame));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -92,7 +93,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>-        vm-&gt;throwException(callerFrame, createStackOverflowError(callerFrame));
</del><ins>+        throwStackOverflowError(callerFrame);
</ins><span class="cx"> 
</span><span class="cx">     return missingArgCount;
</span><span class="cx"> }
</span><span class="lines">@@ -107,7 +108,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>-        vm-&gt;throwException(callerFrame, createStackOverflowError(callerFrame));
</del><ins>+        throwStackOverflowError(callerFrame);
</ins><span class="cx"> 
</span><span class="cx">     return missingArgCount;
</span><span class="cx"> }
</span><span class="lines">@@ -703,7 +704,7 @@
</span><span class="cx">         FunctionExecutable* functionExecutable = static_cast&lt;FunctionExecutable*&gt;(executable);
</span><span class="cx">         JSObject* error = functionExecutable-&gt;prepareForExecution(execCallee, callee-&gt;scope(), kind);
</span><span class="cx">         if (error) {
</span><del>-            vm-&gt;throwException(exec, createStackOverflowError(exec));
</del><ins>+            throwStackOverflowError(exec);
</ins><span class="cx">             return reinterpret_cast&lt;char*&gt;(vm-&gt;getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
</span><span class="cx">         }
</span><span class="cx">         codeBlock = functionExecutable-&gt;codeBlockFor(kind);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -451,6 +451,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     {
</span><span class="cx">         exec = exec-&gt;callerFrame();
</span><ins>+        Interpreter::ErrorHandlingMode mode(exec);
</ins><span class="cx">         CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
</span><span class="cx">         pc = returnToThrowForThrownException(exec);
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreparserParserErrorh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/parser/ParserError.h (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/parser/ParserError.h        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/parser/ParserError.h        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -94,8 +94,10 @@
</span><span class="cx">             return addErrorInfo(globalObject-&gt;globalExec(), createSyntaxError(globalObject, m_message), m_line, source);
</span><span class="cx">         case EvalError:
</span><span class="cx">             return createSyntaxError(globalObject, m_message);
</span><del>-        case StackOverflow:
</del><ins>+        case StackOverflow: {
+            Interpreter::ErrorHandlingMode mode(globalObject-&gt;globalExec());
</ins><span class="cx">             return createStackOverflowError(globalObject);
</span><ins>+        }
</ins><span class="cx">         case OutOfMemory:
</span><span class="cx">             return createOutOfMemoryError(globalObject);
</span><span class="cx">         }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -190,6 +190,7 @@
</span><span class="cx">     int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, &amp;vm.interpreter-&gt;stack(), CodeForCall);
</span><span class="cx">     if (slotsToAdd &lt; 0) {
</span><span class="cx">         exec = exec-&gt;callerFrame();
</span><ins>+        Interpreter::ErrorHandlingMode mode(exec);
</ins><span class="cx">         CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
</span><span class="cx">         RETURN_TWO(bitwise_cast&lt;void*&gt;(static_cast&lt;uintptr_t&gt;(1)), exec);
</span><span class="cx">     }
</span><span class="lines">@@ -202,6 +203,7 @@
</span><span class="cx">     int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, &amp;vm.interpreter-&gt;stack(), CodeForConstruct);
</span><span class="cx">     if (slotsToAdd &lt; 0) {
</span><span class="cx">         exec = exec-&gt;callerFrame();
</span><ins>+        Interpreter::ErrorHandlingMode mode(exec);
</ins><span class="cx">         CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
</span><span class="cx">         RETURN_TWO(bitwise_cast&lt;void*&gt;(static_cast&lt;uintptr_t&gt;(1)), exec);
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeJSONObjectcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/JSONObject.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/JSONObject.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/JSONObject.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -654,7 +654,7 @@
</span><span class="cx">                 ASSERT(inValue.isObject());
</span><span class="cx">                 ASSERT(isJSArray(asObject(inValue)) || asObject(inValue)-&gt;inherits(JSArray::info()));
</span><span class="cx">                 if (objectStack.size() + arrayStack.size() &gt; maximumFilterRecursion)
</span><del>-                    return m_exec-&gt;vm().throwException(m_exec, createStackOverflowError(m_exec));
</del><ins>+                    return throwStackOverflowError(m_exec);
</ins><span class="cx"> 
</span><span class="cx">                 JSArray* array = asArray(inValue);
</span><span class="cx">                 arrayStack.push(array);
</span><span class="lines">@@ -705,7 +705,7 @@
</span><span class="cx">                 ASSERT(inValue.isObject());
</span><span class="cx">                 ASSERT(!isJSArray(asObject(inValue)) &amp;&amp; !asObject(inValue)-&gt;inherits(JSArray::info()));
</span><span class="cx">                 if (objectStack.size() + arrayStack.size() &gt; maximumFilterRecursion)
</span><del>-                    return m_exec-&gt;vm().throwException(m_exec, createStackOverflowError(m_exec));
</del><ins>+                    return throwStackOverflowError(m_exec);
</ins><span class="cx"> 
</span><span class="cx">                 JSObject* object = asObject(inValue);
</span><span class="cx">                 objectStack.push(object);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeStringRecursionCheckercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> JSValue StringRecursionChecker::throwStackOverflowError()
</span><span class="cx"> {
</span><del>-    return m_exec-&gt;vm().throwException(m_exec, createStackOverflowError(m_exec));
</del><ins>+    return JSC::throwStackOverflowError(m_exec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue StringRecursionChecker::emptyString()
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeVMEntryScopecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.cpp (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.cpp        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.cpp        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -53,8 +53,7 @@
</span><span class="cx">     // Clear the exception stack between entries
</span><span class="cx">     vm.clearExceptionStack();
</span><span class="cx"> 
</span><del>-    void* limit = m_stack.recursionLimit(requiredCapacity());
-    vm.setStackLimit(limit);
</del><ins>+    updateStackLimit();
</ins><span class="cx">     vm.setLastStackTop(m_stack.origin());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -65,6 +64,12 @@
</span><span class="cx">     m_vm.setLastStackTop(m_prevLastStackTop);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void VMEntryScope::updateStackLimit()
+{
+    void* limit = m_stack.recursionLimit(requiredCapacity());
+    m_vm.setStackLimit(limit);
+}
+
</ins><span class="cx"> size_t VMEntryScope::requiredCapacity() const
</span><span class="cx"> {
</span><span class="cx">     Interpreter* interpreter = m_vm.interpreter;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeVMEntryScopeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.h (160966 => 160967)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.h        2013-12-21 18:51:04 UTC (rev 160966)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/VMEntryScope.h        2013-12-21 19:25:09 UTC (rev 160967)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE VMEntryScope(VM&amp;, JSGlobalObject*);
</span><span class="cx">     JS_EXPORT_PRIVATE ~VMEntryScope();
</span><span class="cx"> 
</span><ins>+    void updateStackLimit();
</ins><span class="cx">     JSGlobalObject* globalObject() const { return m_globalObject; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre>
</div>
</div>

</body>
</html>