Bug 2055507 - pt 8. Disable the chunk cache on Windows r=glandium

Differential Revision: https://phabricator.services.mozilla.com/D313993
This commit is contained in:
Paul Bone
2026-09-01 02:17:56 +00:00
committed by pbone@mozilla.com
parent 90f5d20710
commit dbf748e3f4
3 changed files with 25 additions and 29 deletions
+13 -17
View File
@@ -517,9 +517,11 @@ void base_chunk_dealloc(void* aChunk, size_t aSize, ChunkType aType) {
MOZ_ASSERT((aSize & kChunkSizeMask) == 0);
MOZ_ASSERT(!gChunkRTree.Get(aChunk));
#ifndef XP_WIN
if (gCache.TryRecord(aChunk, aSize, aType)) {
return;
}
#endif
pages_unmap(aChunk, aSize);
}
@@ -575,10 +577,16 @@ void* arena_chunk_alloc(chunk_allocator_t* aChunkAllocator, size_t aSize,
}
static void* system_pages_map(size_t aSize, size_t aAlignment) {
void* ret = gCache.Recycle(aSize, aAlignment);
void* ret = nullptr;
#ifndef XP_WIN
ret = gCache.Recycle(aSize, aAlignment);
if (!ret) {
#endif
ret = pages_mmap_aligned(aSize, aAlignment, ReserveAndCommit);
#ifndef XP_WIN
}
#endif
return ret;
}
@@ -602,11 +610,9 @@ bool arena_chunk_t::IsEmpty() {
(~gPageSizeMask | CHUNK_MAP_ALLOCATED)) == gMaxLargeClass;
}
bool ChunkCache::TryRecord(void* aChunk, size_t aSize, ChunkType aType) {
if (!CanRecycle(aSize)) {
return false;
}
#ifndef XP_WIN
bool ChunkCache::TryRecord(void* aChunk, size_t aSize, ChunkType aType) {
size_t recycled_so_far = mRecycledSize;
// In case some race condition put us above the limit.
@@ -617,17 +623,9 @@ bool ChunkCache::TryRecord(void* aChunk, size_t aSize, ChunkType aType) {
size_t recycle_remaining = gRecycleLimit - recycled_so_far;
size_t to_recycle;
if (aSize > recycle_remaining) {
#ifndef XP_WIN
to_recycle = recycle_remaining;
// Drop pages that would overflow the recycle limit
pages_trim(aChunk, aSize, 0, to_recycle, ReserveAndCommit);
#else
// On windows pages_trim unallocates and reallocates the whole
// chunk, there's no point doing that during recycling so instead we
// fail.
pages_unmap(aChunk, aSize);
return;
#endif
} else {
to_recycle = aSize;
}
@@ -705,10 +703,6 @@ void ChunkCache::Record(void* aChunk, size_t aSize, ChunkType aType) {
}
void* ChunkCache::Recycle(size_t aSize, size_t aAlignment) {
if (!CanRecycle(aSize)) {
return nullptr;
}
size_t alloc_size = aSize + aAlignment - kChunkSize;
// Beware size_t wrap-around.
if (alloc_size < aSize) {
@@ -780,3 +774,5 @@ void* ChunkCache::Recycle(size_t aSize, size_t aAlignment) {
// The global chunk cache.
ChunkCache gCache;
#endif /* ! XP_WIN */
+9 -12
View File
@@ -230,6 +230,13 @@ void* pages_mmap_aligned(size_t size, size_t alignment,
void pages_unmap(void* aAddr, size_t aSize);
// On Windows, calls to VirtualAlloc and VirtualFree must be matched, making
// it awkward to recycle allocations of varying sizes.
// Therefore the chunk cache is disabled on windows since arenas have a
// chunk list for arena chunks, and non-arena chunks arbitrary sizes
// don't cache well without splitting.
#ifndef XP_WIN
class ChunkCache {
private:
Mutex mMutex;
@@ -251,18 +258,6 @@ class ChunkCache {
void Init() { mMutex.Init(); }
static constexpr bool CanRecycle(size_t aSize) {
#ifdef XP_WIN
// On Windows, calls to VirtualAlloc and VirtualFree must be matched, making
// it awkward to recycle allocations of varying sizes. Therefore we only
// allow recycling when the size equals the chunksize, unless deallocation
// is entirely disabled.
return aSize == kChunkSize;
#else
return true;
#endif
}
// Try to put this chunk in the cache, false if the cache is full.
bool TryRecord(void* aChunk, size_t aSize, ChunkType aType);
@@ -277,4 +272,6 @@ class ChunkCache {
extern ChunkCache gCache;
#endif /* ! XP_WIN */
#endif /* ! CHUNK_H */
+3
View File
@@ -3448,7 +3448,10 @@ static bool malloc_init_hard() {
DefineGlobals();
#endif
#ifndef XP_WIN
gCache.Init();
#endif
huge_init();
sBaseAlloc.Init();