diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index e93422496b..87fc27342d 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -367,7 +367,10 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable& executa vm().execution_context_stack().last()->executable = &executable; if (auto native_executable = executable.get_or_create_native_executable()) { - native_executable->run(vm()); + auto block_index = 0; + if (entry_point) + block_index = executable.basic_blocks.find_first_index_if([&](auto const& block) { return block.ptr() == entry_point; }).value(); + native_executable->run(vm(), block_index); #if 0 for (size_t i = 0; i < vm().running_execution_context().local_variables.size(); ++i) { diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index 9bdf46f5ff..0e02788381 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -1736,11 +1736,32 @@ OwnPtr Compiler::compile(Bytecode::Executable& bytecode_execut compiler.reload_cached_accumulator(); + Assembler::Label normal_entry {}; + + compiler.m_assembler.jump_if( + Assembler::Operand::Register(ARG3), + Assembler::Condition::EqualTo, + Assembler::Operand::Imm(0), + normal_entry); + + compiler.m_assembler.jump(Assembler::Operand::Register(ARG3)); + + normal_entry.link(compiler.m_assembler); + for (size_t block_index = 0; block_index < bytecode_executable.basic_blocks.size(); block_index++) { auto& block = bytecode_executable.basic_blocks[block_index]; compiler.block_data_for(*block).start_offset = compiler.m_output.size(); compiler.set_current_block(*block); auto it = Bytecode::InstructionStreamIterator(block->instruction_stream()); + + if (it.at_end()) { + mapping.append({ + .native_offset = compiler.m_output.size(), + .block_index = block_index, + .bytecode_offset = 0, + }); + } + while (!it.at_end()) { auto const& op = *it; diff --git a/Userland/Libraries/LibJS/JIT/NativeExecutable.cpp b/Userland/Libraries/LibJS/JIT/NativeExecutable.cpp index a6d0137c2b..9981be13e4 100644 --- a/Userland/Libraries/LibJS/JIT/NativeExecutable.cpp +++ b/Userland/Libraries/LibJS/JIT/NativeExecutable.cpp @@ -19,6 +19,15 @@ NativeExecutable::NativeExecutable(void* code, size_t size, Vector(m_code) + entry.native_offset); + } + } } NativeExecutable::~NativeExecutable() @@ -26,12 +35,19 @@ NativeExecutable::~NativeExecutable() munmap(m_code, m_size); } -void NativeExecutable::run(VM& vm) const +void NativeExecutable::run(VM& vm, size_t entry_point) const { - typedef void (*JITCode)(VM&, Value* registers, Value* locals); + FlatPtr entry_point_address = 0; + if (entry_point != 0) { + entry_point_address = m_block_entry_points[entry_point]; + VERIFY(entry_point_address != 0); + } + + typedef void (*JITCode)(VM&, Value* registers, Value* locals, FlatPtr entry_point_address); ((JITCode)m_code)(vm, vm.bytecode_interpreter().registers().data(), - vm.running_execution_context().local_variables.data()); + vm.running_execution_context().local_variables.data(), + entry_point_address); } #if ARCH(X86_64) diff --git a/Userland/Libraries/LibJS/JIT/NativeExecutable.h b/Userland/Libraries/LibJS/JIT/NativeExecutable.h index 62003b15fb..9111934fd4 100644 --- a/Userland/Libraries/LibJS/JIT/NativeExecutable.h +++ b/Userland/Libraries/LibJS/JIT/NativeExecutable.h @@ -31,7 +31,7 @@ public: NativeExecutable(void* code, size_t size, Vector); ~NativeExecutable(); - void run(VM&) const; + void run(VM&, size_t entry_point) const; void dump_disassembly(Bytecode::Executable const& executable) const; BytecodeMapping const& find_mapping_entry(size_t native_offset) const; Optional get_source_range(Bytecode::Executable const& executable, FlatPtr address) const; @@ -42,6 +42,7 @@ private: void* m_code { nullptr }; size_t m_size { 0 }; Vector m_mapping; + Vector m_block_entry_points; mutable OwnPtr m_instruction_stream_iterator; };