Commit graph

26 commits

Author SHA1 Message Date
Andreas Kling
4a3ee27702 LibGC: Use Vector::grow_capacity() in MarkingVisitor
Using ensure_capacity() was a mistake, as that API is for specifying an
exact needed capacity, while grow_capacity() is for growing at a
reasonable rate.

Amusingly, we ended up with very different behavior on macOS and Linux
here, since ensure_capacity() calls kmalloc_good_size() which quantizes
to malloc bucket sizes on macOS, but is effectively a no-op on Linux.

Extreme slowdown on Linux caught by GarBench/marking-stress.js
2026-01-08 21:42:01 +01:00
Andreas Kling
8b19992f8c LibGC: Make MarkingVisitor better at bulk-visiting Vector<JS::Value>
When passing a Vector<JS::Value> to the MarkingVisitor, we were
iterating over the vector and visiting one value at a time. This led
to a very inefficient way of building up the GC's work queue.

By adding a new visit_impl() virtual to Cell::Visitor, we can now
grow the work queue capacity once, and then add without incrementally
growing the storage.
2026-01-07 20:51:17 +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
75ad452099 LibGC: Remove one redundant HeapBlock enumeration pass in GC
We were enumerating all HeapBlocks twice to build a HashTable of all
live blocks. With this commit, we only do it once.
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
Aliaksandr Kalenik
763d638353 LibGC: Fix incorrect &cell key in GraphConstructorVisitor 2025-12-27 19:06:56 +01:00
Aliaksandr Kalenik
c26c9a9e45 LibGC: Skip not live cells in GraphConstructorVisitor
Makes `GraphConstructorVisitor` consistent with `MarkingVisitor`.
2025-12-27 19:06:56 +01:00
Aliaksandr Kalenik
ed58f85b75 LibGC: Introduce separate GC root type for "must survive GC" cells
This way `GraphConstructorVisitor` is aware of `MustSurviveGC` roots and
could include them in a dump.
2025-12-27 19:06:56 +01:00
Aliaksandr Kalenik
bfd9658181 LibGC: Add handling for ConservativeVector in dump() 2025-12-26 19:48:46 +01:00
Andreas Kling
2d29ca7e59 LibGC: Dump GC block allocator stats before running post-GC tasks
Post-GC tasks may trigger another GC, and things got very confusing
when that happened. Just dump all stats before running tasks.

Also add a separate Heap function to run these tasks. This makes
backtraces much easier to understand.
2025-12-25 20:21:37 +01:00
Andreas Kling
2a4a8a15f5 LibGC: Make must_survive_garbage_collection() actually work
This had two fatal bugs:

1. We didn't actually mark the cell that must survive GC, we only
   visited its edges.

2. Worse, we didn't actually mark anything at all! We just added
   cells to MarkingVisitor's work queue, but this happened after
   the work queue had already been processed.

This commit fixes these issues by moving the "must survive" pass
earlier in the mark phase.
2025-12-25 20:21:37 +01:00
Andreas Kling
710ea3e20a LibGC: Correct "reserved" field calculation in GC block allocator dumps 2025-12-21 12:08:41 -06:00
Andreas Kling
e9b0ef0afa LibGC: Add allocator statistics to post-GC report 2025-12-19 20:21:07 -06:00
Andreas Kling
716e5f72f2 LibGC: Always use 16 KiB as HeapBlock size
Before this change, we'd use the system page size as the HeapBlock
size. This caused it to vary on different platforms, going as low
as 4 KiB on most Linux systems.

To make this work, we now use posix_memalign() to ensure we get
size-aligned allocations on every platform.

Also nice: HeapBlock::BLOCK_SIZE is now a constant.
2025-12-19 20:21:07 -06:00
Andreas Kling
8289b24a7e LibJS: Introduce VM::the() and use it instead of caching VM pointer
In our process architecture, there's only ever one JS::VM per process.
This allows us to have a VM::the() singleton getter that optimizes
down to a single global access everywhere.

Seeing 1-2% speed-up on all JS benchmarks from this.
2025-12-09 11:58:39 -06:00
Andreas Kling
d234e9ee71 LibGC: Add GC::Heap::the()
There's only ever one GC::Heap per process, so let's have a way to find
it even when you have no context.
2025-11-01 08:40:32 +01:00
Andreas Kling
25a5ed94d6 LibGC: Add GC::Weak<T> as an alternative to AK::WeakPtr<T>
This is a weak pointer that integrates with the garbage collector.
It has a number of differences compared to AK::WeakPtr, including:

- The "control block" is allocated from a well-packed WeakBlock owned by
  the GC heap, not just a generic malloc allocation.

- Pointers to dead cells are nulled out by the garbage collector
  immediately before running destructors.

- It works on any GC::Cell derived type, meaning you don't have to
  inherit from AK::Weakable for the ability to be weakly referenced.

- The Weak always points to a control block, even when "null" (it then
  points to a null WeakImpl), which means one less null check when
  chasing pointers.
2025-10-17 17:22:16 +02:00
Andreas Kling
11ece7de10 LibGC: Add GC::RootHashMap<...> template container
This is a GC-aware wrapper around AK::HashMap. Entry values are treated
as GC roots, much like the GC::RootVector we already had.

We also provide GC::OrderedRootHashMap as a convenience.
2025-05-03 17:33:54 +02:00
Luke Wilde
5146bbe296 LibGC: Visit the edges of the cells that must survive garbage collection
Previously, we would only keep the cell that must survive alive, but
none of it's edges.

This cropped up with a GC UAF in must_survive_garbage_collection of
WebSocket in .NET's SignalR frontend implementation, where an
out-of-scope WebSocket had it's underlying EventTarget properties
garbage collected, and must_survive_garbage_collection read from the
destroyed EventTarget properties.

See: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts#L81
Found on https://www.formula1.com/ during a live session.

Co-Authored-By: Tim Flynn <trflynn89@pm.me>
2025-02-27 14:35:28 -05:00
Timothy Flynn
bc54c0cdfb AK+Everywhere: Store JSON strings as String 2025-02-20 19:27:51 -05:00
Timothy Flynn
70eb0ba1cd AK+Everywhere: Remove the char const* JSON value constructor 2025-02-20 19:27:51 -05:00
Andreas Kling
51a91771b8 LibJS+LibGC: Run FinalizationRegistry cleanup host hook *after* GC
Before this change, it was possible for a second GC to get triggered
in the middle of a first GC, due to allocations happening in the
FinalizationRegistry cleanup host hook. To avoid this causing problems,
we add a "post-GC task" mechanism and use that to invoke the host hook
once all other GC activity is finished, and we've unset the "collecting
garbage" flag.

Note that the test included here only fails reliably when running with
the -g flag (collect garbage after each allocation).

Fixes #3051
2025-01-23 12:10:21 +01:00
InvalidUsernameException
01f8ab35f1 LibGC: Rename remaining occurrence of marked vector
In 3bfb0534be `MarkedVector` was renamed to `RootVector`, but some
related symbols were missed. This commit corrects this.
2025-01-02 16:22:29 -07:00
Andreas Kling
3bfb0534be LibGC: Rename MarkedVector => RootVector
Let's try to make it a bit more clear that this is a Vector of GC roots.
2024-12-26 19:10:44 +01:00
Pavel Shliak
03ac6e6e87 LibGC: Preallocate space before dumping GC graph
Speeds up the append_gc_graph function by preallocating space.
This change reduces the time taken to dump the GC graph by 4%
on about:blank.
2024-12-14 09:06:58 +01: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
Renamed from Libraries/LibJS/Heap/Heap.cpp (Browse further)