WebAssembly: option to crash if no fast memory is available
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Mar 2017 04:02:17 +0000 (04:02 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Mar 2017 04:02:17 +0000 (04:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170219

Reviewed by Mark Lam.

* runtime/Options.h:
* wasm/WasmMemory.cpp:
(JSC::Wasm::webAssemblyCouldntGetFastMemory):
(JSC::Wasm::tryGetFastMemory):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@214526 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/wasm/WasmMemory.cpp

index 871383b..14a9bbc 100644 (file)
@@ -1,3 +1,15 @@
+2017-03-28  JF Bastien  <jfbastien@apple.com>
+
+        WebAssembly: option to crash if no fast memory is available
+        https://bugs.webkit.org/show_bug.cgi?id=170219
+
+        Reviewed by Mark Lam.
+
+        * runtime/Options.h:
+        * wasm/WasmMemory.cpp:
+        (JSC::Wasm::webAssemblyCouldntGetFastMemory):
+        (JSC::Wasm::tryGetFastMemory):
+
 2017-03-28  Mark Lam  <mark.lam@apple.com>
 
         The Mutator should not be able to steal the conn if the Collector hasn't reached the NotRunning phase yet.
index a0d9109..e8ab1ee 100644 (file)
@@ -434,6 +434,7 @@ typedef const char* optionString;
     \
     v(bool, simulateWebAssemblyLowMemory, false, Normal, "If true, the Memory object won't mmap the full 'maximum' range and instead will allocate the minimum required amount.") \
     v(bool, useWebAssemblyFastMemory, true, Normal, "If true, we will try to use a 32-bit address space with a signal handler to bounds check wasm memory.") \
+    v(bool, crashIfWebAssemblyCantFastMemory, false, Normal, "If true, we will crash if we can't obtain fast memory for wasm.") \
     v(bool, useWebAssemblyFastTLS, true, Normal, "If true, we will try to use fast thread-local storage if available on the current platform.")
 
 
index 3d176c8..2b65210 100644 (file)
@@ -42,6 +42,11 @@ namespace {
 const bool verbose = false;
 }
 
+static NEVER_INLINE NO_RETURN_DUE_TO_CRASH void webAssemblyCouldntGetFastMemory()
+{
+    CRASH();
+}
+
 inline bool mmapBytes(size_t bytes, void*& memory)
 {
     dataLogIf(verbose, "Attempting to mmap ", bytes, " bytes: ");
@@ -98,16 +103,6 @@ const HashSet<void*>& viewActiveFastMemories(const AbstractLocker& locker)
 
 inline bool tryGetFastMemory(VM& vm, void*& memory, size_t& mappedCapacity, MemoryMode& mode)
 {
-    // We might GC here so we should be holding the API lock.
-    // FIXME: We should be able to syncronously trigger the GC from another thread.
-    ASSERT(vm.currentThreadIsHoldingAPILock());
-    if (!fastMemoryEnabled())
-        return false;
-
-    // We need to be sure we have a stub prior to running code.
-    if (!vm.getCTIStub(throwExceptionFromWasmThunkGenerator).size())
-        return false;
-
     auto dequeFastMemory = [&] () -> bool {
         // FIXME: We should eventually return these to the OS if we go some number of GCs
         // without using them.
@@ -123,6 +118,16 @@ inline bool tryGetFastMemory(VM& vm, void*& memory, size_t& mappedCapacity, Memo
         return false;
     };
 
+    // We might GC here so we should be holding the API lock.
+    // FIXME: We should be able to syncronously trigger the GC from another thread.
+    ASSERT(vm.currentThreadIsHoldingAPILock());
+    if (UNLIKELY(!fastMemoryEnabled()))
+        goto fail;
+
+    // We need to be sure we have a stub prior to running code.
+    if (UNLIKELY(!vm.getCTIStub(throwExceptionFromWasmThunkGenerator).size()))
+        goto fail;
+
     ASSERT(allocatedFastMemories <= maxFastMemories);
     if (dequeFastMemory())
         return true;
@@ -131,7 +136,9 @@ inline bool tryGetFastMemory(VM& vm, void*& memory, size_t& mappedCapacity, Memo
     if (allocatedFastMemories == maxFastMemories) {
         // There is a reasonable chance that another module has died but has not been collected yet. Don't lose hope yet!
         vm.heap.collectAllGarbage();
-        return dequeFastMemory();
+        if (dequeFastMemory())
+            return true;
+        goto fail;
     }
 
     if (mmapBytes(fastMemoryMappedBytes, memory)) {
@@ -142,7 +149,16 @@ inline bool tryGetFastMemory(VM& vm, void*& memory, size_t& mappedCapacity, Memo
         auto result = activeFastMemories(locker).add(memory);
         ASSERT_UNUSED(result, result.isNewEntry);
     }
-    return memory;
+
+    if (memory)
+        return true;
+    goto fail;
+
+fail:
+    if (UNLIKELY(Options::crashIfWebAssemblyCantFastMemory()))
+        webAssemblyCouldntGetFastMemory();
+
+    return false;
 }
 
 inline void releaseFastMemory(void*& memory, size_t writableSize, size_t mappedCapacity, MemoryMode mode)