Skip to content

Commit 6e2906f

Browse files
committed
ZJIT: Don't make GuardNotFrozen consider immediates
1 parent e31c256 commit 6e2906f

File tree

3 files changed

+9
-11
lines changed

3 files changed

+9
-11
lines changed

zjit/src/codegen.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -654,20 +654,12 @@ fn gen_guard_block_param_proxy(jit: &JITState, asm: &mut Assembler, level: u32,
654654
}
655655

656656
fn gen_guard_not_frozen(jit: &JITState, asm: &mut Assembler, recv: Opnd, state: &FrameState) -> Opnd {
657-
let side_exit = side_exit(jit, state, GuardNotFrozen);
658657
let recv = asm.load(recv);
659-
// Side-exit if recv is false
660-
assert_eq!(Qfalse.as_i64(), 0);
661-
asm.test(recv, recv);
662-
asm.jz(side_exit.clone());
663-
// Side-exit if recv is immediate
664-
asm.test(recv, (RUBY_IMMEDIATE_MASK as u64).into());
665-
asm.jnz(side_exit.clone());
666658
// It's a heap object, so check the frozen flag
667659
let flags = asm.load(Opnd::mem(64, recv, RUBY_OFFSET_RBASIC_FLAGS));
668660
asm.test(flags, (RUBY_FL_FREEZE as u64).into());
669661
// Side-exit if frozen
670-
asm.jnz(side_exit.clone());
662+
asm.jnz(side_exit(jit, state, GuardNotFrozen));
671663
recv
672664
}
673665

zjit/src/cruby_methods.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ fn inline_array_push(fun: &mut hir::Function, block: hir::BlockId, recv: hir::In
330330
fn inline_array_pop(fun: &mut hir::Function, block: hir::BlockId, recv: hir::InsnId, args: &[hir::InsnId], state: hir::InsnId) -> Option<hir::InsnId> {
331331
// Only inline the case of no arguments.
332332
let &[] = args else { return None; };
333+
// We know that all Array are HeapObject, so no need to insert a GuardType(HeapObject).
333334
let arr = fun.push_insn(block, hir::Insn::GuardNotFrozen { recv, state });
334335
Some(fun.push_insn(block, hir::Insn::ArrayPop { array: arr, state }))
335336
}
@@ -391,6 +392,7 @@ fn inline_string_setbyte(fun: &mut hir::Function, block: hir::BlockId, recv: hir
391392
let unboxed_index = fun.push_insn(block, hir::Insn::GuardLess { left: unboxed_index, right: len, state });
392393
let zero = fun.push_insn(block, hir::Insn::Const { val: hir::Const::CInt64(0) });
393394
let _ = fun.push_insn(block, hir::Insn::GuardGreaterEq { left: unboxed_index, right: zero, state });
395+
// We know that all String are HeapObject, so no need to insert a GuardType(HeapObject).
394396
let recv = fun.push_insn(block, hir::Insn::GuardNotFrozen { recv, state });
395397
let _ = fun.push_insn(block, hir::Insn::StringSetbyteFixnum { string: recv, index, value });
396398
// String#setbyte returns the fixnum provided as its `value` argument back to the caller.

zjit/src/hir.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,8 @@ pub enum Insn {
903903
/// Side-exit if the block param has been modified or the block handler for the frame
904904
/// is neither ISEQ nor ifunc, which makes it incompatible with rb_block_param_proxy.
905905
GuardBlockParamProxy { level: u32, state: InsnId },
906-
/// Side-exit if val is frozen.
906+
/// Side-exit if val is frozen. Does *not* check if the val is an immediate; assumes that it is
907+
/// a heap object.
907908
GuardNotFrozen { recv: InsnId, state: InsnId },
908909
/// Side-exit if left is not greater than or equal to right (both operands are C long).
909910
GuardGreaterEq { left: InsnId, right: InsnId, state: InsnId },
@@ -2553,6 +2554,7 @@ impl Function {
25532554
//
25542555
// No need for a GuardShape.
25552556
if let OptimizedMethodType::StructAset = opt_type {
2557+
// We know that all Struct are HeapObject, so no need to insert a GuardType(HeapObject).
25562558
recv = self.push_insn(block, Insn::GuardNotFrozen { recv, state });
25572559
}
25582560

@@ -4150,7 +4152,6 @@ impl Function {
41504152
| Insn::IsNil { val }
41514153
| Insn::IsMethodCfunc { val, .. }
41524154
| Insn::GuardShape { val, .. }
4153-
| Insn::GuardNotFrozen { recv: val, .. }
41544155
| Insn::SetGlobal { val, .. }
41554156
| Insn::SetLocal { val, .. }
41564157
| Insn::SetClassVar { val, .. }
@@ -4169,6 +4170,9 @@ impl Function {
41694170
| Insn::DefinedIvar { self_val: val, .. } => {
41704171
self.assert_subtype(insn_id, val, types::BasicObject)
41714172
}
4173+
Insn::GuardNotFrozen { recv, .. } => {
4174+
self.assert_subtype(insn_id, recv, types::HeapBasicObject)
4175+
}
41724176
// Instructions with 2 Ruby object operands
41734177
Insn::SetIvar { self_val: left, val: right, .. }
41744178
| Insn::NewRange { low: left, high: right, .. }

0 commit comments

Comments
 (0)