Title: [197070] releases/WebKitGTK/webkit-2.12/Source/bmalloc
Revision
197070
Author
carlo...@webkit.org
Date
2016-02-25 01:16:07 -0800 (Thu, 25 Feb 2016)

Log Message

Merge r196873 - bmalloc: Don't use a whole page for metadata
https://bugs.webkit.org/show_bug.cgi?id=154510

Reviewed by Andreas Kling.

(1) Don't round up metadata to a page boundary. This saves 1.5% dirty
memory on iOS and 0.2% on Mac. It also enables a future patch to allocate
smaller chunks without wasting memory.

(2) Initialize metadata lazily. This saves dirty memory when the program
allocates primarily small or large objects (but not both), leaving some
metadata uninitialized.

* bmalloc.xcodeproj/project.pbxproj: Medium objects are gone now.

* bmalloc/BumpAllocator.h:
(bmalloc::BumpAllocator::refill): Added an ASSERT to help debug a bug
I cause while working on this patch.

* bmalloc/Heap.cpp:
(bmalloc::Heap::allocateSmallBumpRanges): Ditto.

(bmalloc::Heap::splitAndAllocate):
(bmalloc::Heap::allocateLarge): Updated for interface change.

* bmalloc/LargeChunk.h: Changed the boundaryTagCount calculation to
a static_assert.

Don't round up to page boundary. (See above.)

(bmalloc::LargeChunk::LargeChunk): Moved code here from LargeChunk::init.
A constructor is a more natural / automatic way to do this initialization.

* bmalloc/LargeObject.h:
(bmalloc::LargeObject::init): Deleted. Moved to LargeChunk.

* bmalloc/Sizes.h: Chagned largeChunkMetadataSize to a simpler constant
because metadata size no longer varies by page size.

* bmalloc/SmallChunk.h:
(bmalloc::SmallChunk::begin):
(bmalloc::SmallChunk::end):
(bmalloc::SmallChunk::lines):
(bmalloc::SmallChunk::pages): Use std::array to make begin/end
calculations easier.

(bmalloc::SmallChunk::SmallChunk): Treat our metadata like a series
of allocated objects. We used to avoid trampling our metadata by
starting object memory at the next page. Now we share the first page
between metadata and objects, and we account for metadata explicitly.

* bmalloc/SuperChunk.h:
(bmalloc::SuperChunk::SuperChunk):
(bmalloc::SuperChunk::smallChunk):
(bmalloc::SuperChunk::largeChunk):
(bmalloc::SuperChunk::create): Deleted. Don't eagerly run the SmallChunk
and LargeChunk constructors. We'll run them lazily as needed.

* bmalloc/VMHeap.cpp:
(bmalloc::VMHeap::VMHeap):
(bmalloc::VMHeap::allocateSmallChunk):
(bmalloc::VMHeap::allocateLargeChunk):
(bmalloc::VMHeap::allocateSuperChunk):
(bmalloc::VMHeap::grow): Deleted. Track small and large chunks explicitly
so we can initialize them lazily.

* bmalloc/VMHeap.h:
(bmalloc::VMHeap::allocateSmallPage):
(bmalloc::VMHeap::allocateLargeObject): Specify whether we're allocating
a small or large chunk since we don't allocate both at once anymore.

Fixed compilation of bmalloc with GCC 4.8 after r196873.
https://bugs.webkit.org/show_bug.cgi?id=154534

Patch by Konstantin Tokarev <annu...@yandex.ru> on 2016-02-22
Reviewed by Mark Lam.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382.

* bmalloc/LargeChunk.h:
* bmalloc/SmallChunk.h:

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/ChangeLog (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/ChangeLog	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/ChangeLog	2016-02-25 09:16:07 UTC (rev 197070)
@@ -1,3 +1,88 @@
+2016-02-22  Konstantin Tokarev  <annu...@yandex.ru>
+
+        Fixed compilation of bmalloc with GCC 4.8 after r196873.
+        https://bugs.webkit.org/show_bug.cgi?id=154534
+
+        Reviewed by Mark Lam.
+
+        See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382.
+
+        * bmalloc/LargeChunk.h:
+        * bmalloc/SmallChunk.h:
+
+2016-02-21  Geoffrey Garen  <gga...@apple.com>
+
+        bmalloc: Don't use a whole page for metadata
+        https://bugs.webkit.org/show_bug.cgi?id=154510
+
+        Reviewed by Andreas Kling.
+
+        (1) Don't round up metadata to a page boundary. This saves 1.5% dirty
+        memory on iOS and 0.2% on Mac. It also enables a future patch to allocate
+        smaller chunks without wasting memory.
+
+        (2) Initialize metadata lazily. This saves dirty memory when the program
+        allocates primarily small or large objects (but not both), leaving some
+        metadata uninitialized.
+
+        * bmalloc.xcodeproj/project.pbxproj: Medium objects are gone now.
+
+        * bmalloc/BumpAllocator.h:
+        (bmalloc::BumpAllocator::refill): Added an ASSERT to help debug a bug
+        I cause while working on this patch.
+
+        * bmalloc/Heap.cpp:
+        (bmalloc::Heap::allocateSmallBumpRanges): Ditto.
+
+        (bmalloc::Heap::splitAndAllocate):
+        (bmalloc::Heap::allocateLarge): Updated for interface change.
+
+        * bmalloc/LargeChunk.h: Changed the boundaryTagCount calculation to
+        a static_assert.
+
+        Don't round up to page boundary. (See above.)
+
+        (bmalloc::LargeChunk::LargeChunk): Moved code here from LargeChunk::init.
+        A constructor is a more natural / automatic way to do this initialization.
+
+        * bmalloc/LargeObject.h:
+        (bmalloc::LargeObject::init): Deleted. Moved to LargeChunk.
+
+        * bmalloc/Sizes.h: Chagned largeChunkMetadataSize to a simpler constant
+        because metadata size no longer varies by page size.
+
+        * bmalloc/SmallChunk.h:
+        (bmalloc::SmallChunk::begin):
+        (bmalloc::SmallChunk::end):
+        (bmalloc::SmallChunk::lines):
+        (bmalloc::SmallChunk::pages): Use std::array to make begin/end
+        calculations easier.
+
+        (bmalloc::SmallChunk::SmallChunk): Treat our metadata like a series
+        of allocated objects. We used to avoid trampling our metadata by
+        starting object memory at the next page. Now we share the first page
+        between metadata and objects, and we account for metadata explicitly.
+
+        * bmalloc/SuperChunk.h:
+        (bmalloc::SuperChunk::SuperChunk):
+        (bmalloc::SuperChunk::smallChunk):
+        (bmalloc::SuperChunk::largeChunk):
+        (bmalloc::SuperChunk::create): Deleted. Don't eagerly run the SmallChunk
+        and LargeChunk constructors. We'll run them lazily as needed.
+
+        * bmalloc/VMHeap.cpp:
+        (bmalloc::VMHeap::VMHeap):
+        (bmalloc::VMHeap::allocateSmallChunk):
+        (bmalloc::VMHeap::allocateLargeChunk):
+        (bmalloc::VMHeap::allocateSuperChunk):
+        (bmalloc::VMHeap::grow): Deleted. Track small and large chunks explicitly
+        so we can initialize them lazily.
+
+        * bmalloc/VMHeap.h:
+        (bmalloc::VMHeap::allocateSmallPage):
+        (bmalloc::VMHeap::allocateLargeObject): Specify whether we're allocating
+        a small or large chunk since we don't allocate both at once anymore.
+
 2016-02-20  Mark Lam  <mark....@apple.com>
 
         Use of inlined asm statements causes problems for -std=c99 builds.

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/BumpAllocator.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/BumpAllocator.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/BumpAllocator.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -99,6 +99,7 @@
     BASSERT(!canAllocate());
     m_ptr = bumpRange.begin;
     m_remaining = bumpRange.objectCount;
+    BASSERT(canAllocate());
 }
 
 inline void BumpAllocator::clear()

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/Heap.cpp (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/Heap.cpp	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/Heap.cpp	2016-02-25 09:16:07 UTC (rev 197070)
@@ -125,6 +125,7 @@
         // In a fragmented page, some free ranges might not fit in the cache.
         if (rangeCache.size() == rangeCache.capacity()) {
             m_smallPagesWithFreeLines[sizeClass].push(page);
+            BASSERT(allocator.canAllocate());
             return;
         }
 
@@ -153,6 +154,7 @@
             rangeCache.push({ begin, objectCount });
     }
 
+    BASSERT(allocator.canAllocate());
     page->setHasFreeLines(lock, false);
 }
 
@@ -304,7 +306,7 @@
     return largeObject;
 }
 
-void* Heap::allocateLarge(std::lock_guard<StaticMutex>&, size_t size)
+void* Heap::allocateLarge(std::lock_guard<StaticMutex>& lock, size_t size)
 {
     BASSERT(size <= largeMax);
     BASSERT(size >= largeMin);
@@ -312,7 +314,7 @@
 
     LargeObject largeObject = m_largeObjects.take(size);
     if (!largeObject)
-        largeObject = m_vmHeap.allocateLargeObject(size);
+        largeObject = m_vmHeap.allocateLargeObject(lock, size);
 
     if (largeObject.vmState().hasVirtual()) {
         m_isAllocatingPages = true;
@@ -326,7 +328,7 @@
     return largeObject.begin();
 }
 
-void* Heap::allocateLarge(std::lock_guard<StaticMutex>&, size_t alignment, size_t size, size_t unalignedSize)
+void* Heap::allocateLarge(std::lock_guard<StaticMutex>& lock, size_t alignment, size_t size, size_t unalignedSize)
 {
     BASSERT(size <= largeMax);
     BASSERT(size >= largeMin);
@@ -340,7 +342,7 @@
 
     LargeObject largeObject = m_largeObjects.take(alignment, size, unalignedSize);
     if (!largeObject)
-        largeObject = m_vmHeap.allocateLargeObject(alignment, size, unalignedSize);
+        largeObject = m_vmHeap.allocateLargeObject(lock, alignment, size, unalignedSize);
 
     if (largeObject.vmState().hasVirtual()) {
         m_isAllocatingPages = true;

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/LargeChunk.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/LargeChunk.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/LargeChunk.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -31,12 +31,13 @@
 #include "ObjectType.h"
 #include "Sizes.h"
 #include "VMAllocate.h"
+#include <array>
 
 namespace bmalloc {
 
 class LargeChunk {
 public:
-    static LargeChunk* create();
+    LargeChunk();
     static LargeChunk* get(void*);
 
     static BeginTag* beginTag(void*);
@@ -46,8 +47,8 @@
     char* end() { return reinterpret_cast<char*>(this) + largeChunkSize; }
 
 private:
-     // Round up to ensure 2 dummy boundary tags -- for the left and right sentinels.
-     static const size_t boundaryTagCount = max(2 * largeMin / sizeof(BoundaryTag), largeChunkSize / largeMin); 
+    static const size_t boundaryTagCount = largeChunkSize / largeMin;
+    static_assert(boundaryTagCount > 2, "LargeChunk must have space for two sentinel boundary tags");
 
     // Our metadata layout includes a left and right edge sentinel.
     // Metadata takes up enough space to leave at least the first two
@@ -63,24 +64,41 @@
     //
     // We use the X's for boundary tags and the O's for edge sentinels.
 
-    BoundaryTag m_boundaryTags[boundaryTagCount];
-
-    // Align to vmPageSize to avoid sharing physical pages with metadata.
-    // Otherwise, we'll confuse the scavenger into trying to scavenge metadata.
-    // FIXME: Below #ifdef workaround fix should be removed after all linux based ports bump
-    // own gcc version. See https://bugs.webkit.org/show_bug.cgi?id=140162#c87
-#if BPLATFORM(IOS)
-    char m_memory[] __attribute__((aligned(16384)));
-    static_assert(vmPageSize == 16384, "vmPageSize and alignment must be same");
-#else
-    char m_memory[] __attribute__((aligned(4096)));
-    static_assert(vmPageSize == 4096, "vmPageSize and alignment must be same");
-#endif
+    std::array<BoundaryTag, boundaryTagCount> m_boundaryTags;
+    char m_memory[] __attribute__((aligned(largeAlignment+0)));
 };
 
-static_assert(largeChunkMetadataSize == sizeof(LargeChunk), "'largeChunkMetadataSize' should be the same number as sizeof(LargeChunk) or our computation in Sizes.h for 'largeMax' is wrong");
-static_assert(largeChunkMetadataSize + largeMax <= largeChunkSize, "We will think we can accommodate larger objects than we can in reality");
+static_assert(largeChunkMetadataSize == sizeof(LargeChunk), "Our largeChunkMetadataSize math in Sizes.h is wrong");
+static_assert(largeChunkMetadataSize + largeMax == largeChunkSize, "largeMax is too small or too big");
 
+inline LargeChunk::LargeChunk()
+{
+    Range range(begin(), end() - begin());
+    BASSERT(range.size() == largeMax);
+
+    BeginTag* beginTag = LargeChunk::beginTag(range.begin());
+    beginTag->setRange(range);
+    beginTag->setFree(true);
+    beginTag->setVMState(VMState::Virtual);
+
+    EndTag* endTag = LargeChunk::endTag(range.begin(), range.size());
+    endTag->init(beginTag);
+
+    // Mark the left and right edges of our range as allocated. This naturally
+    // prevents merging logic from overflowing left (into metadata) or right
+    // (beyond our chunk), without requiring special-case checks.
+
+    EndTag* leftSentinel = beginTag->prev();
+    BASSERT(leftSentinel >= m_boundaryTags.begin());
+    BASSERT(leftSentinel < m_boundaryTags.end());
+    leftSentinel->initSentinel();
+
+    BeginTag* rightSentinel = endTag->next();
+    BASSERT(rightSentinel >= m_boundaryTags.begin());
+    BASSERT(rightSentinel < m_boundaryTags.end());
+    rightSentinel->initSentinel();
+}
+
 inline LargeChunk* LargeChunk::get(void* object)
 {
     BASSERT(!isSmall(object));

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/LargeObject.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/LargeObject.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/LargeObject.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -35,8 +35,6 @@
 
 class LargeObject {
 public:
-    static Range init(LargeChunk*);
-
     LargeObject();
     LargeObject(void*);
 
@@ -271,33 +269,6 @@
     }
 }
 
-inline Range LargeObject::init(LargeChunk* chunk)
-{
-    Range range(chunk->begin(), chunk->end() - chunk->begin());
-
-    BeginTag* beginTag = LargeChunk::beginTag(range.begin());
-    beginTag->setRange(range);
-    beginTag->setFree(true);
-    beginTag->setVMState(VMState::Virtual);
-
-    EndTag* endTag = LargeChunk::endTag(range.begin(), range.size());
-    endTag->init(beginTag);
-
-    // Mark the left and right edges of our chunk as allocated. This naturally
-    // prevents merging logic from overflowing beyond our chunk, without requiring
-    // special-case checks.
-    
-    EndTag* leftSentinel = beginTag->prev();
-    BASSERT(leftSentinel >= static_cast<void*>(chunk));
-    leftSentinel->initSentinel();
-
-    BeginTag* rightSentinel = endTag->next();
-    BASSERT(rightSentinel < static_cast<void*>(range.begin()));
-    rightSentinel->initSentinel();
-    
-    return range;
-}
-
 } // namespace bmalloc
 
 #endif // LargeObject_h

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/Sizes.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/Sizes.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/Sizes.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -56,28 +56,23 @@
     static const size_t superChunkSize = 2 * MB;
     static const size_t superChunkMask = ~(superChunkSize - 1);
 
-    static const size_t smallMax = 1024;
-    static const size_t smallLineSize = 256;
-    static const size_t smallLineCount = vmPageSize / smallLineSize;
-    static const size_t smallLineMask = ~(smallLineSize - 1ul);
-
     static const size_t smallChunkSize = superChunkSize / 2;
     static const size_t smallChunkOffset = superChunkSize / 2;
     static const size_t smallChunkMask = ~(smallChunkSize - 1ul);
 
+    static const size_t smallMax = 1024;
+    static const size_t smallLineSize = 256;
+    static const size_t smallLineCount = vmPageSize / smallLineSize;
+
     static const size_t largeChunkSize = superChunkSize / 2;
-#if BPLATFORM(IOS)
-    static const size_t largeChunkMetadataSize = 16 * kB;
-#else
-    static const size_t largeChunkMetadataSize = 4 * kB;
-#endif
     static const size_t largeChunkOffset = 0;
     static const size_t largeChunkMask = ~(largeChunkSize - 1ul);
 
     static const size_t largeAlignment = 64;
-    static const size_t largeMax = largeChunkSize - largeChunkMetadataSize;
     static const size_t largeMin = smallMax;
-    
+    static const size_t largeChunkMetadataSize = 4 * kB; // sizeof(LargeChunk)
+    static const size_t largeMax = largeChunkSize - largeChunkMetadataSize;
+
     static const size_t xLargeAlignment = vmPageSize;
     static const size_t xLargeMax = std::numeric_limits<size_t>::max() - xLargeAlignment; // Make sure that rounding up to xLargeAlignment does not overflow.
 

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/SmallChunk.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/SmallChunk.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/SmallChunk.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -35,37 +35,42 @@
 
 class SmallChunk {
 public:
+    SmallChunk(std::lock_guard<StaticMutex>&);
+
     static SmallChunk* get(void*);
 
     SmallPage* begin() { return SmallPage::get(SmallLine::get(m_memory)); }
-    SmallPage* end() { return &m_pages[pageCount]; }
+    SmallPage* end() { return m_pages.end(); }
     
-    SmallLine* lines() { return m_lines; }
-    SmallPage* pages() { return m_pages; }
-
+    SmallLine* lines() { return m_lines.begin(); }
+    SmallPage* pages() { return m_pages.begin(); }
+    
 private:
-    static_assert(!(vmPageSize % smallLineSize), "vmPageSize must be an even multiple of line size");
-    static_assert(!(smallChunkSize % smallLineSize), "chunk size must be an even multiple of line size");
+    std::array<SmallLine, smallChunkSize / smallLineSize> m_lines;
+    std::array<SmallPage, smallChunkSize / vmPageSize> m_pages;
+    char m_memory[] __attribute__((aligned(smallLineSize+0)));
+};
 
-    static const size_t lineCount = smallChunkSize / smallLineSize;
-    static const size_t pageCount = smallChunkSize / vmPageSize;
+static_assert(!(vmPageSize % smallLineSize), "vmPageSize must be an even multiple of line size");
+static_assert(!(smallChunkSize % smallLineSize), "chunk size must be an even multiple of line size");
+static_assert(
+    sizeof(SmallChunk) - vmPageSize % sizeof(SmallChunk) < vmPageSize - 2 * smallMax,
+        "the first page of object memory in a small chunk can't allocate smallMax");
 
-    SmallLine m_lines[lineCount];
-    SmallPage m_pages[pageCount];
+inline SmallChunk::SmallChunk(std::lock_guard<StaticMutex>& lock)
+{
+    // Track the memory used for metadata by allocating imaginary objects.
+    for (SmallLine* line = m_lines.begin(); line < SmallLine::get(m_memory); ++line) {
+        line->ref(lock, 1);
 
-    // Align to vmPageSize to avoid sharing physical pages with metadata.
-    // Otherwise, we'll confuse the scavenger into trying to scavenge metadata.
-    // FIXME: Below #ifdef workaround fix should be removed after all linux based ports bump
-    // own gcc version. See https://bugs.webkit.org/show_bug.cgi?id=140162#c87
-#if BPLATFORM(IOS)
-    char m_memory[] __attribute__((aligned(16384)));
-    static_assert(vmPageSize == 16384, "vmPageSize and alignment must be same");
-#else
-    char m_memory[] __attribute__((aligned(4096)));
-    static_assert(vmPageSize == 4096, "vmPageSize and alignment must be same");
-#endif
-};
+        SmallPage* page = SmallPage::get(line);
+        page->ref(lock);
+    }
 
+    for (SmallPage* page = begin(); page != end(); ++page)
+        page->setHasFreeLines(lock, true);
+}
+
 inline SmallChunk* SmallChunk::get(void* object)
 {
     BASSERT(isSmall(object));

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/SuperChunk.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/SuperChunk.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/SuperChunk.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -33,37 +33,27 @@
 
 class SuperChunk {
 public:
-    static SuperChunk* create();
-
-    SmallChunk* smallChunk();
-    LargeChunk* largeChunk();
-
-private:
     SuperChunk();
+
+    void* smallChunk();
+    void* largeChunk();
 };
 
-inline SuperChunk* SuperChunk::create()
-{
-    void* result = static_cast<char*>(vmAllocate(superChunkSize, superChunkSize));
-    return new (result) SuperChunk;
-}
-
 inline SuperChunk::SuperChunk()
 {
-    new (smallChunk()) SmallChunk;
-    new (largeChunk()) LargeChunk;
+    BASSERT(!test(this, ~superChunkMask));
+    BASSERT(!test(smallChunk(), ~smallChunkMask));
+    BASSERT(!test(largeChunk(), ~largeChunkMask));
 }
 
-inline SmallChunk* SuperChunk::smallChunk()
+inline void* SuperChunk::smallChunk()
 {
-    return reinterpret_cast<SmallChunk*>(
-        reinterpret_cast<char*>(this) + smallChunkOffset);
+    return reinterpret_cast<char*>(this) + smallChunkOffset;
 }
 
-inline LargeChunk* SuperChunk::largeChunk()
+inline void* SuperChunk::largeChunk()
 {
-    return reinterpret_cast<LargeChunk*>(
-        reinterpret_cast<char*>(this) + largeChunkOffset);
+    return reinterpret_cast<char*>(this) + largeChunkOffset;
 }
 
 } // namespace bmalloc

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/VMHeap.cpp (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/VMHeap.cpp	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/VMHeap.cpp	2016-02-25 09:16:07 UTC (rev 197070)
@@ -36,21 +36,37 @@
 {
 }
 
-void VMHeap::grow()
+void VMHeap::allocateSmallChunk(std::lock_guard<StaticMutex>& lock)
 {
-    SuperChunk* superChunk = SuperChunk::create();
-#if BOS(DARWIN)
-    m_zone.addSuperChunk(superChunk);
-#endif
+    if (!m_smallChunks.size())
+        allocateSuperChunk(lock);
 
-    SmallChunk* smallChunk = superChunk->smallChunk();
-    for (auto* it = smallChunk->begin(); it != smallChunk->end(); ++it)
+    // We initialize chunks lazily to avoid dirtying their metadata pages.
+    SmallChunk* smallChunk = new (m_smallChunks.pop()->smallChunk()) SmallChunk(lock);
+    for (auto* it = smallChunk->begin(); it < smallChunk->end(); ++it)
         m_smallPages.push(it);
+}
 
-    LargeChunk* largeChunk = superChunk->largeChunk();
-    LargeObject result(LargeObject::init(largeChunk).begin());
-    BASSERT(result.size() == largeMax);
-    m_largeObjects.insert(result);
+void VMHeap::allocateLargeChunk(std::lock_guard<StaticMutex>& lock)
+{
+    if (!m_largeChunks.size())
+        allocateSuperChunk(lock);
+
+    // We initialize chunks lazily to avoid dirtying their metadata pages.
+    LargeChunk* largeChunk = new (m_largeChunks.pop()->largeChunk()) LargeChunk;
+    LargeObject largeObject(largeChunk->begin());
+    m_largeObjects.insert(largeObject);
 }
 
+void VMHeap::allocateSuperChunk(std::lock_guard<StaticMutex>&)
+{
+    SuperChunk* superChunk =
+        new (vmAllocate(superChunkSize, superChunkSize)) SuperChunk;
+    m_smallChunks.push(superChunk);
+    m_largeChunks.push(superChunk);
+#if BOS(DARWIN)
+    m_zone.addSuperChunk(superChunk);
+#endif
+}
+
 } // namespace bmalloc

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/VMHeap.h (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/VMHeap.h	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc/VMHeap.h	2016-02-25 09:16:07 UTC (rev 197070)
@@ -51,17 +51,23 @@
     VMHeap();
 
     SmallPage* allocateSmallPage(std::lock_guard<StaticMutex>&);
-    LargeObject allocateLargeObject(size_t);
-    LargeObject allocateLargeObject(size_t, size_t, size_t);
+    LargeObject allocateLargeObject(std::lock_guard<StaticMutex>&, size_t);
+    LargeObject allocateLargeObject(std::lock_guard<StaticMutex>&, size_t, size_t, size_t);
 
     void deallocateSmallPage(std::unique_lock<StaticMutex>&, SmallPage*);
     void deallocateLargeObject(std::unique_lock<StaticMutex>&, LargeObject);
-
+    
 private:
-    void grow();
+    void allocateSmallChunk(std::lock_guard<StaticMutex>&);
+    void allocateLargeChunk(std::lock_guard<StaticMutex>&);
+    void allocateSuperChunk(std::lock_guard<StaticMutex>&);
 
     Vector<SmallPage*> m_smallPages;
     SegregatedFreeList m_largeObjects;
+
+    Vector<SuperChunk*> m_smallChunks;
+    Vector<SuperChunk*> m_largeChunks;
+
 #if BOS(DARWIN)
     Zone m_zone;
 #endif
@@ -70,19 +76,18 @@
 inline SmallPage* VMHeap::allocateSmallPage(std::lock_guard<StaticMutex>& lock)
 {
     if (!m_smallPages.size())
-        grow();
+        allocateSmallChunk(lock);
 
     SmallPage* page = m_smallPages.pop();
-    page->setHasFreeLines(lock, true);
     vmAllocatePhysicalPages(page->begin()->begin(), vmPageSize);
     return page;
 }
 
-inline LargeObject VMHeap::allocateLargeObject(size_t size)
+inline LargeObject VMHeap::allocateLargeObject(std::lock_guard<StaticMutex>& lock, size_t size)
 {
     LargeObject largeObject = m_largeObjects.take(size);
     if (!largeObject) {
-        grow();
+        allocateLargeChunk(lock);
         largeObject = m_largeObjects.take(size);
         BASSERT(largeObject);
     }
@@ -90,11 +95,11 @@
     return largeObject;
 }
 
-inline LargeObject VMHeap::allocateLargeObject(size_t alignment, size_t size, size_t unalignedSize)
+inline LargeObject VMHeap::allocateLargeObject(std::lock_guard<StaticMutex>& lock, size_t alignment, size_t size, size_t unalignedSize)
 {
     LargeObject largeObject = m_largeObjects.take(alignment, size, unalignedSize);
     if (!largeObject) {
-        grow();
+        allocateLargeChunk(lock);
         largeObject = m_largeObjects.take(alignment, size, unalignedSize);
         BASSERT(largeObject);
     }

Modified: releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj (197069 => 197070)


--- releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj	2016-02-25 09:15:42 UTC (rev 197069)
+++ releases/WebKitGTK/webkit-2.12/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj	2016-02-25 09:16:07 UTC (rev 197070)
@@ -165,7 +165,7 @@
 				1448C2FD18F3752B00502839 /* api */,
 				14D9DB4D17F2865C00EAAB79 /* cache */,
 				147AAA9C18CE6010002201E4 /* heap: large */,
-				147AAA9A18CE5FD3002201E4 /* heap: small | medium */,
+				147AAA9A18CE5FD3002201E4 /* heap: small */,
 				14D9DB4E17F2866E00EAAB79 /* heap */,
 				14D9DB4F17F2868900EAAB79 /* stdlib */,
 				14B650C418F39F4800751968 /* Configurations */,
@@ -182,14 +182,14 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
-		147AAA9A18CE5FD3002201E4 /* heap: small | medium */ = {
+		147AAA9A18CE5FD3002201E4 /* heap: small */ = {
 			isa = PBXGroup;
 			children = (
 				147AAA8C18CD36A7002201E4 /* SmallChunk.h */,
 				1452478618BC757C00F80098 /* SmallLine.h */,
 				143E29ED18CAE90500FE8A0F /* SmallPage.h */,
 			);
-			name = "heap: small | medium";
+			name = "heap: small";
 			sourceTree = "<group>";
 		};
 		147AAA9C18CE6010002201E4 /* heap: large */ = {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to