ZJIT: Restore SP register after JIT-to-JIT call (#13882)

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Stan Lo <stan.lo@shopify.com>
This commit is contained in:
Takashi Kokubun 2025-07-14 12:22:13 -07:00 committed by GitHub
parent b2a7b76992
commit e288a86692
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 1 deletions

View file

@ -757,7 +757,8 @@ fn gen_send_without_block_direct(
asm_comment!(asm, "switch to new SP register");
let local_size = unsafe { get_iseq_body_local_table_size(iseq) } as usize;
let new_sp = asm.add(SP, ((state.stack().len() + local_size - args.len() + VM_ENV_DATA_SIZE as usize) * SIZEOF_VALUE).into());
let sp_offset = (state.stack().len() + local_size - args.len() + VM_ENV_DATA_SIZE as usize) * SIZEOF_VALUE;
let new_sp = asm.add(SP, sp_offset.into());
asm.mov(SP, new_sp);
asm_comment!(asm, "switch to new CFP");
@ -780,9 +781,14 @@ fn gen_send_without_block_direct(
// If a callee side-exits, i.e. returns Qundef, propagate the return value to the caller.
// The caller will side-exit the callee into the interpreter.
// TODO: Let side exit code pop all JIT frames to optimize away this cmp + je.
asm_comment!(asm, "side-exit if callee side-exits");
asm.cmp(ret, Qundef.into());
asm.je(ZJITState::get_exit_trampoline().into());
asm_comment!(asm, "restore SP register for the caller");
let new_sp = asm.sub(SP, sp_offset.into());
asm.mov(SP, new_sp);
Some(ret)
}