Commit graph

21 commits

Author SHA1 Message Date
Hendiadyoin1
1341f4438d LibJS: Save scheduled jumps when entering unwind contexts
These are then restored upon `ContinuePendingUnwind`.
This stops us from forgetting where we needed to jump when we do extra
try-catches in finally blocks.

Co-Authored-By: Jesús "gsus" Lapastora <cyber.gsuscode@gmail.com>
2023-10-30 13:10:08 +01:00
Hendiadyoin1
f5645e3c9c LibJS: Use static unwind mappings for unwind related functions 2023-10-30 13:10:08 +01:00
Hendiadyoin1
73f347b75c LibJS: Create static unwind mappings for BasicBlocks
This is currently only used in the bytecode dump to annotate to where
unwinds lead per block, but will be hooked up to the virtual machine in
the next commit.
2023-10-30 13:10:08 +01:00
Andreas Kling
72c31fdd01 LibJS: Remove all interactions between Assembler and BasicBlock
With this change, Assembler is now free from LibJS concepts and could
move out to its own apartment. :^)
2023-10-27 19:07:22 +02:00
Andreas Kling
3523f9f722 LibJS/JIT: Add patchable absolute references to basic blocks 2023-10-27 19:07:22 +02:00
Andreas Kling
babdc0a25b LibJS: Work-in-progress JIT compiler :^) 2023-10-27 19:07:22 +02:00
Andreas Kling
d24e07579f LibJS: Use a Vector<u8> for BasicBlock instruction storage
This reduces the minimum size of a basic block from 4 KiB to 0 bytes.
With this change, memory usage at the end of Speedometer is 1.2 GiB,
down from 1.8 GiB.
2023-09-28 11:25:19 +02:00
Daniel Bertalan
e3f65f215d LibJS/Bytecode: Do not rethrow caught exception from finally
If the exception from the `try` block has already been caught by
`catch`, we need to clear the saved exception before entering `finally`
so that ContinuePendingUnwind will not re-throw it.

9 new passes on test262 :^)
2023-07-14 17:05:29 +02:00
Andreas Kling
dc884aa0d3 LibJS/Bytecode: Remove unnecessary variable environment stack
The var environments will unwind as needed with the ExecutionContext
and there's no need to include it in the unwind info.

We still need to do this for lexical environments though, since they
can have short local lifetimes inside a function.
2023-07-02 18:30:02 +02:00
Andreas Kling
fb979dcf34 LibJS/Bytecode: Make Bytecode::Interpreter participate in GC marking
Since the relationship between VM and Bytecode::Interpreter is now
clear, we can have VM ask the Interpreter for roots in the GC marking
pass. This avoids having to register and unregister handles and
MarkedVectors over and over.

Since GeneratorObject can also own a RegisterWindow, we share the code
in a RegisterWindow::visit_edges() helper.

~4% speed-up on Kraken/stanford-crypto-ccm.js :^)
2023-07-02 14:50:02 +02:00
Andreas Kling
ce634957c1 LibJS/Bytecode: Restore old environments when an exception is caught
Unwind contexts now remember the lexical and variable environments in
effect when they were created. If an exception is caught, we revert
to those environments in the running execution context.
2023-05-14 06:18:28 +02:00
Andreas Kling
21db2b7b90 Everywhere: Remove NonnullOwnPtr.h includes 2023-03-06 23:46:35 +01:00
Linus Groh
6e19ab2bbc AK+Everywhere: Rename String to DeprecatedString
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
2022-12-06 08:54:33 +01:00
Hendiadyoin1
192897c269 LibJS: Remeber which instruction terminated a block 2022-12-03 17:07:30 +03:30
Andreas Kling
d203a86900 LibJS: Always inline the bytecode instruction iterator's operator++ 2021-10-25 13:37:02 +02:00
Andreas Kling
3618ca2420 LibJS: Propagate exceptions across bytecode executable boundaries
To support situations like this:

    function foo() { throw 1; }

    try {
        foo();
    } catch (e) {
    }

Each unwind context now keeps track of its origin executable.

When an exception is thrown, we return from run() immediately if the
nearest unwind context isn't in the current executable.

This causes a natural unwind to the point where we find the
catch/finally block(s) to jump into.
2021-10-25 12:57:21 +02:00
Ali Mohammad Pur
e73b142a97 LibJS: Make basic block size customizable
And keep the default 4 KiB for the code generator.
2021-06-15 22:06:33 +04:30
Ali Mohammad Pur
4cfdfb6a88 LibJS: Automatically split linear bytecode into multiple blocks
...instead of crashing :^)
2021-06-11 00:30:09 +02:00
Gunnar Beutner
67cc31a74f LibJS: Implement bytecode generation for try..catch..finally
EnterUnwindContext pushes an unwind context (exception handler and/or
finalizer) onto a stack.

LeaveUnwindContext pops the unwind context from that stack.

Upon return to the interpreter loop we check whether the VM has an
exception pending. If no unwind context is available we return from the
loop. If an exception handler is available we clear the VM's exception,
put the exception value into the accumulator register, clear the unwind
context's handler and jump to the handler. If no handler is available
but a finalizer is available we save the exception value + metadata (for
 later use by ContinuePendingUnwind), clear the VM's exception, pop the
unwind context and jump to the finalizer.

ContinuePendingUnwind checks whether a saved exception is available. If
no saved exception is available it jumps to the resume label. Otherwise
it stores the exception into the VM.

The Jump after LeaveUnwindContext could be integrated into the
LeaveUnwindContext instruction. I've kept them separate for now to make
the bytecode more readable.

> try { 1; throw "x" } catch (e) { 2 } finally { 3 }; 4
1:
[   0] EnterScope
[  10] EnterUnwindContext handler:@4 finalizer:@3
[  38] EnterScope
[  48] LoadImmediate 1
[  60] NewString 1 ("x")
[  70] Throw
<for non-terminated blocks: insert LeaveUnwindContext + Jump @3 here>
2:
[   0] LoadImmediate 4
3:
[   0] EnterScope
[  10] LoadImmediate 3
[  28] ContinuePendingUnwind resume:@2
4:
[   0] SetVariable 0 (e)
[  10] EnterScope
[  20] LoadImmediate 2
[  38] LeaveUnwindContext
[  3c] Jump @3

String Table:
0: e
1: x
2021-06-10 21:59:46 +02:00
Gunnar Beutner
6a0d1fa259 LibJS: Store strings in a string table
Instead of using Strings in the bytecode ops this adds a global string
table to the Executable struct which individual operations can refer
to using indices. This brings bytecode ops one step closer to being
pointer free.
2021-06-09 17:42:52 +02:00
Ali Mohammad Pur
01e8f0889a LibJS: Generate bytecode in basic blocks instead of one big block
This limits the size of each block (currently set to 1K), and gets us
closer to a canonical, more easily analysable bytecode format.
As a result of this, "Labels" are now simply entries to basic blocks.
Since there is no more 'conditional' jump (as all jumps are always
taken), JumpIf{True,False} are unified to JumpConditional, and
JumpIfNullish is renamed to JumpNullish.
Also fixes #7914 as a result of reimplementing the loop logic.
2021-06-09 09:07:29 +02:00
Renamed from Userland/Libraries/LibJS/Bytecode/Block.h (Browse further)