YJIT: Bump ec->cfp after setting cfp->jit_return (#9072)

This commit is contained in:
Takashi Kokubun 2023-11-30 08:23:25 -08:00 коммит произвёл GitHub
Родитель f193f96d31
Коммит d048bae96b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 16 добавлений и 16 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);
}
}
}