Commit graph

18 commits

Author SHA1 Message Date
Andreas Kling
3c74dc9f4d LibJS: Segregate GC-allocated objects by type
This patch adds two macros to declare per-type allocators:

- JS_DECLARE_ALLOCATOR(TypeName)
- JS_DEFINE_ALLOCATOR(TypeName)

When used, they add a type-specific CellAllocator that the Heap will
delegate allocation requests to.

The result of this is that GC objects of the same type always end up
within the same HeapBlock, drastically reducing the ability to perform
type confusion attacks.

It also improves HeapBlock utilization, since each block now has cells
sized exactly to the type used within that block. (Previously we only
had a handful of block sizes available, and most GC allocations ended
up with a large amount of slack in their tails.)

There is a small performance hit from this, but I'm sure we can make
up for it elsewhere.

Note that the old size-based allocators still exist, and we fall back
to them for any type that doesn't have its own CellAllocator.
2023-11-19 12:10:31 +01:00
Andreas Kling
72c9f56c66 LibJS: Make Heap::allocate<T>() infallible
Stop worrying about tiny OOMs. Work towards #20449.

While going through these, I also changed the function signature in many
places where returning ThrowCompletionOr<T> is no longer necessary.
2023-08-13 15:38:42 +02:00
Linus Groh
b84f8fb55b LibJS: Make intrinsics getters return NonnullGCPtr
Some of these are allocated upon initialization of the intrinsics, and
some lazily, but in neither case the getters actually return a nullptr.

This saves us a whole bunch of pointer dereferences (as NonnullGCPtr has
an `operator T&()`), and also has the interesting side effect of forcing
us to explicitly use the FunctionObject& overload of call(), as passing
a NonnullGCPtr is ambigous - it could implicitly be turned into a Value
_or_ a FunctionObject& (so we have to dereference manually).
2023-04-13 14:29:42 +02:00
Timothy Flynn
b75b7f0c0d LibJS+Everywhere: Propagate Cell::initialize errors from Heap::allocate
Callers that are already in a fallible context will now TRY to allocate
cells. Callers in infallible contexts get a FIXME.
2023-01-29 00:02:45 +00:00
Linus Groh
22089436ed LibJS: Convert Heap::allocate{,_without_realm}() to NonnullGCPtr 2022-12-15 06:56:37 -05:00
Andreas Kling
4abdb68655 LibJS: Remove Object(Object& prototype) footgun
This constructor was easily confused with a copy constructor, and it was
possible to accidentally copy-construct Objects in at least one way that
we dicovered (via generic ThrowCompletionOr construction).

This patch adds a mandatory ConstructWithPrototypeTag parameter to the
constructor to disambiguate it.
2022-12-14 15:11:57 +01:00
Linus Groh
54ebf71da2 LibJS: Convert WeakSet::create() to NonnullGCPtr 2022-12-14 09:59:45 +00:00
Linus Groh
50428ea8d2 LibJS: Move intrinsics to the realm
Intrinsics, i.e. mostly constructor and prototype objects, but also
things like empty and new object shape now live on a new heap-allocated
JS::Intrinsics object, thus completing the long journey of taking all
the magic away from the global object.
This represents the Realm's [[Intrinsics]] slot in the spec and matches
its existing [[GlobalObject]] / [[GlobalEnv]] slots in terms of
architecture.

In the majority of cases it should now be possibly to fully allocate a
regular object without the global object existing, and in fact that's
what we do now - the realm is allocated before the global object, and
the intrinsics between both :^)
2022-08-27 11:29:10 +01:00
Linus Groh
e992a9f469 LibJS+LibWeb: Replace GlobalObject with Realm in Heap::allocate<T>()
This is a continuation of the previous three commits.

Now that create() receives the allocating realm, we can simply forward
that to allocate(), which accounts for the majority of these changes.
Additionally, we can get rid of the realm_from_global_object() in one
place, with one more remaining in VM::throw_completion().
2022-08-23 13:58:30 +01:00
Linus Groh
b99cc7d050 LibJS+LibWeb: Replace GlobalObject with Realm in create() functions
This is a continuation of the previous two commits.

As allocating a JS cell already primarily involves a realm instead of a
global object, and we'll need to pass one to the allocate() function
itself eventually (it's bridged via the global object right now), the
create() functions need to receive a realm as well.
The plan is for this to be the highest-level function that actually
receives a realm and passes it around, AOs on an even higher level will
use the "current realm" concept via VM::current_realm() as that's what
the spec assumes; passing around realms (or global objects, for that
matter) on higher AO levels is pointless and unlike for allocating
individual objects, which may happen outside of regular JS execution, we
don't need control over the specific realm that is being used there.
2022-08-23 13:58:30 +01:00
Lenny Maiorani
d00b79568f Libraries: Use default constructors/destructors in LibJS
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-16 16:19:40 +00:00
Andreas Kling
e08d325124 LibJS: Use HashTable::remove_all_matching() in WeakSet :^) 2022-01-05 18:57:14 +01:00
Andreas Kling
83bd675477 LibJS: Make WeakContainer pruning do less work
Instead of iterating *all* swept cells when pruning weak containers,
only iterate the cells actually *in* the container.

Also, instead of compiling a list of all swept cells, we can simply
check the Cell::state() flag to know if something should be pruned.
2021-10-05 18:52:00 +02:00
Andreas Kling
470c99a2a6 LibJS: Tweak the WeakContainer::remove_swept_cells() API a little bit
Make this API take a Span<Cell*> instead of a Vector<Cell*>&.
This is behavior neutral, but stops the API looking like it wants to
do mutable things to the Vector.
2021-09-11 12:09:55 +02:00
Andreas Kling
cd53d046b2 LibJS: Fix typo "sweeped" => "swept" everywhere 2021-06-27 22:40:49 +02:00
Idan Horowitz
1a8ee5d8d7 LibJS: Generify the garbage collector's weak container notifications
This will allow us to use the same interface for other JS weak
containers like the WeakMap & WeakRef.
2021-06-12 10:44:28 +01:00
Idan Horowitz
a00d154522 LibJS: Notify WeakSets when heap cells are sweeped
This is an implementation of the following optional optimization:
https://tc39.es/ecma262/#sec-weakref-execution
2021-06-09 21:52:25 +01:00
Idan Horowitz
8b6beac5ce LibJS: Add the WeakSet built-in object 2021-06-09 21:52:25 +01:00