Skip to content

Commit f8b4feb

Browse files
committed
ZJIT: Use LoadField for specialized GetIvar
1 parent 0268c86 commit f8b4feb

File tree

3 files changed

+12
-50
lines changed

3 files changed

+12
-50
lines changed

zjit/src/codegen.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
449449
Insn::LoadPC => gen_load_pc(asm),
450450
Insn::LoadSelf => gen_load_self(),
451451
&Insn::LoadField { recv, id, offset, return_type: _ } => gen_load_field(asm, opnd!(recv), id, offset),
452-
&Insn::LoadIvarEmbedded { self_val, id, index } => gen_load_ivar_embedded(asm, opnd!(self_val), id, index),
453-
&Insn::LoadIvarExtended { self_val, id, index } => gen_load_ivar_extended(asm, opnd!(self_val), id, index),
454452
&Insn::IsBlockGiven => gen_is_block_given(jit, asm),
455453
&Insn::ArrayMax { state, .. }
456454
| &Insn::FixnumDiv { state, .. }
@@ -988,29 +986,6 @@ fn gen_load_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32) -> Opnd
988986
asm.load(Opnd::mem(64, recv, offset))
989987
}
990988

991-
fn gen_load_ivar_embedded(asm: &mut Assembler, self_val: Opnd, id: ID, index: u16) -> Opnd {
992-
// See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h
993-
994-
asm_comment!(asm, "Load embedded ivar id={} index={}", id.contents_lossy(), index);
995-
let offs = ROBJECT_OFFSET_AS_ARY as i32 + (SIZEOF_VALUE * index.to_usize()) as i32;
996-
let self_val = asm.load(self_val);
997-
let ivar_opnd = Opnd::mem(64, self_val, offs);
998-
asm.load(ivar_opnd)
999-
}
1000-
1001-
fn gen_load_ivar_extended(asm: &mut Assembler, self_val: Opnd, id: ID, index: u16) -> Opnd {
1002-
asm_comment!(asm, "Load extended ivar id={} index={}", id.contents_lossy(), index);
1003-
// Compile time value is *not* embedded.
1004-
1005-
// Get a pointer to the extended table
1006-
let self_val = asm.load(self_val);
1007-
let tbl_opnd = asm.load(Opnd::mem(64, self_val, ROBJECT_OFFSET_AS_HEAP_FIELDS as i32));
1008-
1009-
// Read the ivar from the extended table
1010-
let ivar_opnd = Opnd::mem(64, tbl_opnd, (SIZEOF_VALUE * index.to_usize()) as i32);
1011-
asm.load(ivar_opnd)
1012-
}
1013-
1014989
/// Compile an interpreter entry block to be inserted into an ISEQ
1015990
fn gen_entry_prologue(asm: &mut Assembler, iseq: IseqPtr) {
1016991
asm_comment!(asm, "ZJIT entry point: {}", iseq_get_location(iseq, 0));

zjit/src/hir.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,6 @@ pub enum Insn {
676676
/// Load cfp->self
677677
LoadSelf,
678678
LoadField { recv: InsnId, id: ID, offset: i32, return_type: Type },
679-
/// Read an instance variable at the given index, embedded in the object
680-
LoadIvarEmbedded { self_val: InsnId, id: ID, index: u16 },
681-
/// Read an instance variable at the given index, from the extended table
682-
LoadIvarExtended { self_val: InsnId, id: ID, index: u16 },
683679

684680
/// Get a local variable from a higher scope or the heap.
685681
/// If `use_sp` is true, it uses the SP register to optimize the read.
@@ -915,8 +911,6 @@ impl Insn {
915911
Insn::LoadPC => false,
916912
Insn::LoadSelf => false,
917913
Insn::LoadField { .. } => false,
918-
Insn::LoadIvarEmbedded { .. } => false,
919-
Insn::LoadIvarExtended { .. } => false,
920914
Insn::CCall { elidable, .. } => !elidable,
921915
Insn::CCallWithFrame { elidable, .. } => !elidable,
922916
Insn::ObjectAllocClass { .. } => false,
@@ -1177,8 +1171,6 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
11771171
Insn::LoadPC => write!(f, "LoadPC"),
11781172
Insn::LoadSelf => write!(f, "LoadSelf"),
11791173
&Insn::LoadField { recv, id, offset, return_type: _ } => write!(f, "LoadField {recv}, :{}@{:p}", id.contents_lossy(), self.ptr_map.map_offset(offset)),
1180-
&Insn::LoadIvarEmbedded { self_val, id, index } => write!(f, "LoadIvarEmbedded {self_val}, :{}@{:p}", id.contents_lossy(), self.ptr_map.map_index(index as u64)),
1181-
&Insn::LoadIvarExtended { self_val, id, index } => write!(f, "LoadIvarExtended {self_val}, :{}@{:p}", id.contents_lossy(), self.ptr_map.map_index(index as u64)),
11821174
Insn::SetIvar { self_val, id, val, .. } => write!(f, "SetIvar {self_val}, :{}, {val}", id.contents_lossy()),
11831175
Insn::GetGlobal { id, .. } => write!(f, "GetGlobal :{}", id.contents_lossy()),
11841176
Insn::SetGlobal { id, val, .. } => write!(f, "SetGlobal :{}, {val}", id.contents_lossy()),
@@ -1800,8 +1792,6 @@ impl Function {
18001792
&SetGlobal { id, val, state } => SetGlobal { id, val: find!(val), state },
18011793
&GetIvar { self_val, id, state } => GetIvar { self_val: find!(self_val), id, state },
18021794
&LoadField { recv, id, offset, return_type } => LoadField { recv: find!(recv), id, offset, return_type },
1803-
&LoadIvarEmbedded { self_val, id, index } => LoadIvarEmbedded { self_val: find!(self_val), id, index },
1804-
&LoadIvarExtended { self_val, id, index } => LoadIvarExtended { self_val: find!(self_val), id, index },
18051795
&SetIvar { self_val, id, val, state } => SetIvar { self_val: find!(self_val), id, val: find!(val), state },
18061796
&GetClassVar { id, ic, state } => GetClassVar { id, ic, state },
18071797
&SetClassVar { id, val, ic, state } => SetClassVar { id, val: find!(val), ic, state },
@@ -1938,8 +1928,6 @@ impl Function {
19381928
Insn::LoadPC => types::CPtr,
19391929
Insn::LoadSelf => types::BasicObject,
19401930
&Insn::LoadField { return_type, .. } => return_type,
1941-
Insn::LoadIvarEmbedded { .. } => types::BasicObject,
1942-
Insn::LoadIvarExtended { .. } => types::BasicObject,
19431931
Insn::GetSpecialSymbol { .. } => types::BasicObject,
19441932
Insn::GetSpecialNumber { .. } => types::BasicObject,
19451933
Insn::GetClassVar { .. } => types::BasicObject,
@@ -2678,13 +2666,17 @@ impl Function {
26782666
// If there is no IVAR index, then the ivar was undefined when we
26792667
// entered the compiler. That means we can just return nil for this
26802668
// shape + iv name
2681-
Insn::Const { val: Const::Value(Qnil) }
2669+
self.push_insn(block, Insn::Const { val: Const::Value(Qnil) })
26822670
} else if recv_type.flags().is_embedded() {
2683-
Insn::LoadIvarEmbedded { self_val, id, index: ivar_index }
2671+
// See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h
2672+
let offset = ROBJECT_OFFSET_AS_ARY as i32 + (SIZEOF_VALUE * ivar_index.to_usize()) as i32;
2673+
self.push_insn(block, Insn::LoadField { recv: self_val, id, offset, return_type: types::BasicObject })
26842674
} else {
2685-
Insn::LoadIvarExtended { self_val, id, index: ivar_index }
2675+
let as_heap = self.push_insn(block, Insn::LoadField { recv: self_val, id: ID!(_as_heap), offset: ROBJECT_OFFSET_AS_HEAP_FIELDS as i32, return_type: types::CPtr });
2676+
2677+
let offset = SIZEOF_VALUE_I32 * ivar_index as i32;
2678+
self.push_insn(block, Insn::LoadField { recv: as_heap, id, offset, return_type: types::BasicObject })
26862679
};
2687-
let replacement = self.push_insn(block, replacement);
26882680
self.make_equal_to(insn_id, replacement);
26892681
}
26902682
_ => { self.push_insn_id(block, insn_id); }
@@ -3376,10 +3368,6 @@ impl Function {
33763368
&Insn::LoadField { recv, .. } => {
33773369
worklist.push_back(recv);
33783370
}
3379-
&Insn::LoadIvarEmbedded { self_val, .. }
3380-
| &Insn::LoadIvarExtended { self_val, .. } => {
3381-
worklist.push_back(self_val);
3382-
}
33833371
&Insn::GuardBlockParamProxy { state, .. } |
33843372
&Insn::GetGlobal { state, .. } |
33853373
&Insn::GetSpecialSymbol { state, .. } |
@@ -3754,8 +3742,6 @@ impl Function {
37543742
self.assert_subtype(insn_id, val, types::BasicObject)
37553743
}
37563744
Insn::DefinedIvar { self_val, .. } => self.assert_subtype(insn_id, self_val, types::BasicObject),
3757-
Insn::LoadIvarEmbedded { self_val, .. } => self.assert_subtype(insn_id, self_val, types::HeapBasicObject),
3758-
Insn::LoadIvarExtended { self_val, .. } => self.assert_subtype(insn_id, self_val, types::HeapBasicObject),
37593745
Insn::SetLocal { val, .. } => self.assert_subtype(insn_id, val, types::BasicObject),
37603746
Insn::SetClassVar { val, .. } => self.assert_subtype(insn_id, val, types::BasicObject),
37613747
Insn::IfTrue { val, .. } | Insn::IfFalse { val, .. } => self.assert_subtype(insn_id, val, types::CBool),

zjit/src/hir/opt_tests.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4551,7 +4551,7 @@ mod hir_opt_tests {
45514551
PatchPoint NoSingletonClass(C@0x1000)
45524552
v22:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
45534553
v25:HeapObject[class_exact:C] = GuardShape v22, 0x1038
4554-
v26:BasicObject = LoadIvarEmbedded v25, :@foo@0x1039
4554+
v26:BasicObject = LoadField v25, :@foo@0x1039
45554555
CheckInterrupts
45564556
Return v26
45574557
");
@@ -4590,9 +4590,10 @@ mod hir_opt_tests {
45904590
PatchPoint NoSingletonClass(C@0x1000)
45914591
v22:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C]
45924592
v25:HeapObject[class_exact:C] = GuardShape v22, 0x1038
4593-
v26:BasicObject = LoadIvarExtended v25, :@foo@0x1039
4593+
v26:CPtr = LoadField v25, :_as_heap@0x1039
4594+
v27:BasicObject = LoadField v26, :@foo@0x103a
45944595
CheckInterrupts
4595-
Return v26
4596+
Return v27
45964597
");
45974598
}
45984599

0 commit comments

Comments
 (0)