YJIT: Bump ec->cfp after setting cfp->jit_return (#9072)
This commit is contained in:
parent
f193f96d31
commit
d048bae96b
@ -5216,13 +5216,12 @@ struct ControlFrame {
|
|||||||
// * Provided sp should point to the new frame's sp, immediately following locals and the environment
|
// * 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 entry, CFP points to the caller (not callee) frame
|
||||||
// * At exit, ec->cfp is updated to the pushed CFP
|
// * 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)
|
// * Stack overflow is not checked (should be done by the caller)
|
||||||
// * Interrupts are not checked (should be done by the caller)
|
// * Interrupts are not checked (should be done by the caller)
|
||||||
fn gen_push_frame(
|
fn gen_push_frame(
|
||||||
jit: &mut JITState,
|
jit: &mut JITState,
|
||||||
asm: &mut Assembler,
|
asm: &mut Assembler,
|
||||||
set_sp_cfp: bool, // if true CFP and SP will be switched to the callee
|
|
||||||
frame: ControlFrame,
|
frame: ControlFrame,
|
||||||
) {
|
) {
|
||||||
let sp = frame.sp;
|
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_SELF), frame.recv);
|
||||||
asm.mov(cfp_opnd(RUBY_OFFSET_CFP_BLOCK_CODE), 0.into());
|
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)
|
// Spill stack temps to let the callee use them (must be done before changing the SP register)
|
||||||
asm.spill_temps();
|
asm.spill_temps();
|
||||||
|
|
||||||
@ -5324,16 +5323,6 @@ fn gen_push_frame(
|
|||||||
}
|
}
|
||||||
let ep = asm.sub(sp, SIZEOF_VALUE.into());
|
let ep = asm.sub(sp, SIZEOF_VALUE.into());
|
||||||
asm.mov(cfp_opnd(RUBY_OFFSET_CFP_EP), ep);
|
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(
|
fn gen_send_cfunc(
|
||||||
@ -5561,7 +5550,7 @@ fn gen_send_cfunc(
|
|||||||
frame_type |= VM_FRAME_FLAG_CFRAME_KW
|
frame_type |= VM_FRAME_FLAG_CFRAME_KW
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_push_frame(jit, asm, false, ControlFrame {
|
gen_push_frame(jit, asm, ControlFrame {
|
||||||
frame_type,
|
frame_type,
|
||||||
specval,
|
specval,
|
||||||
cme,
|
cme,
|
||||||
@ -5575,6 +5564,10 @@ fn gen_send_cfunc(
|
|||||||
iseq: None,
|
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() {
|
if !kw_arg.is_null() {
|
||||||
// Build a hash from all kwargs passed
|
// Build a hash from all kwargs passed
|
||||||
asm_comment!(asm, "build_kwhash");
|
asm_comment!(asm, "build_kwhash");
|
||||||
@ -6659,7 +6652,7 @@ fn gen_send_iseq(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup the new frame
|
// Setup the new frame
|
||||||
gen_push_frame(jit, asm, true, ControlFrame {
|
gen_push_frame(jit, asm, ControlFrame {
|
||||||
frame_type,
|
frame_type,
|
||||||
specval,
|
specval,
|
||||||
cme,
|
cme,
|
||||||
@ -6721,6 +6714,12 @@ fn gen_send_iseq(
|
|||||||
BranchGenFn::JITReturn,
|
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
|
// Directly jump to the entry point of the callee
|
||||||
gen_direct_jump(
|
gen_direct_jump(
|
||||||
jit,
|
jit,
|
||||||
|
@ -569,8 +569,9 @@ impl BranchGenFn {
|
|||||||
}
|
}
|
||||||
BranchGenFn::JITReturn => {
|
BranchGenFn::JITReturn => {
|
||||||
asm_comment!(asm, "update cfp->jit_return");
|
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);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user