Title: [263316] trunk
Revision
263316
Author
ysuz...@apple.com
Date
2020-06-19 21:20:52 -0700 (Fri, 19 Jun 2020)

Log Message

[JSC] Check Gigacage usage before launching VM
https://bugs.webkit.org/show_bug.cgi?id=213410

Reviewed by Mark Lam.

JSTests:

* stress/exhaust-gigacage-and-allocate-vm.js: Added.
(foo):

Source/bmalloc:

Add Gigacage::footprint and Gigacage::size functions to expose usage to API users.
Rename Gigacage::size to Gigacage::maxSize.

* bmalloc/Gigacage.cpp:
(Gigacage::ensureGigacage):
(Gigacage::size):
(Gigacage::footprint):
* bmalloc/Gigacage.h:
(Gigacage::maxSize):
(Gigacage::alignment):
(Gigacage::mask):
(Gigacage::size):
(Gigacage::footprint):
* bmalloc/Heap.cpp:
(bmalloc::Heap::gigacageSize):
* bmalloc/Heap.h:

Source/_javascript_Core:

Since VM allocates JSBigInt from Gigacage, it is possible that VM creation fails when Gigacage is exhausted.
As a work-around for internal testing, we insert ad-hoc Gigacage usage check before launching a new agent.
If 80% of Gigacage is used, we fail to launch a new VM gracefully.

* assembler/testmasm.cpp:
(JSC::testCagePreservesPACFailureBit):
* jsc.cpp:
(functionDollarAgentStart):

Source/WTF:

* wtf/Gigacage.h:
(Gigacage::footprint):
(Gigacage::maxSize):
(Gigacage::size):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (263315 => 263316)


--- trunk/JSTests/ChangeLog	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/JSTests/ChangeLog	2020-06-20 04:20:52 UTC (rev 263316)
@@ -1,5 +1,15 @@
 2020-06-19  Yusuke Suzuki  <ysuz...@apple.com>
 
+        [JSC] Check Gigacage usage before launching VM
+        https://bugs.webkit.org/show_bug.cgi?id=213410
+
+        Reviewed by Mark Lam.
+
+        * stress/exhaust-gigacage-and-allocate-vm.js: Added.
+        (foo):
+
+2020-06-19  Yusuke Suzuki  <ysuz...@apple.com>
+
         [JSC] Attempt to reduce timeout failures on Apple Watch Series 3
         https://bugs.webkit.org/show_bug.cgi?id=213419
 

Added: trunk/JSTests/stress/exhaust-gigacage-and-allocate-vm.js (0 => 263316)


--- trunk/JSTests/stress/exhaust-gigacage-and-allocate-vm.js	                        (rev 0)
+++ trunk/JSTests/stress/exhaust-gigacage-and-allocate-vm.js	2020-06-20 04:20:52 UTC (rev 263316)
@@ -0,0 +1,22 @@
+//@ skip if $memoryLimited
+//@ runDefault
+
+// Should not crash with this test.
+
+const a = [0];
+a.__proto__ = {};
+Object.defineProperty(a, 0, { get: foo });
+Object.defineProperty(a, 80000000, {});
+function foo() {
+    new Uint8Array(a);
+}
+new Promise(foo);
+try {
+    for (let i = 0; i < 10000000; i++)
+        new ArrayBuffer(1000);
+} catch {}
+
+try {
+    $.agent.start()
+} catch {
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (263315 => 263316)


--- trunk/Source/_javascript_Core/ChangeLog	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-06-20 04:20:52 UTC (rev 263316)
@@ -1,3 +1,19 @@
+2020-06-19  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Check Gigacage usage before launching VM
+        https://bugs.webkit.org/show_bug.cgi?id=213410
+
+        Reviewed by Mark Lam.
+
+        Since VM allocates JSBigInt from Gigacage, it is possible that VM creation fails when Gigacage is exhausted.
+        As a work-around for internal testing, we insert ad-hoc Gigacage usage check before launching a new agent.
+        If 80% of Gigacage is used, we fail to launch a new VM gracefully.
+
+        * assembler/testmasm.cpp:
+        (JSC::testCagePreservesPACFailureBit):
+        * jsc.cpp:
+        (functionDollarAgentStart):
+
 2020-06-19  James Darpinian  <jdarpin...@chromium.org>
 
         Typed array constructor behaves differently when length is not passed or when undefined is passed

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (263315 => 263316)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2020-06-20 04:20:52 UTC (rev 263316)
@@ -2412,8 +2412,8 @@
 
     void* ptr = Gigacage::tryMalloc(Gigacage::Primitive, 1);
     void* taggedPtr = tagArrayPtr(ptr, 1);
-    RELEASE_ASSERT(hasOneBitSet(Gigacage::size(Gigacage::Primitive) << 2));
-    void* notCagedPtr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + (Gigacage::size(Gigacage::Primitive) << 2));
+    RELEASE_ASSERT(hasOneBitSet(Gigacage::maxSize(Gigacage::Primitive) << 2));
+    void* notCagedPtr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(ptr) + (Gigacage::maxSize(Gigacage::Primitive) << 2));
     CHECK_NOT_EQ(Gigacage::caged(Gigacage::Primitive, notCagedPtr), notCagedPtr);
     void* taggedNotCagedPtr = tagArrayPtr(notCagedPtr, 1);
 

Modified: trunk/Source/_javascript_Core/jsc.cpp (263315 => 263316)


--- trunk/Source/_javascript_Core/jsc.cpp	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/_javascript_Core/jsc.cpp	2020-06-20 04:20:52 UTC (rev 263316)
@@ -1879,6 +1879,17 @@
     Lock didStartLock;
     Condition didStartCondition;
     bool didStart = false;
+
+    auto isGigacageMemoryExhausted = [&](Gigacage::Kind kind) {
+        if (!Gigacage::isEnabled(kind))
+            return false;
+        if (Gigacage::footprint(kind) < Gigacage::size(kind) * 0.8)
+            return false;
+        return true;
+    };
+
+    if (isGigacageMemoryExhausted(Gigacage::JSValue) || isGigacageMemoryExhausted(Gigacage::Primitive))
+        return JSValue::encode(throwOutOfMemoryError(globalObject, scope, "Gigacage is exhausted"_s));
     
     Thread::create(
         "JSC Agent",

Modified: trunk/Source/WTF/ChangeLog (263315 => 263316)


--- trunk/Source/WTF/ChangeLog	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/WTF/ChangeLog	2020-06-20 04:20:52 UTC (rev 263316)
@@ -1,3 +1,15 @@
+2020-06-19  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Check Gigacage usage before launching VM
+        https://bugs.webkit.org/show_bug.cgi?id=213410
+
+        Reviewed by Mark Lam.
+
+        * wtf/Gigacage.h:
+        (Gigacage::footprint):
+        (Gigacage::maxSize):
+        (Gigacage::size):
+
 2020-06-19  Truitt Savell  <tsav...@apple.com>
 
         Unreviewed, reverting r263223.

Modified: trunk/Source/WTF/wtf/Gigacage.h (263315 => 263316)


--- trunk/Source/WTF/wtf/Gigacage.h	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/WTF/wtf/Gigacage.h	2020-06-20 04:20:52 UTC (rev 263316)
@@ -69,6 +69,9 @@
 ALWAYS_INLINE bool disablingPrimitiveGigacageIsForbidden() { return false; }
 ALWAYS_INLINE bool isEnabled(Kind) { return false; }
 ALWAYS_INLINE size_t mask(Kind) { return 0; }
+ALWAYS_INLINE size_t footprint(Kind) { return 0; }
+ALWAYS_INLINE size_t maxSize(Kind) { return 0; }
+ALWAYS_INLINE size_t size(Kind) { return 0; }
 
 template<typename T>
 inline T* caged(Kind, T* ptr) { return ptr; }

Modified: trunk/Source/bmalloc/ChangeLog (263315 => 263316)


--- trunk/Source/bmalloc/ChangeLog	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/bmalloc/ChangeLog	2020-06-20 04:20:52 UTC (rev 263316)
@@ -1,3 +1,27 @@
+2020-06-19  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Check Gigacage usage before launching VM
+        https://bugs.webkit.org/show_bug.cgi?id=213410
+
+        Reviewed by Mark Lam.
+
+        Add Gigacage::footprint and Gigacage::size functions to expose usage to API users.
+        Rename Gigacage::size to Gigacage::maxSize.
+
+        * bmalloc/Gigacage.cpp:
+        (Gigacage::ensureGigacage):
+        (Gigacage::size):
+        (Gigacage::footprint):
+        * bmalloc/Gigacage.h:
+        (Gigacage::maxSize):
+        (Gigacage::alignment):
+        (Gigacage::mask):
+        (Gigacage::size):
+        (Gigacage::footprint):
+        * bmalloc/Heap.cpp:
+        (bmalloc::Heap::gigacageSize):
+        * bmalloc/Heap.h:
+
 2020-06-04  Tim Horton  <timothy_hor...@apple.com>
 
         Work around broken system version macro

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.cpp (263315 => 263316)


--- trunk/Source/bmalloc/bmalloc/Gigacage.cpp	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.cpp	2020-06-20 04:20:52 UTC (rev 263316)
@@ -137,7 +137,7 @@
                 return roundUpToMultipleOf(alignment(kind), totalSize);
             };
             auto bump = [] (Kind kind, size_t totalSize) -> size_t {
-                return totalSize + size(kind);
+                return totalSize + maxSize(kind);
             };
             
             size_t totalSize = 0;
@@ -280,6 +280,16 @@
     return g_gigacageConfig.shouldBeEnabled;
 }
 
+size_t size(Kind kind)
+{
+    return PerProcess<PerHeapKind<Heap>>::get()->at(heapKind(kind)).gigacageSize();
+}
+
+size_t footprint(Kind kind)
+{
+    return PerProcess<PerHeapKind<Heap>>::get()->at(heapKind(kind)).footprint();
+}
+
 } // namespace Gigacage
 
 #endif // GIGACAGE_ENABLED

Modified: trunk/Source/bmalloc/bmalloc/Gigacage.h (263315 => 263316)


--- trunk/Source/bmalloc/bmalloc/Gigacage.h	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/bmalloc/bmalloc/Gigacage.h	2020-06-20 04:20:52 UTC (rev 263316)
@@ -137,7 +137,7 @@
     return &g_gigacageConfig.basePtrs[kind];
 }
 
-BINLINE size_t size(Kind kind)
+BINLINE size_t maxSize(Kind kind)
 {
     switch (kind) {
     case Primitive:
@@ -153,14 +153,17 @@
 
 BINLINE size_t alignment(Kind kind)
 {
-    return size(kind);
+    return maxSize(kind);
 }
 
 BINLINE size_t mask(Kind kind)
 {
-    return gigacageSizeToMask(size(kind));
+    return gigacageSizeToMask(maxSize(kind));
 }
 
+BEXPORT size_t size(Kind);
+BEXPORT size_t footprint(Kind);
+
 template<typename Func>
 void forEachKind(const Func& func)
 {
@@ -210,7 +213,9 @@
     static void* unreachable;
     return unreachable;
 }
-BINLINE size_t size(Kind) { BCRASH(); return 0; }
+BINLINE size_t maxSize(Kind) { BCRASH(); return 0; }
+BINLINE size_t size(Kind) { return 0; }
+BINLINE size_t footprint(Kind) { return 0; }
 BINLINE void ensureGigacage() { }
 BINLINE bool contains(const void*) { return false; }
 BINLINE bool disablingPrimitiveGigacageIsForbidden() { return false; }

Modified: trunk/Source/bmalloc/bmalloc/Heap.cpp (263315 => 263316)


--- trunk/Source/bmalloc/bmalloc/Heap.cpp	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/bmalloc/bmalloc/Heap.cpp	2020-06-20 04:20:52 UTC (rev 263316)
@@ -60,8 +60,10 @@
         RELEASE_BASSERT(gigacageBasePtr);
         uint64_t random[2];
         cryptoRandom(reinterpret_cast<unsigned char*>(random), sizeof(random));
-        size_t size = roundDownToMultipleOf(vmPageSize(), gigacageSize() - (random[0] % Gigacage::maximumCageSizeReductionForSlide));
-        ptrdiff_t offset = roundDownToMultipleOf(vmPageSize(), random[1] % (gigacageSize() - size));
+        size_t gigacageSize = Gigacage::maxSize(gigacageKind(kind));
+        size_t size = roundDownToMultipleOf(vmPageSize(), gigacageSize - (random[0] % Gigacage::maximumCageSizeReductionForSlide));
+        m_gigacageSize = size;
+        ptrdiff_t offset = roundDownToMultipleOf(vmPageSize(), random[1] % (gigacageSize - size));
         void* base = reinterpret_cast<unsigned char*>(gigacageBasePtr) + offset;
         m_largeFree.add(LargeRange(base, size, 0, 0));
     }
@@ -82,7 +84,7 @@
 
 size_t Heap::gigacageSize()
 {
-    return Gigacage::size(gigacageKind(m_kind));
+    return m_gigacageSize;
 }
 
 size_t Heap::freeableMemory(UniqueLockHolder&)

Modified: trunk/Source/bmalloc/bmalloc/Heap.h (263315 => 263316)


--- trunk/Source/bmalloc/bmalloc/Heap.h	2020-06-20 04:06:38 UTC (rev 263315)
+++ trunk/Source/bmalloc/bmalloc/Heap.h	2020-06-20 04:20:52 UTC (rev 263316)
@@ -84,6 +84,7 @@
 
     size_t freeableMemory(UniqueLockHolder&);
     size_t footprint();
+    size_t gigacageSize();
 
     void externalDecommit(void* ptr, size_t);
     void externalDecommit(UniqueLockHolder&, void* ptr, size_t);
@@ -107,7 +108,6 @@
     
     bool usingGigacage();
     void* gigacageBasePtr(); // May crash if !usingGigacage().
-    size_t gigacageSize();
 
     void allocateSmallBumpRangesByMetadata(UniqueLockHolder&,
         size_t sizeClass, BumpAllocator&, BumpRangeCache&, LineCache&, FailureAction);
@@ -140,6 +140,7 @@
 
     Scavenger* m_scavenger { nullptr };
 
+    size_t m_gigacageSize { 0 };
     size_t m_footprint { 0 };
     size_t m_freeableMemory { 0 };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to