diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-11-30 08:23:25 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-30 11:23:25 -0500 |
commit | d048bae96b4108104cd0e77aad44962a39a5796f (patch) | |
tree | 2de85174d336a277b1a9e556516463025d161d0b /yjit | |
parent | f193f96d31ffcd02d91f135ba765d92c23b52c55 (diff) |
YJIT: Bump ec->cfp after setting cfp->jit_return (#9072)
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/codegen.rs | 29 | ||||
-rw-r--r-- | yjit/src/core.rs | 3 |
2 files changed, 16 insertions, 16 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 41133e771f..8f0980f9ab 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -5216,13 +5216,12 @@ struct ControlFrame { // * Provided sp should point to the new frame's sp, immediately following locals and the environment // * At entry, CFP points to the caller (not callee) frame // * At exit, ec->cfp is updated to the pushed CFP -// * CFP and SP registers are updated only if set_sp_cfp is set +// * SP register is updated only if frame.iseq is set // * Stack overflow is not checked (should be done by the caller) // * Interrupts are not checked (should be done by the caller) fn gen_push_frame( jit: &mut JITState, asm: &mut Assembler, - set_sp_cfp: bool, // if true CFP and SP will be switched to the callee frame: ControlFrame, ) { let sp = frame.sp; @@ -5314,7 +5313,7 @@ fn gen_push_frame( asm.mov(cfp_opnd(RUBY_OFFSET_CFP_SELF), frame.recv); asm.mov(cfp_opnd(RUBY_OFFSET_CFP_BLOCK_CODE), 0.into()); - if set_sp_cfp { + if frame.iseq.is_some() { // Spill stack temps to let the callee use them (must be done before changing the SP register) asm.spill_temps(); @@ -5324,16 +5323,6 @@ fn gen_push_frame( } let ep = asm.sub(sp, SIZEOF_VALUE.into()); asm.mov(cfp_opnd(RUBY_OFFSET_CFP_EP), ep); - - let new_cfp = asm.lea(cfp_opnd(0)); - if set_sp_cfp { - asm_comment!(asm, "switch to new CFP"); - asm.mov(CFP, new_cfp); - asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP); - } else { - asm_comment!(asm, "set ec->cfp"); - asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), new_cfp); - } } fn gen_send_cfunc( @@ -5561,7 +5550,7 @@ fn gen_send_cfunc( frame_type |= VM_FRAME_FLAG_CFRAME_KW } - gen_push_frame(jit, asm, false, ControlFrame { + gen_push_frame(jit, asm, ControlFrame { frame_type, specval, cme, @@ -5575,6 +5564,10 @@ fn gen_send_cfunc( iseq: None, }); + asm_comment!(asm, "set ec->cfp"); + let new_cfp = asm.lea(Opnd::mem(64, CFP, -(RUBY_SIZEOF_CONTROL_FRAME as i32))); + asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), new_cfp); + if !kw_arg.is_null() { // Build a hash from all kwargs passed asm_comment!(asm, "build_kwhash"); @@ -6659,7 +6652,7 @@ fn gen_send_iseq( }; // Setup the new frame - gen_push_frame(jit, asm, true, ControlFrame { + gen_push_frame(jit, asm, ControlFrame { frame_type, specval, cme, @@ -6721,6 +6714,12 @@ fn gen_send_iseq( BranchGenFn::JITReturn, ); + // ec->cfp is updated after cfp->jit_return for rb_profile_frames() safety + asm_comment!(asm, "switch to new CFP"); + let new_cfp = asm.sub(CFP, RUBY_SIZEOF_CONTROL_FRAME.into()); + asm.mov(CFP, new_cfp); + asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP); + // Directly jump to the entry point of the callee gen_direct_jump( jit, diff --git a/yjit/src/core.rs b/yjit/src/core.rs index 0ab154d118..e6210a2283 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -569,8 +569,9 @@ impl BranchGenFn { } BranchGenFn::JITReturn => { asm_comment!(asm, "update cfp->jit_return"); + let jit_return = RUBY_OFFSET_CFP_JIT_RETURN - RUBY_SIZEOF_CONTROL_FRAME as i32; let raw_ptr = asm.lea_jump_target(target0); - asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), raw_ptr); + asm.mov(Opnd::mem(64, CFP, jit_return), raw_ptr); } } } |