Skip to content

Commit e6ea89e

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 a switch block, a load block for each shape, and a join block. 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 de46ae9 commit e6ea89e

File tree

4 files changed

+575
-147
lines changed

4 files changed

+575
-147
lines changed

zjit/src/codegen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
548548
&Insn::UnboxFixnum { val } => gen_unbox_fixnum(asm, opnd!(val)),
549549
Insn::Test { val } => gen_test(asm, opnd!(val)),
550550
Insn::RefineType { val, .. } => opnd!(val),
551+
Insn::RefineShape { val, .. } => opnd!(val),
551552
Insn::HasType { val, expected } => gen_has_type(asm, opnd!(val), *expected),
552553
Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
553554
Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),

0 commit comments

Comments
 (0)