LibJS/JIT: Consolidate exception handling code

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 commit is contained in:
Simon Wanner 2023-10-28 18:08:20 +02:00 committed by Andreas Kling
parent 202a08ecc2
commit 2cbc9d6970
2 changed files with 16 additions and 8 deletions

View file

@ -319,14 +319,18 @@ void Compiler::compile_decrement(Bytecode::Op::Decrement const&)
void Compiler::check_exception()
{
// if (exception.is_empty()) goto no_exception;
// if (!exception.is_empty()) goto m_exception_handler;
load_vm_register(GPR0, Bytecode::Register::exception());
m_assembler.mov(Assembler::Operand::Register(GPR1), Assembler::Operand::Imm(Value().encoded()));
auto no_exception = m_assembler.make_label();
m_assembler.jump_if_equal(Assembler::Operand::Register(GPR0), Assembler::Operand::Register(GPR1), no_exception);
// We have an exception!
m_assembler.jump_if_not_equal(
Assembler::Operand::Register(GPR0),
Assembler::Operand::Register(GPR1),
m_exception_handler
);
}
void Compiler::handle_exception()
{
// if (!unwind_context.valid) return;
Assembler::Label handle_exception {};
m_assembler.mov(
@ -382,9 +386,6 @@ void Compiler::check_exception()
// NOTE: No catch and no finally!? Crash.
no_finalizer.link(m_assembler);
m_assembler.verify_not_reached();
// no_exception:
no_exception.link(m_assembler);
}
void Compiler::push_unwind_context(bool valid, Optional<Bytecode::Label> const& handler, Optional<Bytecode::Label> const& finalizer)
@ -1219,6 +1220,11 @@ OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable& bytecode_execut
compiler.m_exit_label.link(compiler.m_assembler);
compiler.m_assembler.exit();
if (!compiler.m_exception_handler.jump_slot_offsets_in_instruction_stream.is_empty()) {
compiler.m_exception_handler.link(compiler.m_assembler);
compiler.handle_exception();
}
auto* executable_memory = mmap(nullptr, compiler.m_output.size(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (executable_memory == MAP_FAILED) {
dbgln("mmap: {}", strerror(errno));

View file

@ -125,6 +125,7 @@ private:
void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src);
void check_exception();
void handle_exception();
void push_unwind_context(bool valid, Optional<Bytecode::Label> const& handler, Optional<Bytecode::Label> const& finalizer);
void pop_unwind_context();
@ -167,6 +168,7 @@ private:
Vector<u8> m_output;
Assembler m_assembler { m_output };
Assembler::Label m_exit_label;
Assembler::Label m_exception_handler;
Bytecode::Executable& m_bytecode_executable;
};