[bmalloc] Each IsoPage gets 1MB VA because VMHeap::tryAllocateLargeChunk rounds up
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Jul 2019 02:43:11 +0000 (02:43 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Jul 2019 02:43:11 +0000 (02:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200024

Reviewed by Saam Barati.

Source/bmalloc:

When we allocate IsoHeap's page, we reused VMHeap::tryAllocateLargeChunk. However, this function is originally designed
to be used for Large allocation in bmalloc (e.g. allocating Chunk in bmalloc). As a result, this function rounds up the
requested size with 1MB (bmalloc::chunkSize). As a result, all IsoHeap's 16KB page gets 1MB VA while it just uses 16KB of
the allocated region. This leads to VA exhaustion since IsoHeap now uses 64x VA than we expected!

This patch fixes the above VA exhaustion issue by allocating a page by using tryVMAllocate. When allocating a page, we start
using a VM tag for IsoHeap. We discussed at e-mail and we decided reusing a VM tag previously assigned to CLoop Stack since
this is less profitable. Since this tag is not Malloc-related tag, Leaks tool can scan memory region conservatively without
registering allocated region into Zone, which was previously done in VMHeap and that's why we reused VMHeap for IsoHeap.

* bmalloc/BVMTags.h:
* bmalloc/IsoPage.cpp:
(bmalloc::IsoPageBase::allocatePageMemory):
* bmalloc/IsoTLS.cpp:
(bmalloc::IsoTLS::ensureEntries):
* bmalloc/VMAllocate.h:
(bmalloc::vmAllocate):

Source/JavaScriptCore:

Discussed and we decided to use this VM tag for IsoHeap instead of CLoop stack.

* interpreter/CLoopStack.cpp:
(JSC::CLoopStack::CLoopStack):

Source/WebCore:

Changed how we interpret VM tags. Add IsoHeap VM tag support, and rename WebAssembly tag
to Gigacage tag.

* page/ResourceUsageData.h:
* page/ResourceUsageOverlay.h:
* page/cocoa/ResourceUsageOverlayCocoa.mm:
(WebCore::HistoricResourceUsageData::HistoricResourceUsageData):
* page/cocoa/ResourceUsageThreadCocoa.mm:
(WebCore::displayNameForVMTag):
(WebCore::categoryForVMTag):

Source/WTF:

Start using a VM tag for IsoHeap instead of CLoop Stack.

* wtf/OSAllocator.h:
* wtf/VMTags.h:

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

15 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/interpreter/CLoopStack.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/OSAllocator.h
Source/WTF/wtf/VMTags.h
Source/WebCore/ChangeLog
Source/WebCore/page/ResourceUsageData.h
Source/WebCore/page/ResourceUsageOverlay.h
Source/WebCore/page/cocoa/ResourceUsageOverlayCocoa.mm
Source/WebCore/page/cocoa/ResourceUsageThreadCocoa.mm
Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/BVMTags.h
Source/bmalloc/bmalloc/IsoPage.cpp
Source/bmalloc/bmalloc/IsoTLS.cpp
Source/bmalloc/bmalloc/VMAllocate.h

index bb41dfa..731bde7 100644 (file)
@@ -1,3 +1,15 @@
+2019-07-22  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [bmalloc] Each IsoPage gets 1MB VA because VMHeap::tryAllocateLargeChunk rounds up
+        https://bugs.webkit.org/show_bug.cgi?id=200024
+
+        Reviewed by Saam Barati.
+
+        Discussed and we decided to use this VM tag for IsoHeap instead of CLoop stack.
+
+        * interpreter/CLoopStack.cpp:
+        (JSC::CLoopStack::CLoopStack):
+
 2019-07-22  Saam Barati  <sbarati@apple.com>
 
         Turn off Wasm fast memory on iOS
index 52cc74a..3c93ab8 100644 (file)
@@ -59,7 +59,7 @@ CLoopStack::CLoopStack(VM& vm)
     capacity = WTF::roundUpToMultipleOf(pageSize(), capacity);
     ASSERT(capacity && isPageAligned(capacity));
 
-    m_reservation = PageReservation::reserve(WTF::roundUpToMultipleOf(commitSize(), capacity), OSAllocator::JSVMStackPages);
+    m_reservation = PageReservation::reserve(WTF::roundUpToMultipleOf(commitSize(), capacity), OSAllocator::UnknownUsage);
 
     auto* bottomOfStack = highAddress();
     setCLoopStackLimit(bottomOfStack);
index 9110814..151d586 100644 (file)
@@ -1,3 +1,15 @@
+2019-07-22  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [bmalloc] Each IsoPage gets 1MB VA because VMHeap::tryAllocateLargeChunk rounds up
+        https://bugs.webkit.org/show_bug.cgi?id=200024
+
+        Reviewed by Saam Barati.
+
+        Start using a VM tag for IsoHeap instead of CLoop Stack.
+
+        * wtf/OSAllocator.h:
+        * wtf/VMTags.h:
+
 2019-07-20  Chris Dumez  <cdumez@apple.com>
 
         Speed up HashTable decoding by reserving capacity and avoiding rehashing
index fe58e4e..4f42ece 100644 (file)
@@ -35,7 +35,6 @@ public:
     enum Usage {
         UnknownUsage = -1,
         FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY,
-        JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY,
         JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY,
     };
 
index 14e021f..3c6c92c 100644 (file)
@@ -30,7 +30,7 @@
 #define VM_TAG_FOR_TCMALLOC_MEMORY -1
 #define VM_TAG_FOR_WEBASSEMBLY_MEMORY -1
 #define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
-#define VM_TAG_FOR_REGISTERFILE_MEMORY -1
+#define VM_TAG_FOR_ISOHEAP_MEMORY -1
 
 #else
 
index 4e14202..df318b5 100644 (file)
@@ -1,3 +1,21 @@
+2019-07-22  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [bmalloc] Each IsoPage gets 1MB VA because VMHeap::tryAllocateLargeChunk rounds up
+        https://bugs.webkit.org/show_bug.cgi?id=200024
+
+        Reviewed by Saam Barati.
+
+        Changed how we interpret VM tags. Add IsoHeap VM tag support, and rename WebAssembly tag
+        to Gigacage tag.
+
+        * page/ResourceUsageData.h:
+        * page/ResourceUsageOverlay.h:
+        * page/cocoa/ResourceUsageOverlayCocoa.mm:
+        (WebCore::HistoricResourceUsageData::HistoricResourceUsageData):
+        * page/cocoa/ResourceUsageThreadCocoa.mm:
+        (WebCore::displayNameForVMTag):
+        (WebCore::categoryForVMTag):
+
 2019-07-22  Youenn Fablet  <youenn@apple.com>
 
         Fix inspector override conversion in InspectorPageAgent::overrideSetting
index 9708e61..6c501b7 100644 (file)
@@ -39,12 +39,13 @@ namespace WebCore {
     v(bmalloc, 0, false) \
     v(LibcMalloc, 1, false) \
     v(JSJIT, 2, false) \
-    v(WebAssembly, 3, false) \
+    v(Gigacage, 3, false) \
     v(Images, 4, false) \
     v(GCHeap, 5, true) \
     v(GCOwned, 6, true) \
     v(Other, 7, false) \
     v(Layers, 8, false) \
+    v(IsoHeap, 9, false) \
 
 namespace MemoryCategory {
 #define WEBCORE_DEFINE_MEMORY_CATEGORY(name, id, subcategory) static constexpr unsigned name = id;
index 780b6aa..3e1f054 100644 (file)
@@ -58,7 +58,7 @@ public:
 #endif
 
     static const int normalWidth = 570;
-    static const int normalHeight = 160;
+    static const int normalHeight = 180;
 
 private:
     void willMoveToPage(PageOverlay&, Page*) override { }
index 0c8d293..55b4043 100644 (file)
@@ -163,11 +163,12 @@ HistoricResourceUsageData::HistoricResourceUsageData()
 {
     // VM tag categories.
     categories[MemoryCategory::JSJIT] = HistoricMemoryCategoryInfo(MemoryCategory::JSJIT, 0xFFFF60FF, "JS JIT");
-    categories[MemoryCategory::WebAssembly] = HistoricMemoryCategoryInfo(MemoryCategory::WebAssembly, 0xFF654FF0, "WebAssembly");
+    categories[MemoryCategory::Gigacage] = HistoricMemoryCategoryInfo(MemoryCategory::Gigacage, 0xFF654FF0, "Gigacage");
     categories[MemoryCategory::Images] = HistoricMemoryCategoryInfo(MemoryCategory::Images, 0xFFFFFF00, "Images");
     categories[MemoryCategory::Layers] = HistoricMemoryCategoryInfo(MemoryCategory::Layers, 0xFF00FFFF, "Layers");
     categories[MemoryCategory::LibcMalloc] = HistoricMemoryCategoryInfo(MemoryCategory::LibcMalloc, 0xFF00FF00, "libc malloc");
     categories[MemoryCategory::bmalloc] = HistoricMemoryCategoryInfo(MemoryCategory::bmalloc, 0xFFFF6060, "bmalloc");
+    categories[MemoryCategory::IsoHeap] = HistoricMemoryCategoryInfo(MemoryCategory::IsoHeap, 0xFF809F40, "IsoHeap");
     categories[MemoryCategory::Other] = HistoricMemoryCategoryInfo(MemoryCategory::Other, 0xFFC0FF00, "Other");
 
     // Sub categories (e.g breakdown of bmalloc tag.)
index 8646a0c..107a9c9 100644 (file)
@@ -83,8 +83,9 @@ const char* displayNameForVMTag(unsigned tag)
     case VM_MEMORY_LAYERKIT: return "CoreAnimation";
     case VM_MEMORY_IMAGEIO: return "ImageIO";
     case VM_MEMORY_CGIMAGE: return "CG image";
+    case VM_MEMORY_JAVASCRIPT_CORE: return "Gigacage";
     case VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR: return "JSC JIT";
-    case VM_MEMORY_JAVASCRIPT_CORE: return "WebAssembly";
+    case VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE: return "IsoHeap";
     case VM_MEMORY_MALLOC: return "malloc";
     case VM_MEMORY_MALLOC_HUGE: return "malloc (huge)";
     case VM_MEMORY_MALLOC_LARGE: return "malloc (large)";
@@ -151,10 +152,12 @@ static unsigned categoryForVMTag(unsigned tag)
     case VM_MEMORY_IMAGEIO:
     case VM_MEMORY_CGIMAGE:
         return MemoryCategory::Images;
+    case VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE:
+        return MemoryCategory::IsoHeap;
     case VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR:
         return MemoryCategory::JSJIT;
     case VM_MEMORY_JAVASCRIPT_CORE:
-        return MemoryCategory::WebAssembly;
+        return MemoryCategory::Gigacage;
     case VM_MEMORY_MALLOC:
     case VM_MEMORY_MALLOC_HUGE:
     case VM_MEMORY_MALLOC_LARGE:
index 6e5948a..e8502fa 100644 (file)
@@ -1,5 +1,30 @@
 2019-07-22  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [bmalloc] Each IsoPage gets 1MB VA because VMHeap::tryAllocateLargeChunk rounds up
+        https://bugs.webkit.org/show_bug.cgi?id=200024
+
+        Reviewed by Saam Barati.
+
+        When we allocate IsoHeap's page, we reused VMHeap::tryAllocateLargeChunk. However, this function is originally designed
+        to be used for Large allocation in bmalloc (e.g. allocating Chunk in bmalloc). As a result, this function rounds up the
+        requested size with 1MB (bmalloc::chunkSize). As a result, all IsoHeap's 16KB page gets 1MB VA while it just uses 16KB of
+        the allocated region. This leads to VA exhaustion since IsoHeap now uses 64x VA than we expected!
+
+        This patch fixes the above VA exhaustion issue by allocating a page by using tryVMAllocate. When allocating a page, we start
+        using a VM tag for IsoHeap. We discussed at e-mail and we decided reusing a VM tag previously assigned to CLoop Stack since
+        this is less profitable. Since this tag is not Malloc-related tag, Leaks tool can scan memory region conservatively without
+        registering allocated region into Zone, which was previously done in VMHeap and that's why we reused VMHeap for IsoHeap.
+
+        * bmalloc/BVMTags.h:
+        * bmalloc/IsoPage.cpp:
+        (bmalloc::IsoPageBase::allocatePageMemory):
+        * bmalloc/IsoTLS.cpp:
+        (bmalloc::IsoTLS::ensureEntries):
+        * bmalloc/VMAllocate.h:
+        (bmalloc::vmAllocate):
+
+2019-07-22  Yusuke Suzuki  <ysuzuki@apple.com>
+
         Unreviewed, follow-up fix for tls->size() access
         https://bugs.webkit.org/show_bug.cgi?id=200019
 
index 6574889..eb5e5f9 100644 (file)
@@ -46,9 +46,9 @@
 #endif // defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
 
 #if defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
-#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
+#define VM_TAG_FOR_ISOHEAP_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
 #else
-#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65)
+#define VM_TAG_FOR_ISOHEAP_MEMORY VM_MAKE_TAG(65)
 #endif // defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
 
 #if defined(VM_MEMORY_JAVASCRIPT_CORE)
@@ -62,7 +62,7 @@
 #define VM_TAG_FOR_TCMALLOC_MEMORY -1
 #define VM_TAG_FOR_GIGACAGE_MEMORY -1
 #define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
-#define VM_TAG_FOR_REGISTERFILE_MEMORY -1
+#define VM_TAG_FOR_ISOHEAP_MEMORY -1
 
 #endif // BOS(DARWIN)
 
@@ -71,7 +71,7 @@ namespace bmalloc {
 enum class VMTag {
     Unknown = -1,
     Malloc = VM_TAG_FOR_TCMALLOC_MEMORY,
-    JSVMStack = VM_TAG_FOR_REGISTERFILE_MEMORY,
+    IsoHeap = VM_TAG_FOR_ISOHEAP_MEMORY,
     JSJITCode = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY,
     JSGigacage = VM_TAG_FOR_GIGACAGE_MEMORY,
 };
index 2dac0f4..707c360 100644 (file)
@@ -32,7 +32,7 @@ namespace bmalloc {
 
 void* IsoPageBase::allocatePageMemory()
 {
-    return VMHeap::get()->tryAllocateLargeChunk(pageSize, pageSize).begin();
+    return tryVMAllocate(pageSize, pageSize, VMTag::IsoHeap);
 }
 
 } // namespace bmalloc
index 0dec3de..0104b3a 100644 (file)
@@ -100,7 +100,7 @@ IsoTLS* IsoTLS::ensureEntries(unsigned offset)
         size_t requiredSize = sizeForCapacity(requiredCapacity);
         size_t goodSize = roundUpToMultipleOf(vmPageSize(), requiredSize);
         size_t goodCapacity = capacityForSize(goodSize);
-        void* memory = vmAllocate(goodSize);
+        void* memory = vmAllocate(goodSize, VMTag::IsoHeap);
         IsoTLS* newTLS = new (memory) IsoTLS();
         newTLS->m_capacity = goodCapacity;
         if (tls) {
index e3976ca..17889bd 100644 (file)
@@ -130,9 +130,9 @@ inline void* tryVMAllocate(size_t vmSize, VMTag usage = VMTag::Malloc)
     return result;
 }
 
-inline void* vmAllocate(size_t vmSize)
+inline void* vmAllocate(size_t vmSize, VMTag usage = VMTag::Malloc)
 {
-    void* result = tryVMAllocate(vmSize);
+    void* result = tryVMAllocate(vmSize, usage);
     RELEASE_BASSERT(result);
     return result;
 }
@@ -189,9 +189,9 @@ inline void* tryVMAllocate(size_t vmAlignment, size_t vmSize, VMTag usage = VMTa
     return aligned;
 }
 
-inline void* vmAllocate(size_t vmAlignment, size_t vmSize)
+inline void* vmAllocate(size_t vmAlignment, size_t vmSize, VMTag usage = VMTag::Malloc)
 {
-    void* result = tryVMAllocate(vmAlignment, vmSize);
+    void* result = tryVMAllocate(vmAlignment, vmSize, usage);
     RELEASE_BASSERT(result);
     return result;
 }