Commit Graph

8 Commits

Author SHA1 Message Date
Andreas Kling
b9ec043b5a LibGC: Add live HeapBlock registry to fix weak container UAF
Maintain a HashTable<HeapBlock*> of live heap blocks in the Heap,
updated on block creation and destruction.

Weak containers (WeakMap, WeakSet, WeakRef, FinalizationRegistry)
now check block liveness before accessing cell memory in their
remove_dead_cells() methods. This prevents use-after-free when
blocks have been freed during incremental sweeping.
2026-05-10 10:58:11 +02:00
Andreas Kling
fb4095ae50 LibGC: Implement incremental sweeping for reduced GC pause times
Instead of sweeping all heap blocks in one go after marking, sweep
incrementally, one block at a time, interleaved with program execution.
This significantly reduces worst-case GC pause times by spreading
sweep work across multiple smaller time slices.

Sweep is driven by two complementary mechanisms:

1. Timer-based sweeping: A 16ms repeating timer drives background
   sweep work, processing blocks for up to 5ms per timer fire.

2. Allocation-directed sweeping: Each allocator sweeps its own
   pending blocks before creating new ones, ensuring forward
   progress even without timer events.

Each allocator maintains its own list of blocks pending sweep,
and allocators with pending work are tracked in a separate list
for efficient timer-driven sweeping.

Key implementation details:

- Newly allocated cells during sweep are marked immediately to
  prevent premature collection.

- Mark bits are cleared incrementally as each block is swept,
  rather than in a separate pass over the entire heap.

- Finalization and weak reference processing remain stop-the-world
  since they must complete atomically before any sweeping occurs.
2026-05-10 10:58:11 +02:00
Shannon Booth
95e13f71a9 LibGC: Prefer Optional<StringView> for CellAllocator class name
In an effort towards removing the use of the null state of StringView.
2026-02-21 12:37:44 +01:00
Shannon Booth
1787f06bbd LibGC: Remove unused cell name parameter from HeapBlock 2026-02-21 12:37:44 +01:00
Andreas Kling
2ac363dcba LibGC: Only call finalize() on types that override finalize()
This dramatically cuts down on time spent in the GC's finalizer pass,
since most types don't override finalize().
2026-01-07 20:51:17 +01:00
Andreas Kling
280049e52d LibGC+LibWeb: Only ask relevant cell types if they must survive GC
Instead of checking if every single cell overrides the "must survive GC"
virtual, we can make this a HeapBlock level thing.

This avoids almost an entire GC heap traversal during the mark phase.
2026-01-07 20:51:17 +01:00
Andreas Kling
e9b0ef0afa LibGC: Add allocator statistics to post-GC report 2025-12-19 20:21:07 -06:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00