Skip to content

Commit 4651585

Browse files
committed
ZJIT: Add mask_name to GuardXYZBitsSet
This makes HIR easier to debug.
1 parent 5571212 commit 4651585

5 files changed

Lines changed: 35 additions & 24 deletions

File tree

zjit/src/codegen.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,8 +536,8 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
536536
Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
537537
Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
538538
&Insn::GuardBitEquals { val, expected, reason, state } => gen_guard_bit_equals(jit, asm, opnd!(val), expected, reason, &function.frame_state(state)),
539-
&Insn::GuardAnyBitSet { val, mask, reason, state } => gen_guard_any_bit_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)),
540-
&Insn::GuardNoBitsSet { val, mask, reason, state } => gen_guard_no_bits_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)),
539+
&Insn::GuardAnyBitSet { val, mask, reason, state, .. } => gen_guard_any_bit_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)),
540+
&Insn::GuardNoBitsSet { val, mask, reason, state, .. } => gen_guard_no_bits_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)),
541541
&Insn::GuardLess { left, right, state } => gen_guard_less(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state)),
542542
&Insn::GuardGreaterEq { left, right, state } => gen_guard_greater_eq(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state)),
543543
Insn::PatchPoint { invariant, state } => no_output!(gen_patch_point(jit, asm, invariant, &function.frame_state(*state))),

zjit/src/cruby.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,12 @@ impl ID {
783783
}
784784
}
785785

786+
impl Display for ID {
787+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
788+
write!(f, "{}", self.contents_lossy())
789+
}
790+
}
791+
786792
/// Produce a Ruby string from a Rust string slice
787793
pub fn rust_str_to_ruby(str: &str) -> VALUE {
788794
unsafe { rb_utf8_str_new(str.as_ptr() as *const _, str.len() as i64) }
@@ -1401,6 +1407,9 @@ pub(crate) mod ids {
14011407
name: _ep_method_entry
14021408
name: _ep_specval
14031409
name: _rbasic_flags
1410+
name: RUBY_FL_FREEZE
1411+
name: RUBY_ELTS_SHARED
1412+
name: VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM
14041413
}
14051414

14061415
/// Get an CRuby `ID` to an interned string, e.g. a particular method name.

zjit/src/hir.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,9 @@ pub enum Insn {
10271027
/// Side-exit if val is not the expected Const.
10281028
GuardBitEquals { val: InsnId, expected: Const, reason: SideExitReason, state: InsnId },
10291029
/// Side-exit if (val & mask) == 0
1030-
GuardAnyBitSet { val: InsnId, mask: Const, reason: SideExitReason, state: InsnId },
1030+
GuardAnyBitSet { val: InsnId, mask: Const, mask_name: Option<ID>, reason: SideExitReason, state: InsnId },
10311031
/// Side-exit if (val & mask) != 0
1032-
GuardNoBitsSet { val: InsnId, mask: Const, reason: SideExitReason, state: InsnId },
1032+
GuardNoBitsSet { val: InsnId, mask: Const, mask_name: Option<ID>, reason: SideExitReason, state: InsnId },
10331033
/// Side-exit if left is not greater than or equal to right (both operands are C long).
10341034
GuardGreaterEq { left: InsnId, right: InsnId, state: InsnId },
10351035
/// Side-exit if left is not less than right (both operands are C long).
@@ -1550,7 +1550,9 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
15501550
Insn::HasType { val, expected, .. } => { write!(f, "HasType {val}, {}", expected.print(self.ptr_map)) },
15511551
Insn::GuardTypeNot { val, guard_type, .. } => { write!(f, "GuardTypeNot {val}, {}", guard_type.print(self.ptr_map)) },
15521552
Insn::GuardBitEquals { val, expected, .. } => { write!(f, "GuardBitEquals {val}, {}", expected.print(self.ptr_map)) },
1553+
Insn::GuardAnyBitSet { val, mask, mask_name: Some(name), .. } => { write!(f, "GuardAnyBitSet {val}, {name}={}", mask.print(self.ptr_map)) },
15531554
Insn::GuardAnyBitSet { val, mask, .. } => { write!(f, "GuardAnyBitSet {val}, {}", mask.print(self.ptr_map)) },
1555+
Insn::GuardNoBitsSet { val, mask, mask_name: Some(name), .. } => { write!(f, "GuardNoBitsSet {val}, {name}={}", mask.print(self.ptr_map)) },
15541556
Insn::GuardNoBitsSet { val, mask, .. } => { write!(f, "GuardNoBitsSet {val}, {}", mask.print(self.ptr_map)) },
15551557
Insn::GuardLess { left, right, .. } => write!(f, "GuardLess {left}, {right}"),
15561558
Insn::GuardGreaterEq { left, right, .. } => write!(f, "GuardGreaterEq {left}, {right}"),
@@ -2236,8 +2238,8 @@ impl Function {
22362238
&GuardType { val, guard_type, state } => GuardType { val: find!(val), guard_type, state },
22372239
&GuardTypeNot { val, guard_type, state } => GuardTypeNot { val: find!(val), guard_type, state },
22382240
&GuardBitEquals { val, expected, reason, state } => GuardBitEquals { val: find!(val), expected, reason, state },
2239-
&GuardAnyBitSet { val, mask, reason, state } => GuardAnyBitSet { val: find!(val), mask, reason, state },
2240-
&GuardNoBitsSet { val, mask, reason, state } => GuardNoBitsSet { val: find!(val), mask, reason, state },
2241+
&GuardAnyBitSet { val, mask, mask_name, reason, state } => GuardAnyBitSet { val: find!(val), mask, mask_name, reason, state },
2242+
&GuardNoBitsSet { val, mask, mask_name, reason, state } => GuardNoBitsSet { val: find!(val), mask, mask_name, reason, state },
22412243
&GuardGreaterEq { left, right, state } => GuardGreaterEq { left: find!(left), right: find!(right), state },
22422244
&GuardLess { left, right, state } => GuardLess { left: find!(left), right: find!(right), state },
22432245
&IsBlockGiven { lep } => IsBlockGiven { lep: find!(lep) },
@@ -3004,12 +3006,12 @@ impl Function {
30043006

30053007
pub fn guard_not_frozen(&mut self, block: BlockId, recv: InsnId, state: InsnId) {
30063008
let flags = self.load_rbasic_flags(block, recv);
3007-
self.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(RUBY_FL_FREEZE as u64), reason: SideExitReason::GuardNotFrozen, state });
3009+
self.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(RUBY_FL_FREEZE as u64), mask_name: Some(ID!(RUBY_FL_FREEZE)), reason: SideExitReason::GuardNotFrozen, state });
30083010
}
30093011

30103012
pub fn guard_not_shared(&mut self, block: BlockId, recv: InsnId, state: InsnId) {
30113013
let flags = self.load_rbasic_flags(block, recv);
3012-
self.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(RUBY_ELTS_SHARED as u64), reason: SideExitReason::GuardNotShared, state });
3014+
self.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(RUBY_ELTS_SHARED as u64), mask_name: Some(ID!(RUBY_ELTS_SHARED)), reason: SideExitReason::GuardNotShared, state });
30133015
}
30143016

30153017
/// Rewrite eligible Send/SendWithoutBlock opcodes into SendDirect
@@ -6794,7 +6796,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
67946796

67956797
let ep = fun.push_insn(block, Insn::GetEP { level });
67966798
let flags = fun.push_insn(block, Insn::LoadField { recv: ep, id: ID!(_env_data_index_flags), offset: SIZEOF_VALUE_I32 * (VM_ENV_DATA_INDEX_FLAGS as i32), return_type: types::CInt64 });
6797-
fun.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM.into()), reason: SideExitReason::BlockParamProxyModified, state: exit_id });
6799+
fun.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM.into()), mask_name: Some(ID!(VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM)), reason: SideExitReason::BlockParamProxyModified, state: exit_id });
67986800

67996801
let block_handler = fun.push_insn(block, Insn::LoadField { recv: ep, id: ID!(_env_data_index_specval), offset: SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL, return_type: types::CInt64 });
68006802

@@ -6812,7 +6814,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
68126814
const _: () = assert!(RUBY_SYMBOL_FLAG & 1 == 0, "guard below rejects symbol block handlers");
68136815

68146816
// Bail out if the block handler is neither ISEQ nor ifunc
6815-
fun.push_insn(block, Insn::GuardAnyBitSet { val: block_handler, mask: Const::CUInt64(0x1), reason: SideExitReason::BlockParamProxyNotIseqOrIfunc, state: exit_id });
6817+
fun.push_insn(block, Insn::GuardAnyBitSet { val: block_handler, mask: Const::CUInt64(0x1), mask_name: None, reason: SideExitReason::BlockParamProxyNotIseqOrIfunc, state: exit_id });
68166818
// TODO(Shopify/ruby#753): GC root, so we should be able to avoid unnecessary GC tracing
68176819
state.stack_push(fun.push_insn(block, Insn::Const { val: Const::Value(unsafe { rb_block_param_proxy }) }));
68186820
}

zjit/src/hir/opt_tests.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,7 +3888,7 @@ mod hir_opt_tests {
38883888
bb2(v8:BasicObject, v9:BasicObject):
38893889
v14:CPtr = GetEP 0
38903890
v15:CInt64 = LoadField v14, :_env_data_index_flags@0x1000
3891-
v16:CInt64 = GuardNoBitsSet v15, CUInt64(512)
3891+
v16:CInt64 = GuardNoBitsSet v15, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM=CUInt64(512)
38923892
v17:CInt64 = LoadField v14, :_env_data_index_specval@0x1001
38933893
v18:CInt64 = GuardAnyBitSet v17, CUInt64(1)
38943894
v19:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1008))
@@ -6560,7 +6560,7 @@ mod hir_opt_tests {
65606560
v13:ArrayExact = NewArray
65616561
v15:CPtr = GetEP 0
65626562
v16:CInt64 = LoadField v15, :_env_data_index_flags@0x1000
6563-
v17:CInt64 = GuardNoBitsSet v16, CUInt64(512)
6563+
v17:CInt64 = GuardNoBitsSet v16, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM=CUInt64(512)
65646564
v18:CInt64 = LoadField v15, :_env_data_index_specval@0x1001
65656565
v19:CInt64 = GuardAnyBitSet v18, CUInt64(1)
65666566
v20:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1008))
@@ -6591,7 +6591,7 @@ mod hir_opt_tests {
65916591
v13:ArrayExact = NewArray
65926592
v15:CPtr = GetEP 0
65936593
v16:CInt64 = LoadField v15, :_env_data_index_flags@0x1000
6594-
v17:CInt64 = GuardNoBitsSet v16, CUInt64(512)
6594+
v17:CInt64 = GuardNoBitsSet v16, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM=CUInt64(512)
65956595
v18:CInt64 = LoadField v15, :_env_data_index_specval@0x1001
65966596
v19:CInt64[0] = GuardBitEquals v18, CInt64(0)
65976597
v20:NilClass = Const Value(nil)
@@ -6625,7 +6625,7 @@ mod hir_opt_tests {
66256625
v10:ArrayExact = NewArray
66266626
v12:CPtr = GetEP 1
66276627
v13:CInt64 = LoadField v12, :_env_data_index_flags@0x1000
6628-
v14:CInt64 = GuardNoBitsSet v13, CUInt64(512)
6628+
v14:CInt64 = GuardNoBitsSet v13, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM=CUInt64(512)
66296629
v15:CInt64 = LoadField v12, :_env_data_index_specval@0x1001
66306630
v16:CInt64 = GuardAnyBitSet v15, CUInt64(1)
66316631
v17:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1008))
@@ -6987,7 +6987,7 @@ mod hir_opt_tests {
69876987
PatchPoint MethodRedefined(C@0x1000, foo=@0x1008, cme:0x1010)
69886988
v29:HeapObject[class_exact:C] = GuardType v11, HeapObject[class_exact:C]
69896989
v30:CUInt64 = LoadField v29, :_rbasic_flags@0x1038
6990-
v31:CUInt64 = GuardNoBitsSet v30, CUInt64(2048)
6990+
v31:CUInt64 = GuardNoBitsSet v30, RUBY_FL_FREEZE=CUInt64(2048)
69916991
StoreField v29, :foo=@0x1039, v12
69926992
WriteBarrier v29, v12
69936993
CheckInterrupts
@@ -7020,7 +7020,7 @@ mod hir_opt_tests {
70207020
PatchPoint MethodRedefined(C@0x1000, foo=@0x1008, cme:0x1010)
70217021
v29:HeapObject[class_exact:C] = GuardType v11, HeapObject[class_exact:C]
70227022
v30:CUInt64 = LoadField v29, :_rbasic_flags@0x1038
7023-
v31:CUInt64 = GuardNoBitsSet v30, CUInt64(2048)
7023+
v31:CUInt64 = GuardNoBitsSet v30, RUBY_FL_FREEZE=CUInt64(2048)
70247024
v32:CPtr = LoadField v29, :_as_heap@0x1039
70257025
StoreField v32, :foo=@0x103a, v12
70267026
WriteBarrier v29, v12
@@ -7641,9 +7641,9 @@ mod hir_opt_tests {
76417641
PatchPoint MethodRedefined(Array@0x1000, []=@0x1008, cme:0x1010)
76427642
v31:ArrayExact = GuardType v9, ArrayExact
76437643
v32:CUInt64 = LoadField v31, :_rbasic_flags@0x1038
7644-
v33:CUInt64 = GuardNoBitsSet v32, CUInt64(2048)
7644+
v33:CUInt64 = GuardNoBitsSet v32, RUBY_FL_FREEZE=CUInt64(2048)
76457645
v34:CUInt64 = LoadField v31, :_rbasic_flags@0x1038
7646-
v35:CUInt64 = GuardNoBitsSet v34, CUInt64(4096)
7646+
v35:CUInt64 = GuardNoBitsSet v34, RUBY_ELTS_SHARED=CUInt64(4096)
76477647
v36:CInt64[1] = UnboxFixnum v16
76487648
v37:CInt64 = ArrayLength v31
76497649
v38:CInt64[1] = GuardLess v36, v37
@@ -7683,9 +7683,9 @@ mod hir_opt_tests {
76837683
v35:ArrayExact = GuardType v13, ArrayExact
76847684
v36:Fixnum = GuardType v14, Fixnum
76857685
v37:CUInt64 = LoadField v35, :_rbasic_flags@0x1038
7686-
v38:CUInt64 = GuardNoBitsSet v37, CUInt64(2048)
7686+
v38:CUInt64 = GuardNoBitsSet v37, RUBY_FL_FREEZE=CUInt64(2048)
76877687
v39:CUInt64 = LoadField v35, :_rbasic_flags@0x1038
7688-
v40:CUInt64 = GuardNoBitsSet v39, CUInt64(4096)
7688+
v40:CUInt64 = GuardNoBitsSet v39, RUBY_ELTS_SHARED=CUInt64(4096)
76897689
v41:CInt64 = UnboxFixnum v36
76907690
v42:CInt64 = ArrayLength v35
76917691
v43:CInt64 = GuardLess v41, v42
@@ -8011,7 +8011,7 @@ mod hir_opt_tests {
80118011
v36:CInt64[0] = Const CInt64(0)
80128012
v37:CInt64 = GuardGreaterEq v35, v36
80138013
v38:CUInt64 = LoadField v30, :_rbasic_flags@0x1039
8014-
v39:CUInt64 = GuardNoBitsSet v38, CUInt64(2048)
8014+
v39:CUInt64 = GuardNoBitsSet v38, RUBY_FL_FREEZE=CUInt64(2048)
80158015
v40:Fixnum = StringSetbyteFixnum v30, v31, v32
80168016
IncrCounter inline_cfunc_optimized_send_count
80178017
CheckInterrupts
@@ -8053,7 +8053,7 @@ mod hir_opt_tests {
80538053
v36:CInt64[0] = Const CInt64(0)
80548054
v37:CInt64 = GuardGreaterEq v35, v36
80558055
v38:CUInt64 = LoadField v30, :_rbasic_flags@0x1039
8056-
v39:CUInt64 = GuardNoBitsSet v38, CUInt64(2048)
8056+
v39:CUInt64 = GuardNoBitsSet v38, RUBY_FL_FREEZE=CUInt64(2048)
80578057
v40:Fixnum = StringSetbyteFixnum v30, v31, v32
80588058
IncrCounter inline_cfunc_optimized_send_count
80598059
CheckInterrupts

zjit/src/hir/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,7 +2058,7 @@ pub mod hir_build_tests {
20582058
PatchPoint NoEPEscape(test)
20592059
v33:CPtr = GetEP 0
20602060
v34:CInt64 = LoadField v33, :_env_data_index_flags@0x1000
2061-
v35:CInt64 = GuardNoBitsSet v34, CUInt64(512)
2061+
v35:CInt64 = GuardNoBitsSet v34, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM=CUInt64(512)
20622062
v36:CInt64 = LoadField v33, :_env_data_index_specval@0x1001
20632063
v37:CInt64 = GuardAnyBitSet v36, CUInt64(1)
20642064
v38:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1008))
@@ -3434,7 +3434,7 @@ pub mod hir_build_tests {
34343434
PatchPoint NoEPEscape(open)
34353435
v31:CPtr = GetEP 0
34363436
v32:CInt64 = LoadField v31, :_env_data_index_flags@0x1000
3437-
v33:CInt64 = GuardNoBitsSet v32, CUInt64(512)
3437+
v33:CInt64 = GuardNoBitsSet v32, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM=CUInt64(512)
34383438
v34:CInt64 = LoadField v31, :_env_data_index_specval@0x1001
34393439
v35:CInt64 = GuardAnyBitSet v34, CUInt64(1)
34403440
v36:HeapObject[BlockParamProxy] = Const Value(VALUE(0x1008))

0 commit comments

Comments
 (0)