LibGC: Tune heap allocation threshold and growth factor

Establish post-collection heap thresholds with a 1.75x growth factor
over live byte count, with an 8 MiB minimum.

These constants were chosen based on a benchmark sweep of the
Speedometer browser benchmarks (and a wider set of JS workloads) — see
the PR description for the data behind the choice.

Keep the constants in Heap.cpp instead of Heap.h so future tweaks don't
trigger 1000+ file rebuilds.
This commit is contained in:
Andreas Kling 2026-05-05 23:52:57 +02:00 committed by Andreas Kling
parent de7ed9a498
commit 7d9074efa8
2 changed files with 8 additions and 3 deletions

View file

@ -38,6 +38,10 @@
namespace GC {
static constexpr size_t GC_MIN_BYTES_THRESHOLD { 8 * 1024 * 1024 };
static constexpr size_t GC_HEAP_GROWTH_FACTOR_NUMERATOR { 7 };
static constexpr size_t GC_HEAP_GROWTH_FACTOR_DENOMINATOR { 4 };
static Heap* s_the;
Heap& Heap::the()
@ -49,6 +53,7 @@ Heap::Heap(AK::Function<void(HashMap<Cell*, GC::HeapRoot>&)> gather_embedder_roo
: m_gather_embedder_roots(move(gather_embedder_roots))
{
s_the = this;
m_gc_bytes_threshold = GC_MIN_BYTES_THRESHOLD;
static_assert(HeapBlock::min_possible_cell_size <= 32, "Heap Cell tracking uses too much data!");
m_size_based_cell_allocators.append(make<CellAllocator>(64));
m_size_based_cell_allocators.append(make<CellAllocator>(96));
@ -779,7 +784,8 @@ void Heap::sweep_dead_cells(bool print_report, Core::ElapsedTimer const& measure
});
}
m_gc_bytes_threshold = live_cell_bytes > GC_MIN_BYTES_THRESHOLD ? live_cell_bytes : GC_MIN_BYTES_THRESHOLD;
auto next_gc_bytes_threshold = live_cell_bytes * GC_HEAP_GROWTH_FACTOR_NUMERATOR / GC_HEAP_GROWTH_FACTOR_DENOMINATOR;
m_gc_bytes_threshold = max(next_gc_bytes_threshold, GC_MIN_BYTES_THRESHOLD);
if (print_report) {
AK::Duration const time_spent = measurement_timer.elapsed_time();

View file

@ -155,8 +155,7 @@ private:
}
}
static constexpr size_t GC_MIN_BYTES_THRESHOLD { 4 * 1024 * 1024 };
size_t m_gc_bytes_threshold { GC_MIN_BYTES_THRESHOLD };
size_t m_gc_bytes_threshold { 0 };
size_t m_allocated_bytes_since_last_gc { 0 };
bool m_should_collect_on_every_allocation { false };