Skip to content

Commit d048bae

Browse files
authored
YJIT: Bump ec->cfp after setting cfp->jit_return (#9072)
1 parent f193f96 commit d048bae

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

yjit/src/codegen.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,13 +5216,12 @@ struct ControlFrame {
52165216
// * Provided sp should point to the new frame's sp, immediately following locals and the environment
52175217
// * At entry, CFP points to the caller (not callee) frame
52185218
// * At exit, ec->cfp is updated to the pushed CFP
5219-
// * CFP and SP registers are updated only if set_sp_cfp is set
5219+
// * SP register is updated only if frame.iseq is set
52205220
// * Stack overflow is not checked (should be done by the caller)
52215221
// * Interrupts are not checked (should be done by the caller)
52225222
fn gen_push_frame(
52235223
jit: &mut JITState,
52245224
asm: &mut Assembler,
5225-
set_sp_cfp: bool, // if true CFP and SP will be switched to the callee
52265225
frame: ControlFrame,
52275226
) {
52285227
let sp = frame.sp;
@@ -5314,7 +5313,7 @@ fn gen_push_frame(
53145313
asm.mov(cfp_opnd(RUBY_OFFSET_CFP_SELF), frame.recv);
53155314
asm.mov(cfp_opnd(RUBY_OFFSET_CFP_BLOCK_CODE), 0.into());
53165315

5317-
if set_sp_cfp {
5316+
if frame.iseq.is_some() {
53185317
// Spill stack temps to let the callee use them (must be done before changing the SP register)
53195318
asm.spill_temps();
53205319

@@ -5324,16 +5323,6 @@ fn gen_push_frame(
53245323
}
53255324
let ep = asm.sub(sp, SIZEOF_VALUE.into());
53265325
asm.mov(cfp_opnd(RUBY_OFFSET_CFP_EP), ep);
5327-
5328-
let new_cfp = asm.lea(cfp_opnd(0));
5329-
if set_sp_cfp {
5330-
asm_comment!(asm, "switch to new CFP");
5331-
asm.mov(CFP, new_cfp);
5332-
asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP);
5333-
} else {
5334-
asm_comment!(asm, "set ec->cfp");
5335-
asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), new_cfp);
5336-
}
53375326
}
53385327

53395328
fn gen_send_cfunc(
@@ -5561,7 +5550,7 @@ fn gen_send_cfunc(
55615550
frame_type |= VM_FRAME_FLAG_CFRAME_KW
55625551
}
55635552

5564-
gen_push_frame(jit, asm, false, ControlFrame {
5553+
gen_push_frame(jit, asm, ControlFrame {
55655554
frame_type,
55665555
specval,
55675556
cme,
@@ -5575,6 +5564,10 @@ fn gen_send_cfunc(
55755564
iseq: None,
55765565
});
55775566

5567+
asm_comment!(asm, "set ec->cfp");
5568+
let new_cfp = asm.lea(Opnd::mem(64, CFP, -(RUBY_SIZEOF_CONTROL_FRAME as i32)));
5569+
asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), new_cfp);
5570+
55785571
if !kw_arg.is_null() {
55795572
// Build a hash from all kwargs passed
55805573
asm_comment!(asm, "build_kwhash");
@@ -6659,7 +6652,7 @@ fn gen_send_iseq(
66596652
};
66606653

66616654
// Setup the new frame
6662-
gen_push_frame(jit, asm, true, ControlFrame {
6655+
gen_push_frame(jit, asm, ControlFrame {
66636656
frame_type,
66646657
specval,
66656658
cme,
@@ -6721,6 +6714,12 @@ fn gen_send_iseq(
67216714
BranchGenFn::JITReturn,
67226715
);
67236716

6717+
// ec->cfp is updated after cfp->jit_return for rb_profile_frames() safety
6718+
asm_comment!(asm, "switch to new CFP");
6719+
let new_cfp = asm.sub(CFP, RUBY_SIZEOF_CONTROL_FRAME.into());
6720+
asm.mov(CFP, new_cfp);
6721+
asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP);
6722+
67246723
// Directly jump to the entry point of the callee
67256724
gen_direct_jump(
67266725
jit,

yjit/src/core.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,9 @@ impl BranchGenFn {
569569
}
570570
BranchGenFn::JITReturn => {
571571
asm_comment!(asm, "update cfp->jit_return");
572+
let jit_return = RUBY_OFFSET_CFP_JIT_RETURN - RUBY_SIZEOF_CONTROL_FRAME as i32;
572573
let raw_ptr = asm.lea_jump_target(target0);
573-
asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), raw_ptr);
574+
asm.mov(Opnd::mem(64, CFP, jit_return), raw_ptr);
574575
}
575576
}
576577
}

0 commit comments

Comments
 (0)