Skip to content

Commit db3d82b

Browse files
committed
ZJIT: Guide WB skipping for Insn::SetLocal using HIR type info
1 parent 7f398a3 commit db3d82b

File tree

2 files changed

+12
-14
lines changed

2 files changed

+12
-14
lines changed

zjit/src/codegen.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
370370
Insn::SetGlobal { id, val, state } => return gen_setglobal(jit, asm, *id, opnd!(val), &function.frame_state(*state)),
371371
Insn::GetGlobal { id, state: _ } => gen_getglobal(asm, *id),
372372
&Insn::GetLocal { ep_offset, level } => gen_getlocal_with_ep(asm, ep_offset, level)?,
373-
Insn::SetLocal { val, ep_offset, level } => return gen_setlocal_with_ep(asm, opnd!(val), *ep_offset, *level),
373+
&Insn::SetLocal { val, ep_offset, level } => return gen_setlocal_with_ep(asm, jit, function, val, ep_offset, level),
374374
Insn::GetConstantPath { ic, state } => gen_get_constant_path(jit, asm, *ic, &function.frame_state(*state))?,
375375
Insn::SetIvar { self_val, id, val, state: _ } => return gen_setivar(asm, opnd!(self_val), *id, opnd!(val)),
376376
Insn::SideExit { state, reason } => return gen_side_exit(jit, asm, reason, &function.frame_state(*state)),
@@ -507,21 +507,19 @@ fn gen_getlocal_with_ep(asm: &mut Assembler, local_ep_offset: u32, level: u32) -
507507
/// Set a local variable from a higher scope or the heap. `local_ep_offset` is in number of VALUEs.
508508
/// We generate this instruction with level=0 only when the local variable is on the heap, so we
509509
/// can't optimize the level=0 case using the SP register.
510-
fn gen_setlocal_with_ep(asm: &mut Assembler, val: Opnd, local_ep_offset: u32, level: u32) -> Option<()> {
510+
fn gen_setlocal_with_ep(asm: &mut Assembler, jit: &JITState, function: &Function, val: InsnId, local_ep_offset: u32, level: u32) -> Option<()> {
511511
let ep = gen_get_ep(asm, level);
512-
match val {
513-
// If we're writing a constant, non-heap VALUE, do a raw memory write without
514-
// running write barrier.
515-
lir::Opnd::Value(const_val) if const_val.special_const_p() => {
516-
let offset = -(SIZEOF_VALUE_I32 * i32::try_from(local_ep_offset).ok()?);
517-
asm.mov(Opnd::mem(64, ep, offset), val);
518-
}
512+
513+
// When we've proved that we're writing an immediate,
514+
// we can skip the write barrier.
515+
if function.type_of(val).is_immediate() {
516+
let offset = -(SIZEOF_VALUE_I32 * i32::try_from(local_ep_offset).ok()?);
517+
asm.mov(Opnd::mem(64, ep, offset), jit.get_opnd(val)?);
518+
} else {
519519
// We're potentially writing a reference to an IMEMO/env object,
520520
// so take care of the write barrier with a function.
521-
_ => {
522-
let local_index = c_int::try_from(local_ep_offset).ok().and_then(|idx| idx.checked_mul(-1))?;
523-
asm_ccall!(asm, rb_vm_env_write, ep, local_index.into(), val);
524-
}
521+
let local_index = c_int::try_from(local_ep_offset).ok().and_then(|idx| idx.checked_mul(-1))?;
522+
asm_ccall!(asm, rb_vm_env_write, ep, local_index.into(), jit.get_opnd(val)?);
525523
}
526524
Some(())
527525
}

zjit/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ impl Function {
12641264
self.union_find.borrow_mut().make_equal_to(insn, replacement);
12651265
}
12661266

1267-
fn type_of(&self, insn: InsnId) -> Type {
1267+
pub fn type_of(&self, insn: InsnId) -> Type {
12681268
assert!(self.insns[insn.0].has_output());
12691269
self.insn_types[self.union_find.borrow_mut().find(insn).0]
12701270
}

0 commit comments

Comments
 (0)