Skip to content

Commit 9f5476a

Browse files
committed
ZJIT: Fix CFP restore after SendDirect and add CLIF IR dumping
Reload CFP from EC after callee returns (the callee pops its frame). Fix max_num_params to account for LoadArg slots, not just block params. Add --zjit-dump-lir support to print Cranelift IR before compilation.
1 parent 111df6b commit 9f5476a

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

zjit/src/backend/cranelift_backend.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ impl CraneliftBuilder {
154154
/// Compile the built function and copy the machine code into the CodeBlock.
155155
/// Returns the start CodePtr and GC offsets (empty since we use value pool).
156156
pub fn compile(self, cb: &mut CodeBlock) -> Result<(CodePtr, Vec<CodePtr>), CompileError> {
157+
// Dump Cranelift IR if --zjit-dump-lir is set
158+
if crate::options::get_option!(dump_lir).is_some() {
159+
eprintln!("=== Cranelift IR ===");
160+
eprintln!("{}", self.func.display());
161+
eprintln!("===================");
162+
}
163+
157164
let mut ctx = Context::for_function(self.func);
158165

159166
ctx.compile(&*self.isa, &mut Default::default())

zjit/src/codegen.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -946,9 +946,14 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, version: IseqVersionRef, func
946946
builder.switch_to_block(exit_block);
947947
builder.ins().return_(&[qundef]);
948948

949-
// Continue block: restore SP
949+
// Continue block: restore CFP and SP
950950
builder.seal_block(cont_block);
951951
builder.switch_to_block(cont_block);
952+
// Reload CFP from EC (callee popped its frame)
953+
let ec_after = builder.use_var(ec_var);
954+
let restored_cfp = builder.ins().load(cl_types::I64, MemFlags::trusted(), ec_after, Offset32::new(RUBY_OFFSET_EC_CFP as i32));
955+
builder.def_var(cfp_var, restored_cfp);
956+
// Restore SP
952957
let restored_sp = builder.ins().iadd_imm(callee_sp, -(sp_offset_bytes));
953958
builder.def_var(sp_var, restored_sp);
954959

@@ -3577,7 +3582,16 @@ fn max_num_params(function: &Function) -> usize {
35773582
let reverse_post_order = function.rpo();
35783583
reverse_post_order.iter().map(|&block_id| {
35793584
let block = function.block(block_id);
3580-
block.params().len()
3585+
// Count block params AND LoadArg slots (they share the same ABI param space)
3586+
let block_param_count = block.params().len();
3587+
let max_load_arg = block.insns().filter_map(|&insn_id| {
3588+
if let Insn::LoadArg { idx, .. } = function.find(insn_id) {
3589+
Some(idx as usize + 1)
3590+
} else {
3591+
None
3592+
}
3593+
}).max().unwrap_or(0);
3594+
block_param_count.max(max_load_arg)
35813595
}).max().unwrap_or(0)
35823596
}
35833597

0 commit comments

Comments
 (0)