LibJS: Improve garbage collection trigger condition

This patch triggers the collector when allocated memory doubles instead
of every 100k allocations. Which can almost half (reduce by ~48%) the
time spent on collection when loading google-maps.

This dynamic approach is inspired by some other GCs like Golang's and
Lua's and improves performance in memory heavy applications because
marking must visit old objects which will dominate the marking phase if
the GC is invoked too often.

This commit also improves the Octane Splay benchmark and almost
doubles it :^)
This commit is contained in:
flofriday 2023-08-08 19:50:32 +02:00 committed by Andreas Kling
commit a2abc5b824
Notes: sideshowbarker 2024-07-17 21:11:12 +09:00
2 changed files with 9 additions and 6 deletions

View file

@ -79,14 +79,14 @@ ALWAYS_INLINE CellAllocator& Heap::allocator_for_size(size_t cell_size)
Cell* Heap::allocate_cell(size_t size)
{
if (should_collect_on_every_allocation()) {
m_allocated_bytes_since_last_gc = 0;
collect_garbage();
} else if (m_allocations_since_last_gc > m_max_allocations_between_gc) {
m_allocations_since_last_gc = 0;
} else if (m_allocated_bytes_since_last_gc + size > m_gc_bytes_threshold) {
m_allocated_bytes_since_last_gc = 0;
collect_garbage();
} else {
++m_allocations_since_last_gc;
}
m_allocated_bytes_since_last_gc += size;
auto& allocator = allocator_for_size(size);
return allocator.allocate_cell(*this);
}
@ -354,6 +354,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;
if (print_report) {
Duration const time_spent = measurement_timer.elapsed_time();
size_t live_block_count = 0;