Skip to content

Commit 2ca2865

Browse files
authored
ZJIT: Remove eager nil-fill of locals in JIT-to-JIT calls (ruby#16544)
The caller in gen_send_iseq_direct was eagerly writing Qnil to all non-parameter local slots of the callee's frame before every JIT-to-JIT call. This is unnecessary because compile_jit_entry_state already initializes non-parameter locals to Const(Qnil) in the JIT entry block, and these values are propagated to the target block via branch edges. Before any non-leaf call (including eval/binding), gen_spill_locals writes these nil values from the FrameState to the stack, ensuring that eval can correctly read uninitialized locals as nil. The nil-fill in function_stub_hit's prepare_for_exit is kept because that path handles compilation failures where JIT code never runs.
1 parent ff89d56 commit 2ca2865

File tree

1 file changed

+1
-11
lines changed

1 file changed

+1
-11
lines changed

zjit/src/codegen.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,16 +1619,6 @@ fn gen_send_iseq_direct(
16191619
0
16201620
};
16211621

1622-
// Fill non-parameter locals with nil (they may be read by eval before being written)
1623-
let num_params = params.size.to_usize();
1624-
if local_size > num_params {
1625-
asm_comment!(asm, "initialize non-parameter locals to nil");
1626-
for local_idx in num_params..local_size {
1627-
let offset = local_size_and_idx_to_bp_offset(local_size, local_idx);
1628-
asm.store(Opnd::mem(64, SP, -offset * SIZEOF_VALUE_I32), Qnil.into());
1629-
}
1630-
}
1631-
16321622
// Make a method call. The target address will be rewritten once compiled.
16331623
let iseq_call = IseqCall::new(iseq, num_optionals_passed);
16341624
let dummy_ptr = cb.get_write_ptr().raw_ptr(cb);
@@ -2876,7 +2866,7 @@ c_callable! {
28762866
let pc = unsafe { rb_iseq_pc_at_idx(iseq, entry_insn_idxs[iseq_call.jit_entry_idx.to_usize()]) };
28772867
unsafe { rb_set_cfp_pc(cfp, pc) };
28782868

2879-
// Successful JIT-to-JIT calls fill nils to non-parameter locals in generated code.
2869+
// JIT-to-JIT calls don't eagerly fill nils to non-parameter locals.
28802870
// If we side-exit from function_stub_hit (before JIT code runs), we need to set them here.
28812871
fn prepare_for_exit(iseq: IseqPtr, cfp: CfpPtr, sp: *mut VALUE, compile_error: &CompileError) {
28822872
unsafe {

0 commit comments

Comments
 (0)