Title: [165128] trunk/Source
Revision
165128
Author
[email protected]
Date
2014-03-05 13:57:26 -0800 (Wed, 05 Mar 2014)

Log Message

[Win32][LLINT] Crash when running JSC stress tests.
https://bugs.webkit.org/show_bug.cgi?id=129429

Source/_javascript_Core:

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 [email protected] <[email protected]> on 2014-03-05
Reviewed by Geoffrey Garen.

* _javascript_Core.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 [email protected] <[email protected]> on 2014-03-05
Reviewed by Geoffrey Garen.

* wtf/Platform.h: Enable LLINT on Win32.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (165127 => 165128)


--- trunk/Source/_javascript_Core/ChangeLog	2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-03-05 21:57:26 UTC (rev 165128)
@@ -1,3 +1,30 @@
+2014-03-05  [email protected]  <[email protected]>
+
+        [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.
+
+        * _javascript_Core.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.
+
 2014-03-05  Michael Saboff  <[email protected]>
 
         JSDataViewPrototype::getData() and setData() crash on platforms that don't allow unaligned accesses

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh (165127 => 165128)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh	2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh	2014-03-05 21:57:26 UTC (rev 165128)
@@ -29,4 +29,4 @@
 
 # When enabling LLINT and switching to the x86 backend, use "LowLevelInterpreterWin.asm" as output file when running asm.rb.
 
-/usr/bin/env ruby "${SRCROOT}/offlineasm/asm.rb" "${SRCROOT}/llint/LowLevelInterpreter.asm" "${BUILT_PRODUCTS_DIR}/LLIntOffsetsExtractor/LLIntOffsetsExtractor${3}.exe" "LLIntAssembly.h" || exit 1
+/usr/bin/env ruby "${SRCROOT}/offlineasm/asm.rb" "${SRCROOT}/llint/LowLevelInterpreter.asm" "${BUILT_PRODUCTS_DIR}/LLIntOffsetsExtractor/LLIntOffsetsExtractor${3}.exe" "LowLevelInterpreterWin.asm" || exit 1

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (165127 => 165128)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2014-03-05 21:57:26 UTC (rev 165128)
@@ -824,9 +824,13 @@
     ASSERT(owner != scratch1);
     ASSERT(owner != scratch2);
 
+#if ENABLE(DFG_JIT)
     MacroAssembler::Jump definitelyNotMarked = DFG::SpeculativeJIT::genericWriteBarrier(jit, owner);
+#endif
     MacroAssembler::Call call = storeToWriteBarrierBuffer(jit, owner, scratch1, scratch2, allocator);
+#if ENABLE(DFG_JIT)
     definitelyNotMarked.link(&jit);
+#endif
     return call;
 }
 #endif // ENABLE(GGC)

Modified: trunk/Source/_javascript_Core/offlineasm/x86.rb (165127 => 165128)


--- trunk/Source/_javascript_Core/offlineasm/x86.rb	2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/_javascript_Core/offlineasm/x86.rb	2014-03-05 21:57:26 UTC (rev 165128)
@@ -414,7 +414,7 @@
     end
     
     def x86Operand(kind)
-        if !isIntelSyntax || kind != :double
+        if !isIntelSyntax
             x86AddressOperand(:ptr)
         else
             "#{getSizeString(kind)}[#{offset.value} + #{base.x86Operand(:ptr)} + #{index.x86Operand(:ptr)} * #{scale}]"
@@ -1326,7 +1326,7 @@
                 }
             end
             op = operands[0].x86CallOperand(:ptr)
-            if isMSVC && (/\Allint_/.match(op) || /\Aslow_path/.match(op))
+            if isMSVC && (operands[0].is_a? LabelReference)
                 writeSymbolToFile(op)
             end
             $asm.puts "call #{op}"

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (165127 => 165128)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2014-03-05 21:56:51 UTC (rev 165127)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2014-03-05 21:57:26 UTC (rev 165128)
@@ -749,8 +749,37 @@
     return oldReservedZoneSize;
 }
 
+#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<char*>(&stackLimit); p > stackLimit; p -= pageSize) {
+        char ch = *p;
+        *p = ch;
+    }
+}
+#endif
+
 inline void VM::updateStackLimit()
 {
+#if PLATFORM(WIN)
+    void* lastStackLimit = m_stackLimit;
+#endif
+
     if (m_stackPointerAtVMEntry) {
         ASSERT(wtfThreadData().stack().isGrowingDownward());
         char* startOfStack = reinterpret_cast<char*>(m_stackPointerAtVMEntry);
@@ -769,6 +798,10 @@
 #endif
     }
 
+#if PLATFORM(WIN)
+    if (lastStackLimit != m_stackLimit)
+        preCommitStackMemory(m_stackLimit);
+#endif
 }
 
 #if ENABLE(FTL_JIT)

Modified: trunk/Source/WTF/ChangeLog (165127 => 165128)


--- 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)
@@ -1,3 +1,12 @@
+2014-03-05  [email protected]  <[email protected]>
+
+        [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.
+
 2014-03-04  Zan Dobersek  <[email protected]>
 
         [GTK] Build the Udis86 disassembler

Modified: trunk/Source/WTF/wtf/Platform.h (165127 => 165128)


--- 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)
@@ -640,7 +640,7 @@
 #if !defined(ENABLE_JIT) \
     && (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(MIPS)) \
     && !OS(WINCE) \
-    && !OS(WINDOWS)
+    && !(OS(WINDOWS) && CPU(X86_64))
 #define ENABLE_JIT 1
 #endif
 
@@ -693,8 +693,8 @@
    low-level interpreter. */
 #if !defined(ENABLE_LLINT) \
     && ENABLE(JIT) \
-    && (OS(DARWIN) || OS(LINUX) || OS(FREEBSD)) \
-    && ((OS(DARWIN) && !PLATFORM(EFL)) || PLATFORM(GTK)) \
+    && (OS(DARWIN) || OS(LINUX) || OS(FREEBSD) || OS(WINDOWS)) \
+    && ((OS(DARWIN) && !PLATFORM(EFL)) || PLATFORM(GTK) || PLATFORM(WIN)) \
     && (CPU(X86) || CPU(X86_64) || CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) || CPU(ARM64) || CPU(MIPS) || CPU(SH4))
 #define ENABLE_LLINT 1
 #endif
@@ -783,7 +783,7 @@
 #endif
 
 /* Configure the interpreter */
-#if COMPILER(GCC)
+#if COMPILER(GCC) || COMPILER(MSVC)
 #define HAVE_COMPUTED_GOTO 1
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to