mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-07 08:29:58 +00:00
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:
parent
202a08ecc2
commit
2cbc9d6970
|
@ -319,14 +319,18 @@ void Compiler::compile_decrement(Bytecode::Op::Decrement const&)
|
||||||
|
|
||||||
void Compiler::check_exception()
|
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());
|
load_vm_register(GPR0, Bytecode::Register::exception());
|
||||||
m_assembler.mov(Assembler::Operand::Register(GPR1), Assembler::Operand::Imm(Value().encoded()));
|
m_assembler.mov(Assembler::Operand::Register(GPR1), Assembler::Operand::Imm(Value().encoded()));
|
||||||
auto no_exception = m_assembler.make_label();
|
m_assembler.jump_if_not_equal(
|
||||||
m_assembler.jump_if_equal(Assembler::Operand::Register(GPR0), Assembler::Operand::Register(GPR1), no_exception);
|
Assembler::Operand::Register(GPR0),
|
||||||
|
Assembler::Operand::Register(GPR1),
|
||||||
// We have an exception!
|
m_exception_handler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::handle_exception()
|
||||||
|
{
|
||||||
// if (!unwind_context.valid) return;
|
// if (!unwind_context.valid) return;
|
||||||
Assembler::Label handle_exception {};
|
Assembler::Label handle_exception {};
|
||||||
m_assembler.mov(
|
m_assembler.mov(
|
||||||
|
@ -382,9 +386,6 @@ void Compiler::check_exception()
|
||||||
// NOTE: No catch and no finally!? Crash.
|
// NOTE: No catch and no finally!? Crash.
|
||||||
no_finalizer.link(m_assembler);
|
no_finalizer.link(m_assembler);
|
||||||
m_assembler.verify_not_reached();
|
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)
|
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_exit_label.link(compiler.m_assembler);
|
||||||
compiler.m_assembler.exit();
|
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);
|
auto* executable_memory = mmap(nullptr, compiler.m_output.size(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
|
||||||
if (executable_memory == MAP_FAILED) {
|
if (executable_memory == MAP_FAILED) {
|
||||||
dbgln("mmap: {}", strerror(errno));
|
dbgln("mmap: {}", strerror(errno));
|
||||||
|
|
|
@ -125,6 +125,7 @@ private:
|
||||||
void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src);
|
void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src);
|
||||||
|
|
||||||
void check_exception();
|
void check_exception();
|
||||||
|
void handle_exception();
|
||||||
|
|
||||||
void push_unwind_context(bool valid, Optional<Bytecode::Label> const& handler, Optional<Bytecode::Label> const& finalizer);
|
void push_unwind_context(bool valid, Optional<Bytecode::Label> const& handler, Optional<Bytecode::Label> const& finalizer);
|
||||||
void pop_unwind_context();
|
void pop_unwind_context();
|
||||||
|
@ -167,6 +168,7 @@ private:
|
||||||
Vector<u8> m_output;
|
Vector<u8> m_output;
|
||||||
Assembler m_assembler { m_output };
|
Assembler m_assembler { m_output };
|
||||||
Assembler::Label m_exit_label;
|
Assembler::Label m_exit_label;
|
||||||
|
Assembler::Label m_exception_handler;
|
||||||
Bytecode::Executable& m_bytecode_executable;
|
Bytecode::Executable& m_bytecode_executable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue