1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 11:24:58 +00:00
Commit graph

191 commits

Author SHA1 Message Date
Andreas Kling
5b69413c4b Revert "LibJS/Bytecode: Bring back the bytecode optimization pipeline"
This reverts commit 5b29974bfa.
2024-03-06 08:39:29 +01:00
Andreas Kling
cf81bf48c6 Revert "LibJS/Bytecode: Add peephole optimization pass and fuse compare+jump"
This reverts commit 4438ec481c.

Fixes #23480.
2024-03-06 08:39:29 +01:00
Andreas Kling
c4a0afbe28 Revert "LibJS/Bytecode: Fuse [Not, JumpIf] instructions into JumpIfNot"
This reverts commit 795149e585.
2024-03-06 08:39:29 +01:00
Andreas Kling
a5e1e66abc LibJS/Bytecode: Add fast path for LeftShift with Int32 operands 2024-03-04 20:54:51 +01:00
Andreas Kling
795149e585 LibJS/Bytecode: Fuse [Not, JumpIf] instructions into JumpIfNot 2024-03-04 20:54:51 +01:00
Andreas Kling
4438ec481c LibJS/Bytecode: Add peephole optimization pass and fuse compare+jump
This patch adds a new "Peephole" pass for performing small, local
optimizations to bytecode.

We also introduce the first such optimization, fusing a sequence of
some comparison instruction FooCompare followed by a JumpIf into a
new set of JumpFooCompare instructions.

This gives a ~50% speed-up on the following microbenchmark:

    for (let i = 0; i < 10_000_000; ++i) {
    }

But more traditional benchmarks see a pretty sizable speed-up as well,
for example 15% on Kraken/ai-astar.js and 16% on Kraken/audio-dft.js :^)
2024-03-04 20:54:51 +01:00
Andreas Kling
5b29974bfa LibJS/Bytecode: Bring back the bytecode optimization pipeline
...minus the EliminateLoads pass, since it was not compatible with the
new bytecode format.
2024-03-04 20:54:51 +01:00
Andreas Kling
60a555e364 LibJS/Bytecode: Make NewPrimitiveArray a variable-length instruction
Instead of having a FixedArray with a separate heap allocation, we can
just bake the primitive values into the instruction itself.
2024-03-03 22:27:44 +01:00
Andreas Kling
5813df21c8 LibJS/Bytecode: Make primitive bigints be constants
Instead of emitting a NewBigInt instruction to construct a primitive
bigint from a parsed literal, we now instantiate the BigInt on the heap
during codegen.
2024-03-03 22:27:44 +01:00
Andreas Kling
46d209c55b LibJS/Bytecode: Make primitive strings be constants
Instead of emitting a NewString instruction to construct a primitive
string from a parsed literal, we now instantiate the PrimitiveString on
the heap during codegen.
2024-03-03 22:27:44 +01:00
Andreas Kling
9a0a5a79f4 LibJS/Bytecode: Put arguments directly in the Call instruction
Instead of having Call refer to a range of VM registers, it now has
a trailing list of argument operands as part of the instruction.

This means we no longer have to shuffle every argument value into
a register before making a call, making bytecode smaller & faster. :^)
2024-02-20 21:25:18 +01:00
Andreas Kling
da107ec9fb LibJS/Bytecode: Add fast paths for many binary expression instructions
By handling common cases like Int32 arithmetic directly in the
instruction handler, we can avoid the cost of calling the generic helper
functions in Value.cpp.
2024-02-20 21:25:18 +01:00
Andreas Kling
9d9b737a58 LibJS/Bytecode: Dedicated instructions for postfix increment/decrement
Instead of splitting the postfix variants into ToNumeric + Inc/Dec,
we now have dedicated PostfixIncrement and PostfixDecrement instructions
that handle both outputs in one go.
2024-02-20 21:25:18 +01:00
Andreas Kling
e46b217e42 LibJS/Bytecode: Move to a new bytecode format
This patch moves us away from the accumulator-based bytecode format to
one with explicit source and destination registers.

The new format has multiple benefits:

- ~25% faster on the Kraken and Octane benchmarks :^)
- Fewer instructions to accomplish the same thing
- Much easier for humans to read(!)

Because this change requires a fundamental shift in how bytecode is
generated, it is quite comprehensive.

Main implementation mechanism: generate_bytecode() virtual function now
takes an optional "preferred dst" operand, which allows callers to
communicate when they have an operand that would be optimal for the
result to go into. It also returns an optional "actual dst" operand,
which is where the completion value (if any) of the AST node is stored
after the node has "executed".

One thing of note that's new: because instructions can now take locals
as operands, this means we got rid of the GetLocal instruction.
A side-effect of that is we have to think about the temporal deadzone
(TDZ) a bit differently for locals (GetLocal would previously check
for empty values and interpret that as a TDZ access and throw).
We now insert special ThrowIfTDZ instructions in places where a local
access may be in the TDZ, to maintain the correct behavior.

There are a number of progressions and regressions from this test:

A number of async generator tests have been accidentally fixed while
converting the implementation to the new bytecode format. It didn't
seem useful to preserve bugs in the original code when converting it.

Some "does eval() return the correct completion value" tests have
regressed, in particular ones related to propagating the appropriate
completion after control flow statements like continue and break.
These are all fairly obscure issues, and I believe we can continue
working on them separately.

The net test262 result is a progression though. :^)
2024-02-19 21:45:27 +01: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
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
Stephan Vedder
84eecbb10e LibJS/JIT: Add fastpath for set variable 2023-11-19 22:36:07 +01:00
Idan Horowitz
f19349e1b6 LibJS: Instantiate primitive array expressions using a single operation
This will not meaningfully affect short array literals, but it does
give us a bit of extra perf when evaluating huge array expressions like
in Kraken/imaging-darkroom.js
2023-11-18 08:37:34 +01:00
Simon Wanner
86b85aa68b LibJS: Introduce Builtins
Builtins are functions that can be detected during bytecode generation
and enable fast-paths in the JIT.
2023-11-17 19:06:25 +01:00
Andreas Kling
cfdb8a2756 LibJS/JIT: Update "unwind context" stack in JIT code
Until now, the unwind context stack has not been maintained by jitted
code, which meant we were unable to support the `with` statement.
This is a first step towards supporting that by making jitted code
call out to C++ to update the unwind context stack when entering/leaving
unwind contexts.

We also introduce a new "Catch" bytecode instruction that moves the
current exception into the accumulator. It's always emitted at the start
of a "catch" block.
2023-11-12 14:21:41 +01:00
Andreas Kling
298dfa96a4 LibJS: Remove unused members from EnterUnwindContext instruction 2023-11-12 14:21:41 +01:00
Andreas Kling
b6435ca280 LibJS: Unify bytecode instruction names with their helper names 2023-11-12 14:21:41 +01:00
Andreas Kling
b1b2ca1485 LibJS: Add basic monomorphic caching for PutById property access
This patch makes it possible for JS::Object::internal_set() to populate
a CacheablePropertyMetadata, and uses this to implement a basic
monomorphic cache for the most common form of property write access.
2023-11-09 16:02:14 +01:00
Simon Wanner
dd466ec83a LibJS/Bytecode: Remove the PushDeclarativeEnvironment instruction 2023-11-03 07:31:11 +01:00
Simon Wanner
a2b0154661 LibJS/JIT: Compile the AsyncIteratorClose instruction 2023-10-30 07:10:24 +01:00
Simon Wanner
ac59e982a9 LibJS/JIT: Compile the CopyObjectExcludingProperties instruction 2023-10-30 07:10:24 +01:00
Simon Wanner
9494fbe670 LibJS/JIT: Compile the PutByValueWithThis instruction 2023-10-30 07:10:24 +01:00
Simon Wanner
847889343f LibJS/JIT: Compile the New##ErrorName instructions 2023-10-30 07:10:24 +01:00
Simon Wanner
a16082c6a5 LibJS/JIT: Compile the HasPrivateId instruction 2023-10-30 07:10:24 +01:00
Simon Wanner
19045d6431 LibJS/JIT: Compile the GetMethod instruction 2023-10-30 07:10:24 +01:00
Simon Wanner
c0c40110c1 LibJS/JIT: Compile the ImportCall instruction 2023-10-30 07:10:24 +01:00
Simon Wanner
ac43d3f6db LibJS/JIT: Compile the PutPrivateById instruction 2023-10-29 22:57:19 +01:00
Simon Wanner
81697549b7 LibJS/JIT: Compile the PutByIdWithThis instruction 2023-10-29 22:57:19 +01:00
Simon Wanner
38d5d7979b LibJS/JIT: Compile the DeleteByIdWithThis instruction 2023-10-29 22:57:19 +01:00
Simon Wanner
b53277110e LibJS/JIT: Compile the GetByValueWithThis instruction 2023-10-29 22:57:19 +01:00
Simon Wanner
569ca57e22 LibJS/JIT: Compile the GetByIdWithThis instruction 2023-10-29 22:57:19 +01:00
Simon Wanner
4e9edb8c53 LibJS/JIT: Compile the GetPrivateById instruction 2023-10-29 22:57:19 +01:00
Jakub Berkop
6a7b9b85a4 LibJS/JIT: Compile the DeleteByValueWithThis instruction 2023-10-29 21:51:46 +01:00
Jakub Berkop
0776404e03 LibJS/JIT: Compile the DeleteByValue instruction 2023-10-29 21:51:46 +01:00
Jakub Berkop
f5fcd4596c LibJS/JIT: Compile the DeleteById instruction 2023-10-29 21:51:46 +01:00
Simon Wanner
40064d872f LibJS/JIT: Compile the Append instruction 2023-10-29 17:36:09 +01:00
Simon Wanner
c697ff61f6 LibJS/JIT: Compile the IteratorClose instruction 2023-10-29 17:36:09 +01:00
Simon Wanner
4f8f8b7792 LibJS/JIT: Compile the GetIterator instruction 2023-10-29 17:36:09 +01:00
Simon Wanner
d247744a3e LibJS/JIT: Compile the SuperCallWithArgumentArray instruction 2023-10-29 17:36:09 +01:00
Simon Wanner
09dce5f1bd LibJS/JIT: Compile the BlockDeclarationInstantiation instruction 2023-10-29 17:36:09 +01:00
Simon Wanner
4b23a7dfb4 LibJS/JIT: Compile the NewClass bytecode instruction 2023-10-29 07:44:11 +01:00
Simon Wanner
224f92f6e4 LibJS/JIT: Compile the CreateVariable bytecode instruction 2023-10-29 07:44:11 +01:00
Simon Wanner
1d3062de9e LibJS/JIT: Compile the ConcatString bytecode instruction 2023-10-29 07:44:11 +01:00
Idan Horowitz
2b65a80ecb LibJS: Compile the NewBigInt bytecode instruction 2023-10-28 20:27:16 +02:00