<!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>[163428] trunk/Source</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/163428">163428</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2014-02-04 21:32:21 -0800 (Tue, 04 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>The stack limit computation does not work for Windows.
&lt;https://webkit.org/b/128226&gt;

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

* llint/LowLevelInterpreter.cpp:
(JSC::CLoopRegister::CLoopRegister):
(JSC::CLoop::execute):
- Suppressed some compiler warnings for the C loop build.
* runtime/VM.cpp:
(JSC::VM::updateStackLimitWithReservedZoneSize):
- Use the new StackBounds::recursionLimit() to compute the stack limit
  the right way.

Source/WTF:

The current stack limit computation assumes that the stack is allocated
in high memory. On Windows, the stack seems to be allocated very near
address 0, and is smaller in size than our Options::maxPerThreadStackUsage().
This combination triggers a bug where StackBounds::recursionLimit()
underflows and computes a limit address that is ridiculously high in memory.
The net effect is that the Windows port thinks its out of stack space all
the time.

We now check for potential underflows in StackBounds and return an
appropriate limit address.

* wtf/StackBounds.h:
(WTF::StackBounds::recursionLimit):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpretercpp">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfStackBoundsh">trunk/Source/WTF/wtf/StackBounds.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (163427 => 163428)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-05 04:59:20 UTC (rev 163427)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-05 05:32:21 UTC (rev 163428)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2014-02-04  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        The stack limit computation does not work for Windows.
+        &lt;https://webkit.org/b/128226&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoopRegister::CLoopRegister):
+        (JSC::CLoop::execute):
+        - Suppressed some compiler warnings for the C loop build.
+        * runtime/VM.cpp:
+        (JSC::VM::updateStackLimitWithReservedZoneSize):
+        - Use the new StackBounds::recursionLimit() to compute the stack limit
+          the right way.
+
</ins><span class="cx"> 2014-02-04  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove &lt;iframe seamless&gt; support.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp (163427 => 163428)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp        2014-02-05 04:59:20 UTC (rev 163427)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp        2014-02-05 05:32:21 UTC (rev 163428)
</span><span class="lines">@@ -153,6 +153,7 @@
</span><span class="cx"> // pseudo register, as well as hides endianness differences.
</span><span class="cx"> 
</span><span class="cx"> struct CLoopRegister {
</span><ins>+    CLoopRegister() { i = static_cast&lt;intptr_t&gt;(0xbadbeef0baddbeef); }
</ins><span class="cx">     union {
</span><span class="cx">         intptr_t i;
</span><span class="cx">         uintptr_t u;
</span><span class="lines">@@ -479,6 +480,7 @@
</span><span class="cx">     #undef CAST
</span><span class="cx">     #undef SIGN_BIT32
</span><span class="cx"> 
</span><ins>+    return JSValue(); // to suppress a compiler warning.
</ins><span class="cx"> } // Interpreter::llintCLoopExecute()
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (163427 => 163428)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-02-05 04:59:20 UTC (rev 163427)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-02-05 05:32:21 UTC (rev 163428)
</span><span class="lines">@@ -745,8 +745,7 @@
</span><span class="cx">     if (stackPointerAtVMEntry) {
</span><span class="cx">         ASSERT(wtfThreadData().stack().isGrowingDownward());
</span><span class="cx">         char* startOfStack = reinterpret_cast&lt;char*&gt;(stackPointerAtVMEntry);
</span><del>-        char* desiredStackLimit = startOfStack - Options::maxPerThreadStackUsage() + reservedZoneSize;
-        stackLimit = wtfThreadData().stack().recursionLimit(reservedZoneSize, desiredStackLimit);
</del><ins>+        stackLimit = wtfThreadData().stack().recursionLimit(startOfStack, Options::maxPerThreadStackUsage(), reservedZoneSize);
</ins><span class="cx">     } else
</span><span class="cx">         stackLimit = wtfThreadData().stack().recursionLimit(reservedZoneSize);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (163427 => 163428)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-02-05 04:59:20 UTC (rev 163427)
+++ trunk/Source/WTF/ChangeLog        2014-02-05 05:32:21 UTC (rev 163428)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2014-02-04  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        The stack limit computation does not work for Windows.
+        &lt;https://webkit.org/b/128226&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        The current stack limit computation assumes that the stack is allocated
+        in high memory. On Windows, the stack seems to be allocated very near
+        address 0, and is smaller in size than our Options::maxPerThreadStackUsage().
+        This combination triggers a bug where StackBounds::recursionLimit()
+        underflows and computes a limit address that is ridiculously high in memory.
+        The net effect is that the Windows port thinks its out of stack space all
+        the time.
+
+        We now check for potential underflows in StackBounds and return an
+        appropriate limit address.
+
+        * wtf/StackBounds.h:
+        (WTF::StackBounds::recursionLimit):
+
</ins><span class="cx"> 2014-02-04  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove &lt;iframe seamless&gt; support.
</span></span></pre></div>
<a id="trunkSourceWTFwtfStackBoundsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/StackBounds.h (163427 => 163428)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/StackBounds.h        2014-02-05 04:59:20 UTC (rev 163427)
+++ trunk/Source/WTF/wtf/StackBounds.h        2014-02-05 05:32:21 UTC (rev 163428)
</span><span class="lines">@@ -69,15 +69,30 @@
</span><span class="cx">         return static_cast&lt;char*&gt;(m_bound) - minAvailableDelta;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void* recursionLimit(size_t hostZoneSize, void* desiredLimit) const
</del><ins>+    void* recursionLimit(char* startOfUserStack, size_t maxUserStack, size_t reservedZoneSize) const
</ins><span class="cx">     {
</span><span class="cx">         checkConsistency();
</span><ins>+        if (maxUserStack &lt; reservedZoneSize)
+            reservedZoneSize = maxUserStack;
+        size_t maxUserStackWithReservedZone = maxUserStack - reservedZoneSize;
+
</ins><span class="cx">         if (isGrowingDownward()) {
</span><del>-            char* endOfStackWithHostZone = reinterpret_cast&lt;char*&gt;(m_bound) + hostZoneSize;
-            return std::max(desiredLimit, reinterpret_cast&lt;void*&gt;(endOfStackWithHostZone));
</del><ins>+            char* endOfStackWithReservedZone = reinterpret_cast&lt;char*&gt;(m_bound) + reservedZoneSize;
+            if (startOfUserStack &lt; endOfStackWithReservedZone)
+                return endOfStackWithReservedZone;
+            size_t availableUserStack = startOfUserStack - endOfStackWithReservedZone;
+            if (maxUserStackWithReservedZone &gt; availableUserStack)
+                maxUserStackWithReservedZone = availableUserStack;
+            return startOfUserStack - maxUserStackWithReservedZone;
</ins><span class="cx">         }
</span><del>-        char* endOfStackWithHostZone = reinterpret_cast&lt;char*&gt;(m_bound) - hostZoneSize;
-        return std::min(desiredLimit, reinterpret_cast&lt;void*&gt;(endOfStackWithHostZone));
</del><ins>+
+        char* endOfStackWithReservedZone = reinterpret_cast&lt;char*&gt;(m_bound) - reservedZoneSize;
+        if (startOfUserStack &gt; endOfStackWithReservedZone)
+            return endOfStackWithReservedZone;
+        size_t availableUserStack = endOfStackWithReservedZone - startOfUserStack;
+        if (maxUserStackWithReservedZone &gt; availableUserStack)
+            maxUserStackWithReservedZone = availableUserStack;
+        return startOfUserStack + maxUserStackWithReservedZone;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool isGrowingDownward() const
</span></span></pre>
</div>
</div>

</body>
</html>