Commit Graph

102 Commits

Author SHA1 Message Date
Undefine
e39a8719fd Meta: Move most dependency checks to check_for_dependencies.cmake
This file was here for quite a long while now. Let's finally move most
of the dependency checks to one centralized place.
2026-04-20 16:41:29 -06:00
Davi Gomes
6d77c9edd1 Libraries: Move #pragma once above include headers
The #pragma once was placed after the #include directives instead of
immediately after the copyright comment, inconsistent with every other
header file
2026-03-22 14:05:44 +01:00
Davi Gomes
d7c90639ae LibGC: Add missing & in Weak assignment
The Weak<T>::operator=(U const&) template incorrectly compares the
internal pointer directly against the `other` reference. If this
template is instantiated, it causes a compilation error because a Ptr<T>
cannot be compared directly to a U const&
2026-03-14 21:35:06 -05:00
Andreas Kling
fc675e8634 LibGC: Amortize pruning of dead entries in WeakHashSet
Previously, every set() and remove() call would do a full O(capacity)
scan of the underlying hash table to remove dead weak references.
This caused significant stalls on pages where the set grew large, as
every insertion paid the full cost of scanning the entire table.

Fix this by tracking mutations since last prune and only performing
the scan after enough operations to amortize the cost. The threshold
scales with the table size (minimum 64), so the per-operation cost
is O(1) amortized.
2026-03-08 20:49:28 +01:00
Andreas Kling
fe48e27a05 LibJS: Replace GC::Weak with GC::RawPtr in inline cache entries
Property lookup cache entries previously used GC::Weak<T> for shape,
prototype, and prototype_chain_validity pointers. Each GC::Weak
requires a ref-counted WeakImpl allocation and an extra indirection
on every access.

Replace these with GC::RawPtr<T> and make Executable a WeakContainer
so the GC can clear stale pointers during sweep via remove_dead_cells.

For static PropertyLookupCache instances (used throughout the runtime
for well-known property lookups), introduce StaticPropertyLookupCache
which registers itself in a global list that also gets swept.

Now that inline cache entries use GC::RawPtr instead of GC::Weak,
we can compare shape/prototype pointers directly without going
through the WeakImpl indirection. This removes one dependent load
from each IC check in GetById, PutById, GetLength, GetGlobal, and
SetGlobal handlers.
2026-03-08 10:27:13 +01:00
Zaggy1024
d0e7ffdf37 LibGC: Add missing root type switch cases in graph dump
Also, remove the default case so that we don't end up with missing
cases again.
2026-03-03 11:26:42 -06:00
Zaggy1024
7339c26059 LibGC: Use AK::unwind_stack_from_frame_pointer for stack pointer traces
This should allow it to function on RISC-V.
2026-03-03 11:26:42 -06:00
Zaggy1024
a3922aa570 LibGC+Meta: Include inline frames in the GC explorer's stack trace 2026-03-01 21:50:51 +01:00
Zaggy1024
03284abee9 LibGC+Meta: Display a frame size in the GC graph explorer's stack trace
This can help us track down overly-large frames that might be
contributing stale roots.
2026-03-01 21:50:51 +01:00
Zaggy1024
1a3e8fdf60 LibGC+Meta: Look up and display stack frames for StackPointer roots
This adds a stack trace to the JSON output from GC graph dumps which
is shown in a default-collapsed tray on the right side of the graph
explorer. When a stack pointer root is selected, the stack frame it
originated from is highlighted in the tray.
2026-03-01 21:50:51 +01:00
Jelle Raaijmakers
f9e837a832 LibGC+LibWeb: Add and use GC::weak_callback() 2026-02-26 08:03:50 -05:00
Andreas Kling
eda33abdbb LibGC: Remove hash() from Traits<GC::Weak<T>>
Make HashTable<GC::Weak<T>> a compile error to prevent future misuse.
All existing uses have been migrated to GC::WeakHashSet<T> which
provides its own internal hash traits.
2026-02-24 22:35:03 +01:00
Andreas Kling
323e7dd79d LibGC: Add GC::WeakHashSet<T> for safe weak pointer hash sets
HashTable<GC::Weak<T>> is unsafe because GC::Weak's hash depends on
ptr() which becomes nullptr when the object is collected. This corrupts
the hash table: entries shift to wrong buckets, probe chains break
during delete_bucket(), and rehash scatters dead entries incorrectly.

WeakHashSet wraps HashTable with private internal traits that own the
hash function, prunes dead entries before every mutation, and provides
an iterator that skips dead entries and yields T& directly.
2026-02-24 22:35:03 +01:00
Luke Wilde
74f91a089e LibGC: Add missing HeapVector forward declaration 2026-02-23 18:44:26 +00:00
Ben Wiederhake
a4e9287411 LibGC: Remove unused header in HeapBlock 2026-02-23 12:15:23 +01:00
Ben Wiederhake
af489080c4 LibGC: Remove unused header in Heap 2026-02-23 12:15:23 +01:00
Ben Wiederhake
082d17dec3 LibGC: Remove unused header in RootHashMap 2026-02-23 12:15:23 +01:00
Ben Wiederhake
771f6d1c83 LibGC: Remove unused header in Root 2026-02-23 12:15:23 +01:00
Ben Wiederhake
21142445a4 LibGC: Remove unused header in ConservativeVector 2026-02-23 12:15:23 +01:00
Ben Wiederhake
1c48b0dc60 LibGC: Remove unused header in CellAllocator 2026-02-23 12:15:23 +01:00
Ben Wiederhake
eab0367714 LibGC: Remove unused header in Cell 2026-02-23 12:15:23 +01:00
Ben Wiederhake
f006852203 LibGC: Remove unused header in BlockAllocator 2026-02-23 12:15:23 +01: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
Zaggy1024
a3619cd995 LibGC: Take GC::Function's AK::Function as rvalue reference
This saves us some copies that may result in useless ref counts when
constructing a GC::Function.
2026-02-18 13:13:32 -06:00
Andreas Kling
e87f889e31 Everywhere: Abandon Swift adoption
After making no progress on this for a very long time, let's acknowledge
it's not going anywhere and remove it from the codebase.
2026-02-17 10:48:09 -05:00
Sam Atkins
8ffac507c6 LibGC: Include CellAllocator.h in HeapVector.h
Next commit adds a user of this which doesn't already have the
GC_DECLARE_ALLOCATOR() macro available.
2026-02-17 07:40:03 -05:00
Andreas Kling
706eb0018c LibGC+LibWeb: Mark two GC::Cell functions as MUST_UPCALL
Let's make sure that subclasses always call their base class when
overriding these virtuals:

- void finalize()
- void visit_edges(Visitor&)
2026-02-06 13:50:54 +01:00
Andreas Kling
853716fec3 AK+LibGC+ClangPlugins: Add MUST_UPCALL attribute for virtual functions
This introduces a new MUST_UPCALL macro that expands to
[[clang::annotate("must_upcall")]] on Clang. When placed on a virtual
function, the Clang plugin will verify that all overrides call their
base class implementation.

This generalizes the existing Base::visit_edges() check to work with
any annotated virtual function. The first use is Cell::visit_edges(),
but this can be applied to other functions that require upcalls.

The plugin checks for calls via either Base:: (the common typedef
pattern) or the explicit parent class name.
2026-02-06 13:50:54 +01:00
Andreas Kling
d89f3fc5e6 LibGC+ClangPlugins: Forbid non-trivial destructors in Cell subclasses
Add a clang plugin check that flags GC::Cell subclasses (and their
base classes within the Cell hierarchy) that have destructors with
non-trivial bodies. Such logic should use Cell::finalize() instead.

Add GC_ALLOW_CELL_DESTRUCTOR annotation macro for opting out in
exceptional cases (currently only JS::Object).

This prevents us from accidentally adding code in destructors that
runs after something we're pointing to may have been destroyed.
(This could become a problem when the garbage collector sweeps
objects in an unfortunate order.)

This new check uncovered a handful of bugs which are then also fixed
in this commit. :^)
2026-01-30 20:57:42 +01:00
Shannon Booth
79e0e36e36 LibGC: Introduce GC::HeapHashTable<T>, a GC-aware hash table container
Conceptually similar to GC::Function and GC::HeapVector, allowing hash
tables to safely hold GC-managed values. GC::HeapHashTable derives
from GC::Cell and traces its table elements during marking.
2026-01-21 22:26:14 +01:00
Shannon Booth
6dc1ae36b2 LibGC: Add missing Export.h include in HeapRoot.h
This was causing weird clangd errors for myself.
2026-01-21 22:26:14 +01:00
Luke Wilde
babfd70ca7 LibGC: Enforce that a Cell type must declare the allocator to use
This ensures that we are explicitly declaring the allocator to use when
allocating a cell(-inheriting) type, instead of silently falling back
to size-based allocation.

Since this is done in allocate_cell, this will only be detected for
types that are actively being allocated. However, since that means
they're _not_ being allocated, that means it's safe to not declare
an allocator to use for those. For example, the base TypedArray<T>,
which is never directly allocated and only the defined specializations
are ever allocated.
2026-01-20 12:00:11 +01:00
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
Jelle Raaijmakers
d00571719f LibGC+LibJS+LibWeb: Add Visitor::visit(Optional<T>)
No functional changes.
2026-01-06 10:55:56 +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
64f91c41d9 LibGC: Allow construction of ConservativeVector from Vector 2025-12-26 19:48:46 +01:00
Aliaksandr Kalenik
bfd9658181 LibGC: Add handling for ConservativeVector in dump() 2025-12-26 19:48:46 +01:00
Aliaksandr Kalenik
45c22b0313 LibGC: Implement copy assignment operator for ConservativeVector
- Delete defined but not implemented
  `ConservativeVectorBase& operator=(ConservativeVectorBase const&);`
- Mark `ConservativeVectorBase` as non-copyable because underlying
  `m_list_node` cannot be copied safely.
- Change `ConservativeVector` copy assignment to simply copy elements
  from one vector to another, since we don't have to worry about
  `ConservativeVectorBase` while copying.
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
0ac48b6e08 LibGC: Add GC::HeapVector<T>, a fully GC-aware vector container
HeapVector inherits from GC::Cell, and thus participates in tracing
garbage collection. It's not a standalone vector of roots like
RootVector or ConservativeVector. It must be marked for its elements to
be marked.
2025-12-25 20:21:37 +01:00
Andreas Kling
0db2e32e8f LibGC: Allow move/copy construction of Weak<T> from Weak<T> 2025-12-24 10:19:28 +01:00
Andreas Kling
710ea3e20a LibGC: Correct "reserved" field calculation in GC block allocator dumps 2025-12-21 12:08:41 -06:00