2016-04-25 Geoffrey Garen <ggaren@apple.com>
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Apr 2016 18:20:58 +0000 (18:20 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Apr 2016 18:20:58 +0000 (18:20 +0000)
        bmalloc: vm allocations should plant guard pages
        https://bugs.webkit.org/show_bug.cgi?id=156937

        Rolling back in r199936 with a fix for the memory regression.

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

Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/Object.h
Source/bmalloc/bmalloc/VMAllocate.h
Source/bmalloc/bmalloc/VMHeap.cpp

index 484da45..333c994 100644 (file)
@@ -1,3 +1,10 @@
+2016-04-25  Geoffrey Garen  <ggaren@apple.com>
+
+        bmalloc: vm allocations should plant guard pages
+        https://bugs.webkit.org/show_bug.cgi?id=156937
+
+        Rolling back in r199936 with a fix for the memory regression.
+
 2016-04-23  Gavin Barraclough  <barraclough@apple.com>
 
         bmalloc: vm allocations should plant guard pages
index 89650c3..c092a7c 100644 (file)
@@ -52,6 +52,7 @@ public:
     SmallPage* page();
     
     Object operator+(size_t);
+    Object operator-(size_t);
     bool operator<=(const Object&);
 
 private:
@@ -64,6 +65,11 @@ inline Object Object::operator+(size_t offset)
     return Object(m_chunk, m_offset + offset);
 }
 
+inline Object Object::operator-(size_t offset)
+{
+    return Object(m_chunk, m_offset - offset);
+}
+
 inline bool Object::operator<=(const Object& other)
 {
     BASSERT(m_chunk == other.m_chunk);
index b0ae33a..1b79f3b 100644 (file)
@@ -137,6 +137,12 @@ inline void vmDeallocate(void* p, size_t vmSize)
     munmap(p, vmSize);
 }
 
+inline void vmRevokePermissions(void* p, size_t vmSize)
+{
+    vmValidate(p, vmSize);
+    mprotect(p, vmSize, PROT_NONE);
+}
+
 // Allocates vmSize bytes at a specified power-of-two alignment.
 // Use this function to create maskable memory regions.
 
index 13dfeaf..b1d1cae 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace bmalloc {
 
-XLargeRange VMHeap::tryAllocateLargeChunk(std::lock_guard<StaticMutex>& lock, size_t alignment, size_t size)
+XLargeRange VMHeap::tryAllocateLargeChunk(std::lock_guard<StaticMutex>&, size_t alignment, size_t size)
 {
     // We allocate VM in aligned multiples to increase the chances that
     // the OS will provide contiguous ranges that we can merge.
@@ -47,7 +47,7 @@ XLargeRange VMHeap::tryAllocateLargeChunk(std::lock_guard<StaticMutex>& lock, si
     if (!memory)
         return XLargeRange();
 
-    Chunk* chunk = new (memory) Chunk(lock);
+    Chunk* chunk = static_cast<Chunk*>(memory);
     
 #if BOS(DARWIN)
     m_zone.addChunk(chunk);
@@ -58,13 +58,6 @@ XLargeRange VMHeap::tryAllocateLargeChunk(std::lock_guard<StaticMutex>& lock, si
 
 void VMHeap::allocateSmallChunk(std::lock_guard<StaticMutex>& lock, size_t pageClass)
 {
-    Chunk* chunk =
-        new (vmAllocate(chunkSize, chunkSize)) Chunk(lock);
-
-#if BOS(DARWIN)
-    m_zone.addChunk(chunk);
-#endif
-
     size_t pageSize = bmalloc::pageSize(pageClass);
     size_t smallPageCount = pageSize / smallPageSize;
 
@@ -72,12 +65,28 @@ void VMHeap::allocateSmallChunk(std::lock_guard<StaticMutex>& lock, size_t pageC
     // aligned allocation requests at equal and smaller powers of two.
     size_t metadataSize = divideRoundingUp(sizeof(Chunk), pageSize) * pageSize;
 
+    void* memory = vmAllocate(chunkSize, chunkSize);
+    Chunk* chunk = static_cast<Chunk*>(memory);
+
     Object begin(chunk, metadataSize);
     Object end(chunk, chunkSize);
 
+    // Establish guard pages before writing to Chunk memory to work around
+    // an edge case in the Darwin VM system (<rdar://problem/25910098>).
+    vmRevokePermissions(begin.begin(), pageSize);
+    vmRevokePermissions(end.begin() - pageSize, pageSize);
+
+    begin = begin + pageSize;
+    end = end - pageSize;
+
+    new (chunk) Chunk(lock);
+
+#if BOS(DARWIN)
+    m_zone.addChunk(chunk);
+#endif
+
     for (Object it = begin; it + pageSize <= end; it = it + pageSize) {
         SmallPage* page = it.page();
-        new (page) SmallPage;
 
         for (size_t i = 0; i < smallPageCount; ++i)
             page[i].setSlide(i);