<!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>[165128] 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/165128">165128</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-03-05 13:57:26 -0800 (Wed, 05 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Win32][LLINT] Crash when running JSC stress tests.
https://bugs.webkit.org/show_bug.cgi?id=129429

Source/JavaScriptCore:

On Windows the reserved stack space consists of committed memory, a guard page, and uncommitted memory,
where the guard page is a barrier between committed and uncommitted memory.
When data from the guard page is read or written, the guard page is moved, and memory is committed.
This is how the system grows the stack.
When using the C stack on Windows we need to precommit the needed stack space.
Otherwise we might crash later if we access uncommitted stack memory.
This can happen if we allocate stack space larger than the page guard size (4K).
The system does not get the chance to move the guard page, and commit more memory,
and we crash if uncommitted memory is accessed.
The MSVC compiler fixes this by inserting a call to the _chkstk() function,
when needed, see http://support.microsoft.com/kb/100775.

Patch by peavo@outlook.com &lt;peavo@outlook.com&gt; on 2014-03-05
Reviewed by Geoffrey Garen.

* JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Enable LLINT.
* jit/Repatch.cpp:
(JSC::writeBarrier): Compile fix when DFG_JIT is not enabled.
* offlineasm/x86.rb: Compile fix, and small simplification.
* runtime/VM.cpp:
(JSC::preCommitStackMemory): Added function to precommit stack memory.
(JSC::VM::updateStackLimit): Call function to precommit stack memory when stack limit is updated.

Source/WTF:

Patch by peavo@outlook.com &lt;peavo@outlook.com&gt; on 2014-03-05
Reviewed by Geoffrey Garen.

* wtf/Platform.h: Enable LLINT on Win32.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojLLIntLLIntAssemblybuildLLIntAssemblysh">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmx86rb">trunk/Source/JavaScriptCore/offlineasm/x86.rb</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="#trunkSourceWTFwtfPlatformh">trunk/Source/WTF/wtf/Platform.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2014-03-05  peavo@outlook.com  &lt;peavo@outlook.com&gt;
+
+        [Win32][LLINT] Crash when running JSC stress tests.
+        https://bugs.webkit.org/show_bug.cgi?id=129429
+
+        On Windows the reserved stack space consists of committed memory, a guard page, and uncommitted memory,
+        where the guard page is a barrier between committed and uncommitted memory.
+        When data from the guard page is read or written, the guard page is moved, and memory is committed.
+        This is how the system grows the stack.
+        When using the C stack on Windows we need to precommit the needed stack space.
+        Otherwise we might crash later if we access uncommitted stack memory.
+        This can happen if we allocate stack space larger than the page guard size (4K).
+        The system does not get the chance to move the guard page, and commit more memory,
+        and we crash if uncommitted memory is accessed.
+        The MSVC compiler fixes this by inserting a call to the _chkstk() function,
+        when needed, see http://support.microsoft.com/kb/100775.
+
+        Reviewed by Geoffrey Garen.
+
+        * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh: Enable LLINT.
+        * jit/Repatch.cpp:
+        (JSC::writeBarrier): Compile fix when DFG_JIT is not enabled.
+        * offlineasm/x86.rb: Compile fix, and small simplification.
+        * runtime/VM.cpp:
+        (JSC::preCommitStackMemory): Added function to precommit stack memory.
+        (JSC::VM::updateStackLimit): Call function to precommit stack memory when stack limit is updated.
+
</ins><span class="cx"> 2014-03-05  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojLLIntLLIntAssemblybuildLLIntAssemblysh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -29,4 +29,4 @@
</span><span class="cx"> 
</span><span class="cx"> # When enabling LLINT and switching to the x86 backend, use &quot;LowLevelInterpreterWin.asm&quot; as output file when running asm.rb.
</span><span class="cx"> 
</span><del>-/usr/bin/env ruby &quot;${SRCROOT}/offlineasm/asm.rb&quot; &quot;${SRCROOT}/llint/LowLevelInterpreter.asm&quot; &quot;${BUILT_PRODUCTS_DIR}/LLIntOffsetsExtractor/LLIntOffsetsExtractor${3}.exe&quot; &quot;LLIntAssembly.h&quot; || exit 1
</del><ins>+/usr/bin/env ruby &quot;${SRCROOT}/offlineasm/asm.rb&quot; &quot;${SRCROOT}/llint/LowLevelInterpreter.asm&quot; &quot;${BUILT_PRODUCTS_DIR}/LLIntOffsetsExtractor/LLIntOffsetsExtractor${3}.exe&quot; &quot;LowLevelInterpreterWin.asm&quot; || exit 1
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -824,9 +824,13 @@
</span><span class="cx">     ASSERT(owner != scratch1);
</span><span class="cx">     ASSERT(owner != scratch2);
</span><span class="cx"> 
</span><ins>+#if ENABLE(DFG_JIT)
</ins><span class="cx">     MacroAssembler::Jump definitelyNotMarked = DFG::SpeculativeJIT::genericWriteBarrier(jit, owner);
</span><ins>+#endif
</ins><span class="cx">     MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2, allocator);
</span><ins>+#if ENABLE(DFG_JIT)
</ins><span class="cx">     definitelyNotMarked.link(&amp;jit);
</span><ins>+#endif
</ins><span class="cx">     return call;
</span><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(GGC)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmx86rb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/x86.rb (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/x86.rb        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/JavaScriptCore/offlineasm/x86.rb        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -414,7 +414,7 @@
</span><span class="cx">     end
</span><span class="cx">     
</span><span class="cx">     def x86Operand(kind)
</span><del>-        if !isIntelSyntax || kind != :double
</del><ins>+        if !isIntelSyntax
</ins><span class="cx">             x86AddressOperand(:ptr)
</span><span class="cx">         else
</span><span class="cx">             &quot;#{getSizeString(kind)}[#{offset.value} + #{base.x86Operand(:ptr)} + #{index.x86Operand(:ptr)} * #{scale}]&quot;
</span><span class="lines">@@ -1326,7 +1326,7 @@
</span><span class="cx">                 }
</span><span class="cx">             end
</span><span class="cx">             op = operands[0].x86CallOperand(:ptr)
</span><del>-            if isMSVC &amp;&amp; (/\Allint_/.match(op) || /\Aslow_path/.match(op))
</del><ins>+            if isMSVC &amp;&amp; (operands[0].is_a? LabelReference)
</ins><span class="cx">                 writeSymbolToFile(op)
</span><span class="cx">             end
</span><span class="cx">             $asm.puts &quot;call #{op}&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -749,8 +749,37 @@
</span><span class="cx">     return oldReservedZoneSize;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(WIN)
+// On Windows the reserved stack space consists of committed memory, a guard page, and uncommitted memory,
+// where the guard page is a barrier between committed and uncommitted memory.
+// When data from the guard page is read or written, the guard page is moved, and memory is committed.
+// This is how the system grows the stack.
+// When using the C stack on Windows we need to precommit the needed stack space.
+// Otherwise we might crash later if we access uncommitted stack memory.
+// This can happen if we allocate stack space larger than the page guard size (4K).
+// The system does not get the chance to move the guard page, and commit more memory,
+// and we crash if uncommitted memory is accessed.
+// The MSVC compiler fixes this by inserting a call to the _chkstk() function,
+// when needed, see http://support.microsoft.com/kb/100775.
+// By touching every page up to the stack limit with a dummy operation,
+// we force the system to move the guard page, and commit memory.
+
+static void preCommitStackMemory(void* stackLimit)
+{
+    const int pageSize = 4096;
+    for (volatile char* p = reinterpret_cast&lt;char*&gt;(&amp;stackLimit); p &gt; stackLimit; p -= pageSize) {
+        char ch = *p;
+        *p = ch;
+    }
+}
+#endif
+
</ins><span class="cx"> inline void VM::updateStackLimit()
</span><span class="cx"> {
</span><ins>+#if PLATFORM(WIN)
+    void* lastStackLimit = m_stackLimit;
+#endif
+
</ins><span class="cx">     if (m_stackPointerAtVMEntry) {
</span><span class="cx">         ASSERT(wtfThreadData().stack().isGrowingDownward());
</span><span class="cx">         char* startOfStack = reinterpret_cast&lt;char*&gt;(m_stackPointerAtVMEntry);
</span><span class="lines">@@ -769,6 +798,10 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(WIN)
+    if (lastStackLimit != m_stackLimit)
+        preCommitStackMemory(m_stackLimit);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/WTF/ChangeLog        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2014-03-05  peavo@outlook.com  &lt;peavo@outlook.com&gt;
+
+        [Win32][LLINT] Crash when running JSC stress tests.
+        https://bugs.webkit.org/show_bug.cgi?id=129429
+
+        Reviewed by Geoffrey Garen.
+
+        * wtf/Platform.h: Enable LLINT on Win32.
+
</ins><span class="cx"> 2014-03-04  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Build the Udis86 disassembler
</span></span></pre></div>
<a id="trunkSourceWTFwtfPlatformh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Platform.h (165127 => 165128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Platform.h        2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/WTF/wtf/Platform.h        2014-03-05 21:57:26 UTC (rev 165128)
</span><span class="lines">@@ -640,7 +640,7 @@
</span><span class="cx"> #if !defined(ENABLE_JIT) \
</span><span class="cx">     &amp;&amp; (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(MIPS)) \
</span><span class="cx">     &amp;&amp; !OS(WINCE) \
</span><del>-    &amp;&amp; !OS(WINDOWS)
</del><ins>+    &amp;&amp; !(OS(WINDOWS) &amp;&amp; CPU(X86_64))
</ins><span class="cx"> #define ENABLE_JIT 1
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -693,8 +693,8 @@
</span><span class="cx">    low-level interpreter. */
</span><span class="cx"> #if !defined(ENABLE_LLINT) \
</span><span class="cx">     &amp;&amp; ENABLE(JIT) \
</span><del>-    &amp;&amp; (OS(DARWIN) || OS(LINUX) || OS(FREEBSD)) \
-    &amp;&amp; ((OS(DARWIN) &amp;&amp; !PLATFORM(EFL)) || PLATFORM(GTK)) \
</del><ins>+    &amp;&amp; (OS(DARWIN) || OS(LINUX) || OS(FREEBSD) || OS(WINDOWS)) \
+    &amp;&amp; ((OS(DARWIN) &amp;&amp; !PLATFORM(EFL)) || PLATFORM(GTK) || PLATFORM(WIN)) \
</ins><span class="cx">     &amp;&amp; (CPU(X86) || CPU(X86_64) || CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) || CPU(ARM64) || CPU(MIPS) || CPU(SH4))
</span><span class="cx"> #define ENABLE_LLINT 1
</span><span class="cx"> #endif
</span><span class="lines">@@ -783,7 +783,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> /* Configure the interpreter */
</span><del>-#if COMPILER(GCC)
</del><ins>+#if COMPILER(GCC) || COMPILER(MSVC)
</ins><span class="cx"> #define HAVE_COMPUTED_GOTO 1
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>