@@ -106,8 +106,7 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, jit_exception: boo
106106 }
107107
108108 // Always mark the code region executable if asm.compile() has been used.
109- // We need to do this even if code_ptr is None because, whether gen_entry()
110- // fails or not, gen_iseq() may have already used asm.compile().
109+ // We need to do this even if code_ptr is None because gen_iseq() may have already used asm.compile().
111110 cb. mark_all_executable ( ) ;
112111
113112 code_ptr. map_or ( std:: ptr:: null ( ) , |ptr| ptr. raw_ptr ( cb) )
@@ -131,10 +130,7 @@ fn gen_iseq_entry_point(cb: &mut CodeBlock, iseq: IseqPtr, jit_exception: bool)
131130 debug ! ( "{err:?}: gen_iseq failed: {}" , iseq_get_location( iseq, 0 ) ) ;
132131 } ) ?;
133132
134- // Compile an entry point to the JIT code
135- gen_entry ( cb, iseq, start_ptr) . inspect_err ( |err| {
136- debug ! ( "{err:?}: gen_entry failed: {}" , iseq_get_location( iseq, 0 ) ) ;
137- } )
133+ Ok ( start_ptr)
138134}
139135
140136/// Stub a branch for a JIT-to-JIT call
@@ -170,14 +166,16 @@ fn register_with_perf(iseq_name: String, start_ptr: usize, code_size: usize) {
170166 } ;
171167}
172168
173- /// Compile a JIT entry
174- fn gen_entry ( cb : & mut CodeBlock , iseq : IseqPtr , function_ptr : CodePtr ) -> Result < CodePtr , CompileError > {
169+ /// Compile a shared JIT entry trampoline
170+ pub fn gen_entry_trampoline ( cb : & mut CodeBlock ) -> Result < CodePtr , CompileError > {
175171 // Set up registers for CFP, EC, SP, and basic block arguments
176172 let mut asm = Assembler :: new ( ) ;
177- gen_entry_prologue ( & mut asm, iseq ) ;
173+ gen_entry_prologue ( & mut asm) ;
178174
179- // Jump to the first block using a call instruction
180- asm. ccall ( function_ptr. raw_ptr ( cb) , vec ! [ ] ) ;
175+ // Jump to the first block using a call instruction. This trampoline is used
176+ // as rb_zjit_func_t in jit_exec(), which takes (EC, CFP, rb_jit_func_t).
177+ // So C_ARG_OPNDS[2] is rb_jit_func_t, which is (EC, CFP) -> VALUE.
178+ asm. ccall_reg ( C_ARG_OPNDS [ 2 ] , VALUE_BITS ) ;
181179
182180 // Restore registers for CFP, EC, and SP after use
183181 asm_comment ! ( asm, "return to the interpreter" ) ;
@@ -190,8 +188,7 @@ fn gen_entry(cb: &mut CodeBlock, iseq: IseqPtr, function_ptr: CodePtr) -> Result
190188 let start_ptr = code_ptr. raw_addr ( cb) ;
191189 let end_ptr = cb. get_write_ptr ( ) . raw_addr ( cb) ;
192190 let code_size = end_ptr - start_ptr;
193- let iseq_name = iseq_get_location ( iseq, 0 ) ;
194- register_with_perf ( format ! ( "entry for {iseq_name}" ) , start_ptr, code_size) ;
191+ register_with_perf ( "ZJIT entry trampoline" . into ( ) , start_ptr, code_size) ;
195192 }
196193 Ok ( code_ptr)
197194}
@@ -990,8 +987,8 @@ fn gen_load_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32) -> Opnd
990987}
991988
992989/// Compile an interpreter entry block to be inserted into an ISEQ
993- fn gen_entry_prologue ( asm : & mut Assembler , iseq : IseqPtr ) {
994- asm_comment ! ( asm, "ZJIT entry point: {}" , iseq_get_location ( iseq , 0 ) ) ;
990+ fn gen_entry_prologue ( asm : & mut Assembler ) {
991+ asm_comment ! ( asm, "ZJIT entry trampoline" ) ;
995992 // Save the registers we'll use for CFP, EP, SP
996993 asm. frame_setup ( lir:: JIT_PRESERVED_REGS ) ;
997994
0 commit comments