diff options
| author | Takashi Kokubun <takashi.kokubun@shopify.com> | 2025-08-29 11:43:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-29 11:43:33 -0700 |
| commit | 39f3cab80d7b469793a1a3cf091ed875c54c3c86 (patch) | |
| tree | 9df776d3a6841ea873db9ebd257b8775531a662d | |
| parent | 99bf47ab8c3fc4332b7324310615af147a4da560 (diff) | |
YJIT: Stop sharing rb_vm_send among different instructions (#14393)
| -rw-r--r-- | vm_insnhelper.c | 27 | ||||
| -rw-r--r-- | yjit/src/codegen.rs | 19 |
2 files changed, 32 insertions, 14 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 0fb4d086b7..eee20cd9d4 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -6095,25 +6095,26 @@ VALUE rb_vm_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd, ISEQ blockiseq) { stack_check(ec); + VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false); + VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); + VM_EXEC(ec, val); + return val; +} + +VALUE +rb_vm_sendforward(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd, ISEQ blockiseq) +{ + stack_check(ec); struct rb_forwarding_call_data adjusted_cd; struct rb_callinfo adjusted_ci; - VALUE bh; - VALUE val; - - if (vm_ci_flag(cd->ci) & VM_CALL_FORWARDING) { - bh = vm_caller_setup_fwd_args(GET_EC(), GET_CFP(), cd, blockiseq, false, &adjusted_cd, &adjusted_ci); + VALUE bh = vm_caller_setup_fwd_args(GET_EC(), GET_CFP(), cd, blockiseq, false, &adjusted_cd, &adjusted_ci); - val = vm_sendish(ec, GET_CFP(), &adjusted_cd.cd, bh, mexp_search_method); + VALUE val = vm_sendish(ec, GET_CFP(), &adjusted_cd.cd, bh, mexp_search_method); - if (cd->cc != adjusted_cd.cd.cc && vm_cc_markable(adjusted_cd.cd.cc)) { - RB_OBJ_WRITE(GET_ISEQ(), &cd->cc, adjusted_cd.cd.cc); - } - } - else { - bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false); - val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); + if (cd->cc != adjusted_cd.cd.cc && vm_cc_markable(adjusted_cd.cd.cc)) { + RB_OBJ_WRITE(GET_ISEQ(), &cd->cc, adjusted_cd.cd.cc); } VM_EXEC(ec, val); diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 9e9759e781..8b472efdfd 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -9564,7 +9564,24 @@ fn gen_sendforward( jit: &mut JITState, asm: &mut Assembler, ) -> Option<CodegenStatus> { - return gen_send(jit, asm); + // Generate specialized code if possible + let cd = jit.get_arg(0).as_ptr(); + let block = jit.get_arg(1).as_optional_ptr().map(|iseq| BlockHandler::BlockISeq(iseq)); + if let Some(status) = perf_call! { gen_send_general(jit, asm, cd, block) } { + return Some(status); + } + + // Otherwise, fallback to dynamic dispatch using the interpreter's implementation of sendforward + let blockiseq = jit.get_arg(1).as_iseq(); + gen_send_dynamic(jit, asm, cd, unsafe { rb_yjit_sendish_sp_pops((*cd).ci) }, |asm| { + extern "C" { + fn rb_vm_sendforward(ec: EcPtr, cfp: CfpPtr, cd: VALUE, blockiseq: IseqPtr) -> VALUE; + } + asm.ccall( + rb_vm_sendforward as *const u8, + vec![EC, CFP, (cd as usize).into(), VALUE(blockiseq as usize).into()], + ) + }) } fn gen_invokeblock( |
