- Revision
- 173675
- Author
- [email protected]
- Date
- 2014-09-16 15:37:15 -0700 (Tue, 16 Sep 2014)
Log Message
bmalloc: moved line caches from the deallocator to the allocator
https://bugs.webkit.org/show_bug.cgi?id=136868
Reviewed by Gavin Barraclough.
I did this mostly as a simplification, to make it easier to change the
allocation strategy.
No throughput change on MallocBench. Saves about 50kB.
Since the deallocator needs to lock the heap when freeing lines anyway,
there isn't much benefit to giving the deallocator a local cache of
deallocated lines.
We still give the allocator a local cache of lines because that does
reduce the frequency at which it needs to lock the heap in order to
acquire more lines.
* bmalloc/Allocator.cpp:
(bmalloc::Allocator::scavenge):
(bmalloc::Allocator::allocateSmallLine):
(bmalloc::Allocator::allocateMediumLine):
(bmalloc::Allocator::allocateMedium):
(bmalloc::Allocator::allocateSlowCase):
* bmalloc/Allocator.h:
* bmalloc/Deallocator.cpp:
(bmalloc::Deallocator::Deallocator):
(bmalloc::Deallocator::scavenge):
(bmalloc::Deallocator::processObjectLog):
(bmalloc::Deallocator::deallocateSmallLine): Deleted.
(bmalloc::Deallocator::allocateSmallLine): Deleted.
(bmalloc::Deallocator::deallocateMediumLine): Deleted.
(bmalloc::Deallocator::allocateMediumLine): Deleted.
* bmalloc/Deallocator.h:
* bmalloc/Sizes.h:
* bmalloc/VMAllocate.h: Took the opportunity to make the line cache size
exactly one page in size. That's about what we were shooting for anyway,
and it may make it easier to switch to per-page allocation in future.
Modified Paths
Diff
Modified: trunk/Source/bmalloc/ChangeLog (173674 => 173675)
--- trunk/Source/bmalloc/ChangeLog 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/ChangeLog 2014-09-16 22:37:15 UTC (rev 173675)
@@ -1,3 +1,45 @@
+2014-09-16 Geoffrey Garen <[email protected]>
+
+ bmalloc: moved line caches from the deallocator to the allocator
+ https://bugs.webkit.org/show_bug.cgi?id=136868
+
+ Reviewed by Gavin Barraclough.
+
+ I did this mostly as a simplification, to make it easier to change the
+ allocation strategy.
+
+ No throughput change on MallocBench. Saves about 50kB.
+
+ Since the deallocator needs to lock the heap when freeing lines anyway,
+ there isn't much benefit to giving the deallocator a local cache of
+ deallocated lines.
+
+ We still give the allocator a local cache of lines because that does
+ reduce the frequency at which it needs to lock the heap in order to
+ acquire more lines.
+
+ * bmalloc/Allocator.cpp:
+ (bmalloc::Allocator::scavenge):
+ (bmalloc::Allocator::allocateSmallLine):
+ (bmalloc::Allocator::allocateMediumLine):
+ (bmalloc::Allocator::allocateMedium):
+ (bmalloc::Allocator::allocateSlowCase):
+ * bmalloc/Allocator.h:
+ * bmalloc/Deallocator.cpp:
+ (bmalloc::Deallocator::Deallocator):
+ (bmalloc::Deallocator::scavenge):
+ (bmalloc::Deallocator::processObjectLog):
+ (bmalloc::Deallocator::deallocateSmallLine): Deleted.
+ (bmalloc::Deallocator::allocateSmallLine): Deleted.
+ (bmalloc::Deallocator::deallocateMediumLine): Deleted.
+ (bmalloc::Deallocator::allocateMediumLine): Deleted.
+ * bmalloc/Deallocator.h:
+
+ * bmalloc/Sizes.h:
+ * bmalloc/VMAllocate.h: Took the opportunity to make the line cache size
+ exactly one page in size. That's about what we were shooting for anyway,
+ and it may make it easier to switch to per-page allocation in future.
+
2014-09-15 Geoffrey Garen <[email protected]>
bmalloc: allocate small and medium objects using the same bump pointer class
Modified: trunk/Source/bmalloc/bmalloc/Allocator.cpp (173674 => 173675)
--- trunk/Source/bmalloc/bmalloc/Allocator.cpp 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/bmalloc/Allocator.cpp 2014-09-16 22:37:15 UTC (rev 173675)
@@ -63,8 +63,45 @@
m_deallocator.deallocate(allocator.allocate());
allocator.clear();
}
+
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ Heap* heap = PerProcess<Heap>::getFastCase();
+
+ for (auto& smallLineCache : m_smallLineCaches) {
+ while (smallLineCache.size())
+ heap->deallocateSmallLine(lock, smallLineCache.pop());
+ }
+ while (m_mediumLineCache.size())
+ heap->deallocateMediumLine(lock, m_mediumLineCache.pop());
}
+SmallLine* Allocator::allocateSmallLine(size_t smallSizeClass)
+{
+ SmallLineCache& smallLineCache = m_smallLineCaches[smallSizeClass];
+ if (!smallLineCache.size()) {
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ Heap* heap = PerProcess<Heap>::getFastCase();
+
+ while (smallLineCache.size() != smallLineCache.capacity())
+ smallLineCache.push(heap->allocateSmallLine(lock, smallSizeClass));
+ }
+
+ return smallLineCache.pop();
+}
+
+MediumLine* Allocator::allocateMediumLine()
+{
+ if (!m_mediumLineCache.size()) {
+ std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ Heap* heap = PerProcess<Heap>::getFastCase();
+
+ while (m_mediumLineCache.size() != m_mediumLineCache.capacity())
+ m_mediumLineCache.push(heap->allocateMediumLine(lock));
+ }
+
+ return m_mediumLineCache.pop();
+}
+
void* Allocator::allocateLarge(size_t size)
{
size = roundUpToMultipleOf<largeAlignment>(size);
@@ -84,7 +121,7 @@
BumpAllocator& allocator = m_mediumAllocators[mediumSizeClassFor(size)];
if (!allocator.canAllocate())
- allocator.refill(m_deallocator.allocateMediumLine());
+ allocator.refill(allocateMediumLine());
return allocator.allocate();
}
@@ -97,7 +134,7 @@
if (size <= smallMax) {
size_t smallSizeClass = smallSizeClassFor(size);
BumpAllocator& allocator = m_smallAllocators[smallSizeClass];
- allocator.refill(m_deallocator.allocateSmallLine(smallSizeClass));
+ allocator.refill(allocateSmallLine(smallSizeClass));
return allocator.allocate();
}
Modified: trunk/Source/bmalloc/bmalloc/Allocator.h (173674 => 173675)
--- trunk/Source/bmalloc/bmalloc/Allocator.h 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/bmalloc/Allocator.h 2014-09-16 22:37:15 UTC (rev 173675)
@@ -51,16 +51,25 @@
void scavenge();
private:
+ typedef FixedVector<SmallLine*, smallLineCacheCapacity> SmallLineCache;
+ typedef FixedVector<MediumLine*, mediumLineCacheCapacity> MediumLineCache;
+
void* allocateFastCase(BumpAllocator&);
void* allocateMedium(size_t);
void* allocateLarge(size_t);
void* allocateXLarge(size_t);
+ SmallLine* allocateSmallLine(size_t smallSizeClass);
+ MediumLine* allocateMediumLine();
+
Deallocator& m_deallocator;
std::array<BumpAllocator, smallMax / alignment> m_smallAllocators;
std::array<BumpAllocator, mediumMax / alignment> m_mediumAllocators;
+
+ std::array<SmallLineCache, smallMax / alignment> m_smallLineCaches;
+ MediumLineCache m_mediumLineCache;
};
inline bool Allocator::allocateFastCase(size_t size, void*& object)
Modified: trunk/Source/bmalloc/bmalloc/Deallocator.cpp (173674 => 173675)
--- trunk/Source/bmalloc/bmalloc/Deallocator.cpp 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/bmalloc/Deallocator.cpp 2014-09-16 22:37:15 UTC (rev 173675)
@@ -39,9 +39,6 @@
namespace bmalloc {
Deallocator::Deallocator()
- : m_objectLog()
- , m_smallLineCaches()
- , m_mediumLineCache()
{
}
@@ -53,16 +50,6 @@
void Deallocator::scavenge()
{
processObjectLog();
-
- std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
- Heap* heap = PerProcess<Heap>::getFastCase();
-
- for (auto& smallLineCache : m_smallLineCaches) {
- while (smallLineCache.size())
- heap->deallocateSmallLine(lock, smallLineCache.pop());
- }
- while (m_mediumLineCache.size())
- heap->deallocateMediumLine(lock, m_mediumLineCache.pop());
}
void Deallocator::deallocateLarge(void* object)
@@ -80,19 +67,20 @@
void Deallocator::processObjectLog()
{
std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
+ Heap* heap = PerProcess<Heap>::getFastCase();
for (auto object : m_objectLog) {
if (isSmall(object)) {
SmallLine* line = SmallLine::get(object);
if (!line->deref(lock))
continue;
- deallocateSmallLine(lock, line);
+ heap->deallocateSmallLine(lock, line);
} else {
BASSERT(isSmallOrMedium(object));
MediumLine* line = MediumLine::get(object);
if (!line->deref(lock))
continue;
- deallocateMediumLine(lock, line);
+ heap->deallocateMediumLine(lock, line);
}
}
@@ -119,48 +107,4 @@
return deallocateXLarge(object);
}
-void Deallocator::deallocateSmallLine(std::lock_guard<StaticMutex>& lock, SmallLine* line)
-{
- SmallLineCache& smallLineCache = m_smallLineCaches[SmallPage::get(line)->smallSizeClass()];
- if (smallLineCache.size() == smallLineCache.capacity())
- return PerProcess<Heap>::getFastCase()->deallocateSmallLine(lock, line);
-
- smallLineCache.push(line);
-}
-
-SmallLine* Deallocator::allocateSmallLine(size_t smallSizeClass)
-{
- SmallLineCache& smallLineCache = m_smallLineCaches[smallSizeClass];
- if (!smallLineCache.size()) {
- std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
- Heap* heap = PerProcess<Heap>::getFastCase();
-
- while (smallLineCache.size() != smallLineCache.capacity())
- smallLineCache.push(heap->allocateSmallLine(lock, smallSizeClass));
- }
-
- return smallLineCache.pop();
-}
-
-void Deallocator::deallocateMediumLine(std::lock_guard<StaticMutex>& lock, MediumLine* line)
-{
- if (m_mediumLineCache.size() == m_mediumLineCache.capacity())
- return PerProcess<Heap>::getFastCase()->deallocateMediumLine(lock, line);
-
- m_mediumLineCache.push(line);
-}
-
-MediumLine* Deallocator::allocateMediumLine()
-{
- if (!m_mediumLineCache.size()) {
- std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex());
- Heap* heap = PerProcess<Heap>::getFastCase();
-
- while (m_mediumLineCache.size() != m_mediumLineCache.capacity())
- m_mediumLineCache.push(heap->allocateMediumLine(lock));
- }
-
- return m_mediumLineCache.pop();
-}
-
} // namespace bmalloc
Modified: trunk/Source/bmalloc/bmalloc/Deallocator.h (173674 => 173675)
--- trunk/Source/bmalloc/bmalloc/Deallocator.h 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/bmalloc/Deallocator.h 2014-09-16 22:37:15 UTC (rev 173675)
@@ -44,25 +44,14 @@
bool deallocateFastCase(void*);
void deallocateSlowCase(void*);
- void deallocateSmallLine(std::lock_guard<StaticMutex>&, SmallLine*);
- SmallLine* allocateSmallLine(size_t smallSizeClass);
-
- void deallocateMediumLine(std::lock_guard<StaticMutex>&, MediumLine*);
- MediumLine* allocateMediumLine();
-
void scavenge();
private:
- typedef FixedVector<SmallLine*, smallLineCacheCapacity> SmallLineCache;
- typedef FixedVector<MediumLine*, mediumLineCacheCapacity> MediumLineCache;
-
void deallocateLarge(void*);
void deallocateXLarge(void*);
void processObjectLog();
FixedVector<void*, deallocatorLogCapacity> m_objectLog;
- std::array<SmallLineCache, smallMax / alignment> m_smallLineCaches;
- MediumLineCache m_mediumLineCache;
};
inline bool Deallocator::deallocateFastCase(void* object)
Modified: trunk/Source/bmalloc/bmalloc/Sizes.h (173674 => 173675)
--- trunk/Source/bmalloc/bmalloc/Sizes.h 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/bmalloc/Sizes.h 2014-09-16 22:37:15 UTC (rev 173675)
@@ -27,6 +27,7 @@
#define Sizes_h
#include "Algorithm.h"
+#include "BPlatform.h"
#include <algorithm>
#include <cstdint>
#include <cstddef>
@@ -45,6 +46,13 @@
static const size_t alignment = 8;
static const size_t alignmentMask = alignment - 1ul;
+#if BPLATFORM(IOS)
+ static const size_t vmPageSize = 16 * kB;
+#else
+ static const size_t vmPageSize = 4 * kB;
+#endif
+ static const size_t vmPageMask = ~(vmPageSize - 1);
+
static const size_t superChunkSize = 32 * MB;
static const size_t smallMax = 256;
@@ -84,8 +92,8 @@
static const size_t deallocatorLogCapacity = 256;
- static const size_t smallLineCacheCapacity = 16;
- static const size_t mediumLineCacheCapacity = 8;
+ static const size_t smallLineCacheCapacity = vmPageSize / smallLineSize;
+ static const size_t mediumLineCacheCapacity = vmPageSize / mediumLineSize;
static const std::chrono::milliseconds scavengeSleepDuration = std::chrono::milliseconds(512);
Modified: trunk/Source/bmalloc/bmalloc/VMAllocate.h (173674 => 173675)
--- trunk/Source/bmalloc/bmalloc/VMAllocate.h 2014-09-16 22:36:41 UTC (rev 173674)
+++ trunk/Source/bmalloc/bmalloc/VMAllocate.h 2014-09-16 22:37:15 UTC (rev 173675)
@@ -27,7 +27,6 @@
#define VMAllocate_h
#include "BAssert.h"
-#include "BPlatform.h"
#include "Range.h"
#include "Sizes.h"
#include "Syscall.h"
@@ -40,14 +39,6 @@
#define BMALLOC_VM_TAG VM_MAKE_TAG(VM_MEMORY_TCMALLOC)
-#if BPLATFORM(IOS)
-static const size_t vmPageSize = 16 * kB;
-#else
-static const size_t vmPageSize = 4 * kB;
-#endif
-
-static const size_t vmPageMask = ~(vmPageSize - 1);
-
inline size_t vmSize(size_t size)
{
return roundUpToMultipleOf<vmPageSize>(size);