mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 12:14:51 +00:00
ZJIT: Replace GuardShape with LoadField+GuardBitEquals (#15821)
GuardShape is just load+guard, so use the existing HIR instructions for load+guard. Probably makes future analysis slightly easier.
This commit is contained in:
parent
16863f2ec1
commit
523857bfcb
Notes:
git
2026-01-08 19:58:24 +00:00
Merged-By: tekknolagi <donotemailthisaddress@bernsteinbear.com>
@ -449,7 +449,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
|
||||
Insn::Test { val } => gen_test(asm, opnd!(val)),
|
||||
Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
|
||||
Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
|
||||
Insn::GuardBitEquals { val, expected, state } => gen_guard_bit_equals(jit, asm, opnd!(val), *expected, &function.frame_state(*state)),
|
||||
&Insn::GuardBitEquals { val, expected, reason, state } => gen_guard_bit_equals(jit, asm, opnd!(val), expected, reason, &function.frame_state(state)),
|
||||
&Insn::GuardBlockParamProxy { level, state } => no_output!(gen_guard_block_param_proxy(jit, asm, level, &function.frame_state(state))),
|
||||
Insn::GuardNotFrozen { recv, state } => gen_guard_not_frozen(jit, asm, opnd!(recv), &function.frame_state(*state)),
|
||||
Insn::GuardNotShared { recv, state } => gen_guard_not_shared(jit, asm, opnd!(recv), &function.frame_state(*state)),
|
||||
@ -498,7 +498,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
|
||||
Insn::LoadPC => gen_load_pc(asm),
|
||||
Insn::LoadEC => gen_load_ec(),
|
||||
Insn::LoadSelf => gen_load_self(),
|
||||
&Insn::LoadField { recv, id, offset, return_type: _ } => gen_load_field(asm, opnd!(recv), id, offset),
|
||||
&Insn::LoadField { recv, id, offset, return_type } => gen_load_field(asm, opnd!(recv), id, offset, return_type),
|
||||
&Insn::StoreField { recv, id, offset, val } => no_output!(gen_store_field(asm, opnd!(recv), id, offset, opnd!(val), function.type_of(val))),
|
||||
&Insn::WriteBarrier { recv, val } => no_output!(gen_write_barrier(asm, opnd!(recv), opnd!(val), function.type_of(val))),
|
||||
&Insn::IsBlockGiven => gen_is_block_given(jit, asm),
|
||||
@ -1130,10 +1130,10 @@ fn gen_load_self() -> Opnd {
|
||||
Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SELF)
|
||||
}
|
||||
|
||||
fn gen_load_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32) -> Opnd {
|
||||
fn gen_load_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32, return_type: Type) -> Opnd {
|
||||
asm_comment!(asm, "Load field id={} offset={}", id.contents_lossy(), offset);
|
||||
let recv = asm.load(recv);
|
||||
asm.load(Opnd::mem(64, recv, offset))
|
||||
asm.load(Opnd::mem(return_type.num_bits(), recv, offset))
|
||||
}
|
||||
|
||||
fn gen_store_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32, val: Opnd, val_type: Type) {
|
||||
@ -2083,14 +2083,15 @@ fn gen_guard_type_not(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, g
|
||||
}
|
||||
|
||||
/// Compile an identity check with a side exit
|
||||
fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, state: &FrameState) -> lir::Opnd {
|
||||
fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, reason: SideExitReason, state: &FrameState) -> lir::Opnd {
|
||||
let expected_opnd: Opnd = match expected {
|
||||
crate::hir::Const::Value(v) => { Opnd::Value(v) }
|
||||
crate::hir::Const::CInt64(v) => { v.into() }
|
||||
crate::hir::Const::CShape(v) => { Opnd::UImm(v.0 as u64) }
|
||||
_ => panic!("gen_guard_bit_equals: unexpected hir::Const {expected:?}"),
|
||||
};
|
||||
asm.cmp(val, expected_opnd);
|
||||
asm.jnz(side_exit(jit, state, GuardBitEquals(expected)));
|
||||
asm.jnz(side_exit(jit, state, reason));
|
||||
val
|
||||
}
|
||||
|
||||
|
||||
@ -491,7 +491,7 @@ pub enum SideExitReason {
|
||||
GuardType(Type),
|
||||
GuardTypeNot(Type),
|
||||
GuardShape(ShapeId),
|
||||
GuardBitEquals(Const),
|
||||
ExpandArray,
|
||||
GuardNotFrozen,
|
||||
GuardNotShared,
|
||||
GuardLess,
|
||||
@ -580,7 +580,6 @@ impl std::fmt::Display for SideExitReason {
|
||||
SideExitReason::UnhandledDuparraySend(method_id) => write!(f, "UnhandledDuparraySend({method_id})"),
|
||||
SideExitReason::GuardType(guard_type) => write!(f, "GuardType({guard_type})"),
|
||||
SideExitReason::GuardTypeNot(guard_type) => write!(f, "GuardTypeNot({guard_type})"),
|
||||
SideExitReason::GuardBitEquals(value) => write!(f, "GuardBitEquals({})", value.print(&PtrPrintMap::identity())),
|
||||
SideExitReason::GuardNotShared => write!(f, "GuardNotShared"),
|
||||
SideExitReason::PatchPoint(invariant) => write!(f, "PatchPoint({invariant})"),
|
||||
_ => write!(f, "{self:?}"),
|
||||
@ -954,7 +953,7 @@ pub enum Insn {
|
||||
GuardType { val: InsnId, guard_type: Type, state: InsnId },
|
||||
GuardTypeNot { val: InsnId, guard_type: Type, state: InsnId },
|
||||
/// Side-exit if val is not the expected Const.
|
||||
GuardBitEquals { val: InsnId, expected: Const, state: InsnId },
|
||||
GuardBitEquals { val: InsnId, expected: Const, reason: SideExitReason, state: InsnId },
|
||||
/// Side-exit if val doesn't have the expected shape.
|
||||
GuardShape { val: InsnId, shape: ShapeId, state: InsnId },
|
||||
/// Side-exit if the block param has been modified or the block handler for the frame
|
||||
@ -1975,7 +1974,7 @@ impl Function {
|
||||
&IfFalse { val, ref target } => IfFalse { val: find!(val), target: find_branch_edge!(target) },
|
||||
&GuardType { val, guard_type, state } => GuardType { val: find!(val), guard_type, state },
|
||||
&GuardTypeNot { val, guard_type, state } => GuardTypeNot { val: find!(val), guard_type, state },
|
||||
&GuardBitEquals { val, expected, state } => GuardBitEquals { val: find!(val), expected, state },
|
||||
&GuardBitEquals { val, expected, reason, state } => GuardBitEquals { val: find!(val), expected, reason, state },
|
||||
&GuardShape { val, shape, state } => GuardShape { val: find!(val), shape, state },
|
||||
&GuardBlockParamProxy { level, state } => GuardBlockParamProxy { level, state: find!(state) },
|
||||
&GuardNotFrozen { recv, state } => GuardNotFrozen { recv: find!(recv), state },
|
||||
@ -3069,6 +3068,24 @@ impl Function {
|
||||
self.infer_types();
|
||||
}
|
||||
|
||||
fn load_shape(&mut self, block: BlockId, recv: InsnId) -> InsnId {
|
||||
self.push_insn(block, Insn::LoadField {
|
||||
recv,
|
||||
id: ID!(_shape_id),
|
||||
offset: unsafe { rb_shape_id_offset() } as i32,
|
||||
return_type: types::CShape
|
||||
})
|
||||
}
|
||||
|
||||
fn guard_shape(&mut self, block: BlockId, val: InsnId, expected: ShapeId, state: InsnId) -> InsnId {
|
||||
self.push_insn(block, Insn::GuardBitEquals {
|
||||
val,
|
||||
expected: Const::CShape(expected),
|
||||
reason: SideExitReason::GuardShape(expected),
|
||||
state
|
||||
})
|
||||
}
|
||||
|
||||
fn optimize_getivar(&mut self) {
|
||||
for block in self.rpo() {
|
||||
let old_insns = std::mem::take(&mut self.blocks[block.0].insns);
|
||||
@ -3094,7 +3111,8 @@ impl Function {
|
||||
self.push_insn_id(block, insn_id); continue;
|
||||
}
|
||||
let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state });
|
||||
let self_val = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state });
|
||||
let shape = self.load_shape(block, self_val);
|
||||
self.guard_shape(block, shape, recv_type.shape(), state);
|
||||
let mut ivar_index: u16 = 0;
|
||||
let replacement = if ! unsafe { rb_shape_get_iv_index(recv_type.shape().0, id, &mut ivar_index) } {
|
||||
// If there is no IVAR index, then the ivar was undefined when we
|
||||
@ -3148,7 +3166,8 @@ impl Function {
|
||||
self.push_insn_id(block, insn_id); continue;
|
||||
}
|
||||
let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state });
|
||||
let _ = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state });
|
||||
let shape = self.load_shape(block, self_val);
|
||||
self.guard_shape(block, shape, recv_type.shape(), state);
|
||||
let mut ivar_index: u16 = 0;
|
||||
let replacement = if unsafe { rb_shape_get_iv_index(recv_type.shape().0, id, &mut ivar_index) } {
|
||||
self.push_insn(block, Insn::Const { val: Const::Value(pushval) })
|
||||
@ -3219,7 +3238,8 @@ impl Function {
|
||||
// Fall through to emitting the ivar write
|
||||
}
|
||||
let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state });
|
||||
let self_val = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state });
|
||||
let shape = self.load_shape(block, self_val);
|
||||
self.guard_shape(block, shape, recv_type.shape(), state);
|
||||
// Current shape contains this ivar
|
||||
let (ivar_storage, offset) = if recv_type.flags().is_embedded() {
|
||||
// See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h
|
||||
@ -6261,7 +6281,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
||||
let val = state.stack_pop()?;
|
||||
let array = fun.push_insn(block, Insn::GuardType { val, guard_type: types::ArrayExact, state: exit_id, });
|
||||
let length = fun.push_insn(block, Insn::ArrayLength { array });
|
||||
fun.push_insn(block, Insn::GuardBitEquals { val: length, expected: Const::CInt64(num as i64), state: exit_id });
|
||||
fun.push_insn(block, Insn::GuardBitEquals { val: length, expected: Const::CInt64(num as i64), reason: SideExitReason::ExpandArray, state: exit_id });
|
||||
for i in (0..num).rev() {
|
||||
// TODO(max): Add a short-cut path for long indices into an array where the
|
||||
// index is known to be in-bounds
|
||||
|
||||
@ -3677,10 +3677,11 @@ mod hir_opt_tests {
|
||||
Jump bb2(v4)
|
||||
bb2(v6:BasicObject):
|
||||
v15:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v16:HeapBasicObject = GuardShape v15, 0x1000
|
||||
v17:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
v16:CShape = LoadField v15, :_shape_id@0x1000
|
||||
v17:CShape[0x1001] = GuardBitEquals v16, CShape(0x1001)
|
||||
v18:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
CheckInterrupts
|
||||
Return v17
|
||||
Return v18
|
||||
");
|
||||
}
|
||||
|
||||
@ -3701,10 +3702,11 @@ mod hir_opt_tests {
|
||||
Jump bb2(v4)
|
||||
bb2(v6:BasicObject):
|
||||
v15:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v16:HeapBasicObject = GuardShape v15, 0x1000
|
||||
v17:NilClass = Const Value(nil)
|
||||
v16:CShape = LoadField v15, :_shape_id@0x1000
|
||||
v17:CShape[0x1001] = GuardBitEquals v16, CShape(0x1001)
|
||||
v18:NilClass = Const Value(nil)
|
||||
CheckInterrupts
|
||||
Return v17
|
||||
Return v18
|
||||
");
|
||||
}
|
||||
|
||||
@ -3821,9 +3823,10 @@ mod hir_opt_tests {
|
||||
v10:Fixnum[5] = Const Value(5)
|
||||
PatchPoint SingleRactorMode
|
||||
v19:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v20:HeapBasicObject = GuardShape v19, 0x1000
|
||||
StoreField v20, :@foo@0x1001, v10
|
||||
WriteBarrier v20, v10
|
||||
v20:CShape = LoadField v19, :_shape_id@0x1000
|
||||
v21:CShape[0x1001] = GuardBitEquals v20, CShape(0x1001)
|
||||
StoreField v19, :@foo@0x1002, v10
|
||||
WriteBarrier v19, v10
|
||||
CheckInterrupts
|
||||
Return v10
|
||||
");
|
||||
@ -3848,11 +3851,12 @@ mod hir_opt_tests {
|
||||
v10:Fixnum[5] = Const Value(5)
|
||||
PatchPoint SingleRactorMode
|
||||
v19:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v20:HeapBasicObject = GuardShape v19, 0x1000
|
||||
StoreField v20, :@foo@0x1001, v10
|
||||
WriteBarrier v20, v10
|
||||
v23:CShape[0x1002] = Const CShape(0x1002)
|
||||
StoreField v20, :_shape_id@0x1003, v23
|
||||
v20:CShape = LoadField v19, :_shape_id@0x1000
|
||||
v21:CShape[0x1001] = GuardBitEquals v20, CShape(0x1001)
|
||||
StoreField v19, :@foo@0x1002, v10
|
||||
WriteBarrier v19, v10
|
||||
v24:CShape[0x1003] = Const CShape(0x1003)
|
||||
StoreField v19, :_shape_id@0x1000, v24
|
||||
CheckInterrupts
|
||||
Return v10
|
||||
");
|
||||
@ -3880,19 +3884,21 @@ mod hir_opt_tests {
|
||||
v10:Fixnum[1] = Const Value(1)
|
||||
PatchPoint SingleRactorMode
|
||||
v25:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v26:HeapBasicObject = GuardShape v25, 0x1000
|
||||
StoreField v26, :@foo@0x1001, v10
|
||||
WriteBarrier v26, v10
|
||||
v29:CShape[0x1002] = Const CShape(0x1002)
|
||||
StoreField v26, :_shape_id@0x1003, v29
|
||||
v26:CShape = LoadField v25, :_shape_id@0x1000
|
||||
v27:CShape[0x1001] = GuardBitEquals v26, CShape(0x1001)
|
||||
StoreField v25, :@foo@0x1002, v10
|
||||
WriteBarrier v25, v10
|
||||
v30:CShape[0x1003] = Const CShape(0x1003)
|
||||
StoreField v25, :_shape_id@0x1000, v30
|
||||
v16:Fixnum[2] = Const Value(2)
|
||||
PatchPoint SingleRactorMode
|
||||
v31:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v32:HeapBasicObject = GuardShape v31, 0x1002
|
||||
v32:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v33:CShape = LoadField v32, :_shape_id@0x1000
|
||||
v34:CShape[0x1003] = GuardBitEquals v33, CShape(0x1003)
|
||||
StoreField v32, :@bar@0x1004, v16
|
||||
WriteBarrier v32, v16
|
||||
v35:CShape[0x1005] = Const CShape(0x1005)
|
||||
StoreField v32, :_shape_id@0x1003, v35
|
||||
v37:CShape[0x1005] = Const CShape(0x1005)
|
||||
StoreField v32, :_shape_id@0x1000, v37
|
||||
CheckInterrupts
|
||||
Return v16
|
||||
");
|
||||
@ -5611,10 +5617,11 @@ mod hir_opt_tests {
|
||||
PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010)
|
||||
PatchPoint NoSingletonClass(C@0x1000)
|
||||
v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
|
||||
v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038
|
||||
v25:BasicObject = LoadField v24, :@foo@0x1039
|
||||
v24:CShape = LoadField v21, :_shape_id@0x1038
|
||||
v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039)
|
||||
v26:BasicObject = LoadField v21, :@foo@0x103a
|
||||
CheckInterrupts
|
||||
Return v25
|
||||
Return v26
|
||||
");
|
||||
}
|
||||
|
||||
@ -5650,11 +5657,12 @@ mod hir_opt_tests {
|
||||
PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010)
|
||||
PatchPoint NoSingletonClass(C@0x1000)
|
||||
v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
|
||||
v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038
|
||||
v25:CPtr = LoadField v24, :_as_heap@0x1039
|
||||
v26:BasicObject = LoadField v25, :@foo@0x103a
|
||||
v24:CShape = LoadField v21, :_shape_id@0x1038
|
||||
v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039)
|
||||
v26:CPtr = LoadField v21, :_as_heap@0x103a
|
||||
v27:BasicObject = LoadField v26, :@foo@0x103b
|
||||
CheckInterrupts
|
||||
Return v26
|
||||
Return v27
|
||||
");
|
||||
}
|
||||
|
||||
@ -5679,11 +5687,12 @@ mod hir_opt_tests {
|
||||
bb2(v6:BasicObject):
|
||||
PatchPoint SingleRactorMode
|
||||
v16:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v17:HeapBasicObject = GuardShape v16, 0x1000
|
||||
v18:CUInt16[0] = Const CUInt16(0)
|
||||
v19:BasicObject = CCall v17, :rb_ivar_get_at_no_ractor_check@0x1008, v18
|
||||
v17:CShape = LoadField v16, :_shape_id@0x1000
|
||||
v18:CShape[0x1001] = GuardBitEquals v17, CShape(0x1001)
|
||||
v19:CUInt16[0] = Const CUInt16(0)
|
||||
v20:BasicObject = CCall v16, :rb_ivar_get_at_no_ractor_check@0x1008, v19
|
||||
CheckInterrupts
|
||||
Return v19
|
||||
Return v20
|
||||
");
|
||||
}
|
||||
|
||||
@ -5708,11 +5717,12 @@ mod hir_opt_tests {
|
||||
bb2(v6:BasicObject):
|
||||
PatchPoint SingleRactorMode
|
||||
v16:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v17:HeapBasicObject = GuardShape v16, 0x1000
|
||||
v18:CUInt16[0] = Const CUInt16(0)
|
||||
v19:BasicObject = CCall v17, :rb_ivar_get_at_no_ractor_check@0x1008, v18
|
||||
v17:CShape = LoadField v16, :_shape_id@0x1000
|
||||
v18:CShape[0x1001] = GuardBitEquals v17, CShape(0x1001)
|
||||
v19:CUInt16[0] = Const CUInt16(0)
|
||||
v20:BasicObject = CCall v16, :rb_ivar_get_at_no_ractor_check@0x1008, v19
|
||||
CheckInterrupts
|
||||
Return v19
|
||||
Return v20
|
||||
");
|
||||
}
|
||||
|
||||
@ -5739,11 +5749,12 @@ mod hir_opt_tests {
|
||||
bb2(v6:BasicObject):
|
||||
PatchPoint SingleRactorMode
|
||||
v16:HeapBasicObject = GuardType v6, HeapBasicObject
|
||||
v17:HeapBasicObject = GuardShape v16, 0x1000
|
||||
v18:CUInt16[0] = Const CUInt16(0)
|
||||
v19:BasicObject = CCall v17, :rb_ivar_get_at_no_ractor_check@0x1008, v18
|
||||
v17:CShape = LoadField v16, :_shape_id@0x1000
|
||||
v18:CShape[0x1001] = GuardBitEquals v17, CShape(0x1001)
|
||||
v19:CUInt16[0] = Const CUInt16(0)
|
||||
v20:BasicObject = CCall v16, :rb_ivar_get_at_no_ractor_check@0x1008, v19
|
||||
CheckInterrupts
|
||||
Return v19
|
||||
Return v20
|
||||
");
|
||||
}
|
||||
|
||||
@ -6030,10 +6041,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(C@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v26:NilClass = Const Value(nil)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v27:NilClass = Const Value(nil)
|
||||
CheckInterrupts
|
||||
Return v26
|
||||
Return v27
|
||||
");
|
||||
}
|
||||
|
||||
@ -6064,10 +6076,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(C@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v26:NilClass = Const Value(nil)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v27:NilClass = Const Value(nil)
|
||||
CheckInterrupts
|
||||
Return v26
|
||||
Return v27
|
||||
");
|
||||
}
|
||||
|
||||
@ -6096,10 +6109,11 @@ mod hir_opt_tests {
|
||||
PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010)
|
||||
PatchPoint NoSingletonClass(C@0x1000)
|
||||
v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
|
||||
v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038
|
||||
v25:NilClass = Const Value(nil)
|
||||
v24:CShape = LoadField v21, :_shape_id@0x1038
|
||||
v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039)
|
||||
v26:NilClass = Const Value(nil)
|
||||
CheckInterrupts
|
||||
Return v25
|
||||
Return v26
|
||||
");
|
||||
}
|
||||
|
||||
@ -6128,10 +6142,11 @@ mod hir_opt_tests {
|
||||
PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010)
|
||||
PatchPoint NoSingletonClass(C@0x1000)
|
||||
v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
|
||||
v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038
|
||||
v25:NilClass = Const Value(nil)
|
||||
v24:CShape = LoadField v21, :_shape_id@0x1038
|
||||
v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039)
|
||||
v26:NilClass = Const Value(nil)
|
||||
CheckInterrupts
|
||||
Return v25
|
||||
Return v26
|
||||
");
|
||||
}
|
||||
|
||||
@ -6160,11 +6175,12 @@ mod hir_opt_tests {
|
||||
v16:Fixnum[5] = Const Value(5)
|
||||
PatchPoint MethodRedefined(C@0x1000, foo=@0x1008, cme:0x1010)
|
||||
v26:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
|
||||
v29:HeapObject[class_exact:C] = GuardShape v26, 0x1038
|
||||
StoreField v29, :@foo@0x1039, v16
|
||||
WriteBarrier v29, v16
|
||||
v32:CShape[0x103a] = Const CShape(0x103a)
|
||||
StoreField v29, :_shape_id@0x103b, v32
|
||||
v29:CShape = LoadField v26, :_shape_id@0x1038
|
||||
v30:CShape[0x1039] = GuardBitEquals v29, CShape(0x1039)
|
||||
StoreField v26, :@foo@0x103a, v16
|
||||
WriteBarrier v26, v16
|
||||
v33:CShape[0x103b] = Const CShape(0x103b)
|
||||
StoreField v26, :_shape_id@0x1038, v33
|
||||
CheckInterrupts
|
||||
Return v16
|
||||
");
|
||||
@ -6195,11 +6211,12 @@ mod hir_opt_tests {
|
||||
v16:Fixnum[5] = Const Value(5)
|
||||
PatchPoint MethodRedefined(C@0x1000, foo=@0x1008, cme:0x1010)
|
||||
v26:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
|
||||
v29:HeapObject[class_exact:C] = GuardShape v26, 0x1038
|
||||
StoreField v29, :@foo@0x1039, v16
|
||||
WriteBarrier v29, v16
|
||||
v32:CShape[0x103a] = Const CShape(0x103a)
|
||||
StoreField v29, :_shape_id@0x103b, v32
|
||||
v29:CShape = LoadField v26, :_shape_id@0x1038
|
||||
v30:CShape[0x1039] = GuardBitEquals v29, CShape(0x1039)
|
||||
StoreField v26, :@foo@0x103a, v16
|
||||
WriteBarrier v26, v16
|
||||
v33:CShape[0x103b] = Const CShape(0x103b)
|
||||
StoreField v26, :_shape_id@0x1038, v33
|
||||
CheckInterrupts
|
||||
Return v16
|
||||
");
|
||||
@ -9752,21 +9769,22 @@ mod hir_opt_tests {
|
||||
SetLocal :formatted, l0, EP@3, v15
|
||||
PatchPoint SingleRactorMode
|
||||
v54:HeapBasicObject = GuardType v14, HeapBasicObject
|
||||
v55:HeapBasicObject = GuardShape v54, 0x1000
|
||||
StoreField v55, :@formatted@0x1001, v15
|
||||
WriteBarrier v55, v15
|
||||
v58:CShape[0x1002] = Const CShape(0x1002)
|
||||
StoreField v55, :_shape_id@0x1003, v58
|
||||
v55:CShape = LoadField v54, :_shape_id@0x1000
|
||||
v56:CShape[0x1001] = GuardBitEquals v55, CShape(0x1001)
|
||||
StoreField v54, :@formatted@0x1002, v15
|
||||
WriteBarrier v54, v15
|
||||
v59:CShape[0x1003] = Const CShape(0x1003)
|
||||
StoreField v54, :_shape_id@0x1000, v59
|
||||
v43:Class[VMFrozenCore] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(Class@0x1010, lambda@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(Class@0x1010)
|
||||
v63:BasicObject = CCallWithFrame v43, :RubyVM::FrozenCore.lambda@0x1048, block=0x1050
|
||||
v64:BasicObject = CCallWithFrame v43, :RubyVM::FrozenCore.lambda@0x1048, block=0x1050
|
||||
v46:BasicObject = GetLocal :a, l0, EP@6
|
||||
v47:BasicObject = GetLocal :_b, l0, EP@5
|
||||
v48:BasicObject = GetLocal :_c, l0, EP@4
|
||||
v49:BasicObject = GetLocal :formatted, l0, EP@3
|
||||
CheckInterrupts
|
||||
Return v63
|
||||
Return v64
|
||||
");
|
||||
}
|
||||
|
||||
@ -9802,10 +9820,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestFrozen@0x1010, a@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestFrozen@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:Fixnum[1] = Const Value(1)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:Fixnum[1] = Const Value(1)
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -9843,10 +9862,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestMultiIvars@0x1010, b@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestMultiIvars@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:Fixnum[20] = Const Value(20)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:Fixnum[20] = Const Value(20)
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -9882,10 +9902,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestFrozenStr@0x1010, name@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestFrozenStr@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:StringExact[VALUE(0x1050)] = Const Value(VALUE(0x1050))
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:StringExact[VALUE(0x1050)] = Const Value(VALUE(0x1050))
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -9921,10 +9942,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestFrozenNil@0x1010, value@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestFrozenNil@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:NilClass = Const Value(nil)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:NilClass = Const Value(nil)
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -9960,10 +9982,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestUnfrozen@0x1010, a@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestUnfrozen@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v26:BasicObject = LoadField v25, :@a@0x1049
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v27:BasicObject = LoadField v20, :@a@0x104a
|
||||
CheckInterrupts
|
||||
Return v26
|
||||
Return v27
|
||||
");
|
||||
}
|
||||
|
||||
@ -9999,10 +10022,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestAttrReader@0x1010, value@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestAttrReader@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:Fixnum[42] = Const Value(42)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:Fixnum[42] = Const Value(42)
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -10038,10 +10062,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestFrozenSym@0x1010, sym@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestFrozenSym@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:StaticSymbol[:hello] = Const Value(VALUE(0x1050))
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:StaticSymbol[:hello] = Const Value(VALUE(0x1050))
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -10077,10 +10102,11 @@ mod hir_opt_tests {
|
||||
v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestFrozenBool@0x1010, flag@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestFrozenBool@0x1010)
|
||||
v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048
|
||||
v27:TrueClass = Const Value(true)
|
||||
v25:CShape = LoadField v20, :_shape_id@0x1048
|
||||
v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049)
|
||||
v28:TrueClass = Const Value(true)
|
||||
CheckInterrupts
|
||||
Return v27
|
||||
Return v28
|
||||
");
|
||||
}
|
||||
|
||||
@ -10114,10 +10140,11 @@ mod hir_opt_tests {
|
||||
PatchPoint MethodRedefined(TestDynamic@0x1000, val@0x1008, cme:0x1010)
|
||||
PatchPoint NoSingletonClass(TestDynamic@0x1000)
|
||||
v21:HeapObject[class_exact:TestDynamic] = GuardType v9, HeapObject[class_exact:TestDynamic]
|
||||
v24:HeapObject[class_exact:TestDynamic] = GuardShape v21, 0x1038
|
||||
v25:BasicObject = LoadField v24, :@val@0x1039
|
||||
v24:CShape = LoadField v21, :_shape_id@0x1038
|
||||
v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039)
|
||||
v26:BasicObject = LoadField v21, :@val@0x103a
|
||||
CheckInterrupts
|
||||
Return v25
|
||||
Return v26
|
||||
");
|
||||
}
|
||||
|
||||
@ -10154,20 +10181,22 @@ mod hir_opt_tests {
|
||||
v28:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestNestedAccess@0x1010, x@0x1018, cme:0x1020)
|
||||
PatchPoint NoSingletonClass(TestNestedAccess@0x1010)
|
||||
v39:HeapObject[VALUE(0x1008)] = GuardShape v28, 0x1048
|
||||
v50:Fixnum[100] = Const Value(100)
|
||||
v39:CShape = LoadField v28, :_shape_id@0x1048
|
||||
v40:CShape[0x1049] = GuardBitEquals v39, CShape(0x1049)
|
||||
v52:Fixnum[100] = Const Value(100)
|
||||
PatchPoint SingleRactorMode
|
||||
PatchPoint StableConstantNames(0x1050, NESTED_FROZEN)
|
||||
v34:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008))
|
||||
PatchPoint MethodRedefined(TestNestedAccess@0x1010, y@0x1058, cme:0x1060)
|
||||
PatchPoint NoSingletonClass(TestNestedAccess@0x1010)
|
||||
v42:HeapObject[VALUE(0x1008)] = GuardShape v34, 0x1048
|
||||
v51:Fixnum[200] = Const Value(200)
|
||||
v43:CShape = LoadField v34, :_shape_id@0x1048
|
||||
v44:CShape[0x1049] = GuardBitEquals v43, CShape(0x1049)
|
||||
v53:Fixnum[200] = Const Value(200)
|
||||
PatchPoint MethodRedefined(Integer@0x1088, +@0x1090, cme:0x1098)
|
||||
v52:Fixnum[300] = Const Value(300)
|
||||
v54:Fixnum[300] = Const Value(300)
|
||||
IncrCounter inline_cfunc_optimized_send_count
|
||||
CheckInterrupts
|
||||
Return v52
|
||||
Return v54
|
||||
");
|
||||
}
|
||||
|
||||
|
||||
@ -190,6 +190,7 @@ make_counters! {
|
||||
exit_guard_bit_equals_failure,
|
||||
exit_guard_int_equals_failure,
|
||||
exit_guard_shape_failure,
|
||||
exit_expandarray_failure,
|
||||
exit_guard_not_frozen_failure,
|
||||
exit_guard_not_shared_failure,
|
||||
exit_guard_less_failure,
|
||||
@ -509,8 +510,8 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter {
|
||||
BoxFixnumOverflow => exit_box_fixnum_overflow,
|
||||
GuardType(_) => exit_guard_type_failure,
|
||||
GuardTypeNot(_) => exit_guard_type_not_failure,
|
||||
GuardBitEquals(_) => exit_guard_bit_equals_failure,
|
||||
GuardShape(_) => exit_guard_shape_failure,
|
||||
ExpandArray => exit_expandarray_failure,
|
||||
GuardNotFrozen => exit_guard_not_frozen_failure,
|
||||
GuardNotShared => exit_guard_not_shared_failure,
|
||||
GuardLess => exit_guard_less_failure,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user