Instead of emitting the lengthy exception checking/handling routine,
we only emit code for checking the presence of an exception and jump
to a common exception handler.
This code size optimization saves 2.08MiB on Kraken/ai-astar.js
This allows us to use the displacement-less MOV encoding when accessing
register $0 (the accumulator).
This reduces code size by 158 KiB on Kraken/ai-astar.js :^)
Instead of JIT::Assembler making the decision for everyone and forcing
out every caller-saved register in the ABI onto the stack, we now leave
that decision to users of JIT::Assembler.
Instead of emitting the "restore callee-saved registers and return"
sequence again and again, just emit it once at the end of the generated
code, and have everyone jump to it.
This is a code size optimization that saves 207KiB on Kraken/ai-astar.js
Compiler now has a BasicBlockData struct for each BasicBlock. The struct
contains all the stuff that we previously stored with the
Bytecode::BasicBlock.
This uses a new branch_if_both_int32() helper.
It's interesting to note that we can compare encoded Int32 values
without stripping the INT32_TAG, since it doesn't affect signedness
of values.
This necessitated making the JIT::Compiler aware of the current
Bytecode::Executable, since that's where all the string literals are
held, but that seems like a good thing.
These push a "valid" unwind context on the stack and check_exception()
now knows how to jump to the (catch) handler if present.
(finally) finalizers will require some more work, but with this change,
we now have basic support for try...catch. :^)
We now establish a stack of "unwind contexts" similar to what the
bytecode interpreter does, but here, it's a stack of structs with
addresses to the catch and finally blocks.
Unwind contexts also have a "valid" flag, and the root unwind context
(always present, pushed on JIT code entry) has valid=false, which we
interpret in check_exception() as "return and let our caller deal with
the exception".
Anything in Compiler that may generate an exception should now also
call check_exception() ASAP to emit the code for handling this.