Skip to content

Commit 77ddd16

Browse files
committed
ZJIT: Polymorphic getivar with shape-based splitting
Add support for polymorphic getinstancevariable and attr_reader with shape-based splitting. When multiple shapes are observed for the same receiver, we now generate optimized code paths for each shape using IsBitEqual checks on the shape ID. Key changes: - Add RefineShape instruction to record known shape information with is_t_object and is_embedded flags - In iseq_to_hir, emit shape-based splitting for polymorphic getivar and attr_reader (same-class-different-shapes case) - Move guard insertion (GuardType, guard_shape) from optimize_getivar to the HIR building phase - Simplify optimize_getivar to only lower RefineShape inputs to LoadField (T_OBJECT) or CCall (non-T_OBJECT) Problem: This approach doesn't compose perfectly with the splitting for polymorphic send. We potentially want to split twice, one for all the different callee varying in method types and another time for shape variations. For simplicity, we only split in the monomorphic attr_reader callee, polymorphic shapes case for now. Problem: We need to change the strategy for counting fallbacks because there no one place where we can definitively say getivar won't be optimized anymore. Maybe a fallback reason approach that Send uses.
1 parent 219ad68 commit 77ddd16

6 files changed

Lines changed: 559 additions & 154 deletions

File tree

zjit/src/codegen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
532532
&Insn::UnboxFixnum { val } => gen_unbox_fixnum(asm, opnd!(val)),
533533
Insn::Test { val } => gen_test(asm, opnd!(val)),
534534
Insn::RefineType { val, .. } => opnd!(val),
535+
Insn::RefineShape { val, .. } => opnd!(val),
535536
Insn::HasType { val, expected } => gen_has_type(asm, opnd!(val), *expected),
536537
Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
537538
Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),

zjit/src/distribution.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub struct DistributionSummary<T: Copy + PartialEq + Default + std::fmt::Debug,
7979
const SKEW_THRESHOLD: f64 = 0.75;
8080

8181
impl<T: Copy + PartialEq + Default + std::fmt::Debug, const N: usize> DistributionSummary<T, N> {
82+
8283
pub fn new(dist: &Distribution<T, N>) -> Self {
8384
#[cfg(debug_assertions)]
8485
{

0 commit comments

Comments
 (0)