1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 05:48:12 +00:00
Commit graph

5014 commits

Author SHA1 Message Date
Shannon Booth
95e9c89a15 LibJS: Update spec comments in Array.fromAsync
This was a normative change in the Array.fromAsync spec which we already
implemented :^). See:

https://github.com/tc39/proposal-array-from-async/commit/689d0d

I've left an existing FIXME in there for some other bug which we have
which is causing some test262 test cases to fail.
2023-12-23 20:22:42 -05:00
Andreas Kling
6c1fcc5f7e LibJS: Actually invoke the type-isolating cell allocators
Due to a `requires` mistake, we were always using the fallback
size-based cell allocators.

Also, now that we start using them, make them NeverDestroyed so
we don't try to deallocate them on program exit.
2023-12-23 23:02:10 +01:00
Andreas Kling
f4fa37afd2 LibJS+LibWeb: Add missing JS_DEFINE_ALLOCATOR() for a bunch of classes 2023-12-23 23:02:10 +01:00
Andreas Kling
11c968fa1f LibJS: Make Heap aware of all CellAllocators
Also add a link from HeapBlock to their owning CellAllocator.
This fixes an issue where the Heap would skip over non-size-based
cell allocators.
2023-12-23 23:02:10 +01:00
Shannon Booth
e2e7c4d574 Everywhere: Use to_number<T> instead of to_{int,uint,float,double}
In a bunch of cases, this actually ends up simplifying the code as
to_number will handle something such as:

```
Optional<I> opt;
if constexpr (IsSigned<I>)
    opt = view.to_int<I>();
else
    opt = view.to_uint<I>();
```

For us.

The main goal here however is to have a single generic number conversion
API between all of the String classes.
2023-12-23 20:41:07 +01:00
Andrew Kaster
82ec1ea75e LibJS: Provide better assertion for empty execution context stack
When calling `running_execution_context` from other VM APIs, and the
execution context stack is empty, the verification message is inlined
from AK::Vector. Add a specific VERIFY to `running_execution_context` to
help diagnose this issue better.
2023-12-19 21:08:05 +01:00
Andrew Kaster
d361221657 LibJS+LibWeb: Add JS::Value constructor for `JS::Handle<T>`
Similar to the constructors for ``JS::{Nonnull}GCPtr<T>``, this helper
avoids unnecessary .ptr() clutter when we want to construct Values.
2023-12-19 09:21:55 -07:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).

This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
2023-12-17 18:25:10 +03:30
Andreas Kling
ed1ade0534 LibJS: Don't crash in CyclicModule::evaluate() when this == m_cycle_root
The spec allows this scenario, so I don't know why we would want to
assert that it doesn't happen.

Fixes #22317

Also, -1 crash, +1 pass on test262 :^)
2023-12-16 19:39:23 +01:00
Andreas Kling
1e90379008 LibJS: Introduce "dictionary" mode for object shapes
This is similar to "unique" shapes, which were removed in commit
3d92c26445.

The key difference is that dictionary shapes don't have a serial number,
but instead have a "cacheable" flag.

Shapes become dictionaries after 64 transitions have occurred, at which
point no further transitions occur.

As long as properties are only added to a dictionary shape, it remains
cacheable. (Since if we've cached the shape pointer in an IC somewhere,
we know the IC is still valid.)

Deleting a property from a dictionary shape causes it to become an
uncacheable dictionary.

Note that deleting a property from a non-dictionary shape still performs
a delete transition.

This fixes an issue on Discord where Object.freeze() would eventually
OOM us, since they add more than 16000 properties to a single object
before freezing it.

It also yields a 15% speedup on Octane/pdfjs.js :^)
2023-12-16 14:25:58 +01:00
Aliaksandr Kalenik
b108d51c5b LibJS: Only consider VM-accessible execution contexts as strong roots
Partially reverts 3dc5f467a8 to fix
GC memory leak that happens because we treated all execution contexts
as strong roots.
2023-12-13 11:19:13 +01:00
Aliaksandr Kalenik
57e5abae92 LibJS+LibWebView+WebContent+Ladybird: Output GC-graph into a file
Instead of displaying a massive JSON in stdout, it's more practical
to save the GC-graph to a file.
2023-12-12 15:35:35 +01:00
Andreas Kling
ed1bee222b LibJS: Give Shape::TransitionType an underlying 8-bit type
This shrinks Shape by 8 bytes. :^)
2023-12-12 15:26:46 +01:00
Andreas Kling
6cbcd521a2 LibJS/JIT: Add fast path for UnaryMinus on Int32
5% speedup on Octane/mandreel.js :^)
2023-12-12 00:10:44 +01:00
Andreas Kling
8eacb81eba LibJS: Skip redundant marking of Shape property table keys
All the keys in a property table are guaranteed to be marked via
Shape::m_property_key in each step of the transition chain that leads
up to the Shape.
2023-12-11 20:36:15 +01:00
Andreas Kling
3d92c26445 LibJS: Stop making shapes unique
We previously had a concept of unique shapes, which meant that they
couldn't be shared between multiple objects.

Object shapes became unique in three situations:

- They were the shape of the global object.
- They had more than 100 properties added to them.
- They had one or more properties deleted from them.

Unfortunately, unique shapes presented an annoying problem for inline
caches, and we added a "unique shape serial number" for being able to
tell that a unique shape had been mutated.

This patch gets rid of the concept of unique shapes, simplifying all
the caching code, since inline caches can now simply perform a shape
check and then we're good.

To make this possible, we now have the concept of delete transitions,
which occur when a property is deleted from a shape.

Note that this patch by itself introduces a performance regression in
some situtations, since we now create a lot more shapes, and marking
their property keys can be very heavy. This will be addressed in a
subsequent patch.
2023-12-11 20:36:15 +01:00
Andreas Kling
ef86cf4646 LibJS: Mark forward shape transition keys
These should really be weakly held by the Shape, but we don't have a
mechanism for weak hashmap keys at the moment, so let's just mark
these for now so they don't go stale.
2023-12-11 20:36:15 +01:00
Aliaksandr Kalenik
6ac43274b2 LibWeb+LibJS: Use JS::GCPtr for pointers to GC-allocated objects
Fixes warnings found by LibJSGCVerifier
2023-12-11 16:55:25 +01:00
Andreas Kling
37b5c05ec5 LibJS: Add fast path for Uint8ClampedArray Get/Put
These are just like Uint8Array, except Put values have to be clamped
in the 0..255 range.

Takes CPU usage from 40% to 30% on the "Canvas Cycle" demo at
http://www.effectgames.com/demos/canvascycle/ :^)
2023-12-10 13:49:00 +01:00
Andreas Kling
463931384d LibJS: Don't use Handle<Value> for JS::Object private fields
There's no reason to use handles here, we can just mark private element
values from objects that store them.
2023-12-10 09:44:26 +01:00
Andreas Kling
d8be9ebc16 LibJS: Add fast path in ArrayIteratorPrototype::next()
When iterating over vanilla objects/arrays with normal property storage,
we can skip the generic Get mechanism in favor of looking directly at
property storage. This is essentially what we do in the bytecode path.
2023-12-09 00:20:25 +01:00
Andreas Kling
373ec387c1 LibJS: Add fast_is<ArrayIterator>() 2023-12-09 00:20:25 +01:00
Andreas Kling
73ceb475b9 LibJS: Add fast path for magical "length" property in LengthOfArrayLike
For Array objects, we can avoid a generic Get here since we know it has
magical "length" behavior anyway.
2023-12-09 00:20:25 +01:00
Andreas Kling
f47a14b9d6 LibJS: Use a premade shape when creating iterator result objects
Instead of going through the steps of creating an empty new object,
and adding two properties ("value" and "done") to it, we can pre-bake
a shape object and cache the property offsets.

This makes creating iterator result objects in the runtime much faster.

47% speedup on this microbenchmark:

    function go(a) {
        for (const p of a) {
        }
    }
    const a = [];
    a.length = 1_000_000;
    go(a);
2023-12-08 00:54:05 +01:00
Jesús (gsus) Lapastora
706710fa13 LibJS/JIT: Make generating GDB images opt-in
Since generating GDB image can be expensive, it is disabled by default
and can be activated by setting the `LIBJS_JIT_GDB` environment
variable.
2023-12-07 15:34:38 -07:00
Jesús (gsus) Lapastora
f0b984567a LibJS/JIT: Produce & register an ELF image for GDB JIT Interface
Using the code that it has just produced, the JIT::Compiler can build an
ELF image so that we can attach meaningful symbols to JITted code, and
thus enable GDB to display more information about the code that we're
running.
2023-12-07 15:34:38 -07:00
Dan Klishch
96d44b1572 Userland: Make bit-fields compatible with MSVC C++ ABI 2023-12-07 10:28:19 -07:00
Andreas Kling
350e6c54d7 LibJS: Remove dedicated iterator result instructions in favor of GetById
When iterating over an iterable, we get back a JS object with the fields
"value" and "done".

Before this change, we've had two dedicated instructions for retrieving
the two fields: IteratorResultValue and IteratorResultDone. These had no
fast path whatsoever and just did a generic [[Get]] access to fetch the
corresponding property values.

By replacing the instructions with GetById("value") and GetById("done"),
they instantly get caching and JIT fast paths for free, making iterating
over iterables much faster. :^)

26% speed-up on this microbenchmark:

    function go(a) {
        for (const p of a) {
        }
    }
    const a = [];
    a.length = 1_000_000;
    go(a);
2023-12-07 18:12:24 +01:00
Andreas Kling
4699c81fc1 LibJS: Stop converting between Object <-> IteratorRecord all the time
This patch makes IteratorRecord an Object. Although it's not exposed to
author code, this does allow us to store it in a VM register.

Now that we can store it in a VM register, we don't need to convert it
back and forth between IteratorRecord and Object when accessing it from
bytecode.

The big win here is avoiding 3 [[Get]] accesses on every iteration step
of for..of loops. There are also a bunch of smaller efficiencies gained.

20% speed-up on this microbenchmark:

    function go(a) {
        for (const p of a) {
        }
    }
    const a = [];
    a.length = 1_000_000;
    go(a);
2023-12-07 14:06:34 +01:00
Andreas Kling
c9f0f0fc70 LibJS: Elide empty lexical environment in for..in/of blocks
When all the variables in a for..in/of block's lexical scope have been
turned into locals, we don't need to create and immediately abandon an
empty environment for them.

This avoid environment allocation in cases like this:

    function foo(a) {
        for (const x of a) {
        }
    }
2023-12-07 10:52:57 +01:00
Andreas Kling
a2c3db8367 LibJS: Add basic support for module code with top-level await
For now, we handle this by creating a synthetic async function to wrap
the top-level module code. This allows us to piggyback on the async
function driver wrapper mechanism.
2023-12-06 12:58:04 +01:00
Andreas Kling
26c21fba8e LibJS: Use LoadRequestedModules in the ad-hoc module loading path
This ensures that modules go through the expected state transitions,
fixing hundreds of test262 tests.
2023-12-06 12:58:04 +01:00
Andreas Kling
d7005be768 LibJS: Update CyclicModule to match current spec
Just some minor comment tweaks and an updated assertion.
2023-12-06 12:58:04 +01:00
Andreas Kling
58294db294 LibJS: Add successfully loaded modules to the VM's stored module list
This ensures that repeated loads of the same module succeed. (There is a
specific criteria where the same exact module object has to be returned
for multiple loads of the same referrer + specifier.)

Note that we don't check the referrer at the moment, that's a FIXME.
2023-12-03 20:46:55 +01:00
Andreas Kling
99106df834 LibJS: Update import referrer's [[LoadedModules]] in place
We were previously updating a copy of the list, which meant loading
could not proceed even after a module was loaded.
2023-12-03 20:46:55 +01:00
Andreas Kling
5e67853b49 LibJS: Fix logic typo in ContinueModuleLoading 2023-12-03 20:46:55 +01:00
Andreas Kling
fc31a0d506 LibJS: Support LoadRequestedModule AO on SyntheticModule records
This allows test-js to run all the module tests in the new world.
2023-12-03 20:46:55 +01:00
Andreas Kling
4b1053e327 LibJS: Fix logic typo in CyclicModule::inner_module_linking()
The comment was right, but the code didn't match.
2023-12-03 20:46:55 +01:00
Andreas Kling
8b7d27b349 LibJS+LibWeb: More bringing module loading closer to spec
In particular, this patch removes three host hooks on JS::VM in favor
of the new JS-side module loading stuff.
2023-12-03 20:46:55 +01:00
Andreas Kling
07f567cd9f LibJS+LibWeb: Another round of bringing module loading closer to spec
In particular, this patch focuses on:
- Updating the old "import assertions" to the new "import attributes"
- Allowing realms as module import referrer
2023-12-03 20:46:55 +01:00
Andreas Kling
82977ab44b LibJS: Implement GetImportedModule and call it where appropriate
This breaks module loading temporarily while transitioning.
2023-12-03 20:46:55 +01:00
Andreas Kling
a24c543921 LibJS: Update spec steps & add missing assertions in ResolveExport 2023-12-03 20:46:55 +01:00
Andreas Kling
40d2560a93 LibJS: Update spec steps & add missing assertions in GetExportedNames 2023-12-03 20:46:55 +01:00
Andreas Kling
467a5ceb18 LibJS: Split big VERIFY conditions into smaller ones in CyclicModule
This makes assertion failures here more informative.
2023-12-03 20:46:55 +01:00
Andreas Kling
0817d8bda6 LibJS+LibWeb: Make CyclicModule & GraphLoadingState GC-allocated
This allows them to participate in the ownership graph and fixes a
lifetime issue in module loading found by ASAN.

Co-Authored-By: networkException <networkexception@serenityos.org>
2023-12-03 20:46:55 +01:00
Andreas Kling
aa7501a66a LibJS: Set initial state of CyclicModule.[[Status]] to NEW
This is what the specification tells us to do:
https://tc39.es/ecma262/#cyclic-module-record

Co-Authored-By: networkException <networkexception@serenityos.org>
2023-12-03 20:46:55 +01:00
Todderod
e335354b30 LibJS: Call builtins directly in the bytecode interpreter
Allows the bytecode interpreter to call the builtins c++
implementation directly without making a javascript call
just as the JIT.

Kraken test speedups: imaging-gaussian-blur.js (1.5x) and
audio-oscillator.js (1.2x)
2023-12-01 13:01:26 +01:00
Timothy Flynn
026363024f LibJS: Stub out Atomics.notify
We don't have the facilities to implement this method fully (namely, a
fully realized SharedArrayBuffer). But we can implement enough to
validate the values passed in by the user.
2023-11-30 09:51:46 -05:00
Timothy Flynn
78edaad97d LibJS: Stub out Atomics.wait and Atomics.waitAsync
We don't have the facilities to implement these methods fully (namely, a
fully realized SharedArrayBuffer). But we can implement enough to
validate the values passed in by the user.
2023-11-30 09:51:46 -05:00
Timothy Flynn
a7073c3f1f LibJS: Skip test262 tests with the CanBlockIsFalse flag
From test262 documentation, this flag means:

    The test file should only be run when the [[CanBlock]] property of
    the Agent Record executing the file is `false`.

This patch stubs out the accessor for that internal slot and skips tests
with the CanBlockIsFalse if that internal slot is true.
2023-11-30 09:51:46 -05:00