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.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173675
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-09-16 Geoffrey Garen <ggaren@apple.com>
+
+ 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 <ggaren@apple.com>
bmalloc: allocate small and medium objects using the same bump pointer class
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)
BumpAllocator& allocator = m_mediumAllocators[mediumSizeClassFor(size)];
if (!allocator.canAllocate())
- allocator.refill(m_deallocator.allocateMediumLine());
+ allocator.refill(allocateMediumLine());
return allocator.allocate();
}
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();
}
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)
namespace bmalloc {
Deallocator::Deallocator()
- : m_objectLog()
- , m_smallLineCaches()
- , m_mediumLineCache()
{
}
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)
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);
}
}
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
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)
#define Sizes_h
#include "Algorithm.h"
+#include "BPlatform.h"
#include <algorithm>
#include <cstdint>
#include <cstddef>
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;
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);
#define VMAllocate_h
#include "BAssert.h"
-#include "BPlatform.h"
#include "Range.h"
#include "Sizes.h"
#include "Syscall.h"
#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);