@@ -567,29 +567,35 @@ impl std::fmt::Display for SideExitReason {
567567/// Represents whether we know the receiver's class statically at compile-time,
568568/// have profiled type information, or know nothing about it.
569569pub enum ReceiverTypeResolution {
570- /// The receiver's class is statically known at JIT compile-time (no guard needed)
571- StaticallyKnown { class : VALUE } ,
570+ /// No profile information available for the receiver
571+ NoProfile ,
572572 /// The receiver has a monomorphic profile (single type observed, guard needed)
573573 Monomorphic { class : VALUE , profiled_type : ProfiledType } ,
574- /// The receiver has a skewed polymorphic profile (dominant type with some other types, guard needed)
575- SkewedPolymorphic { class : VALUE , profiled_type : ProfiledType } ,
576574 /// The receiver is polymorphic (multiple types, none dominant)
577575 Polymorphic ,
578- /// No profile information available for the receiver
579- NoProfile ,
576+ /// The receiver has a skewed polymorphic profile (dominant type with some other types, guard needed)
577+ SkewedPolymorphic { class : VALUE , profiled_type : ProfiledType } ,
578+ /// More than N types seen with no clear winner
579+ Megamorphic ,
580+ /// Megamorphic, but with a significant skew towards one type
581+ SkewedMegamorphic { class : VALUE , profiled_type : ProfiledType } ,
582+ /// The receiver's class is statically known at JIT compile-time (no guard needed)
583+ StaticallyKnown { class : VALUE } ,
580584}
581585
582586/// Reason why a send-ish instruction cannot be optimized from a fallback instruction
583587#[ derive( Debug , Clone , Copy ) ]
584588pub enum SendFallbackReason {
585589 SendWithoutBlockPolymorphic ,
590+ SendWithoutBlockMegamorphic ,
586591 SendWithoutBlockNoProfiles ,
587592 SendWithoutBlockCfuncNotVariadic ,
588593 SendWithoutBlockCfuncArrayVariadic ,
589594 SendWithoutBlockNotOptimizedMethodType ( MethodType ) ,
590595 SendWithoutBlockNotOptimizedOptimizedMethodType ( OptimizedMethodType ) ,
591596 SendWithoutBlockDirectTooManyArgs ,
592597 SendPolymorphic ,
598+ SendMegamorphic ,
593599 SendNoProfiles ,
594600 SendNotOptimizedMethodType ( MethodType ) ,
595601 CCallWithFrameTooManyArgs ,
@@ -2158,6 +2164,8 @@ impl Function {
21582164 /// - `StaticallyKnown` if the receiver's exact class is known at compile-time
21592165 /// - `Monomorphic`/`SkewedPolymorphic` if we have usable profile data
21602166 /// - `Polymorphic` if the receiver has multiple types
2167+ /// - `Megamorphic`/`SkewedMegamorphic` if the receiver has too many types to optimize
2168+ /// (SkewedMegamorphic may be optimized in the future, but for now we don't)
21612169 /// - `NoProfile` if we have no type information
21622170 fn resolve_receiver_type ( & self , recv : InsnId , recv_type : Type , insn_idx : usize ) -> ReceiverTypeResolution {
21632171 if let Some ( class) = recv_type. runtime_exact_ruby_class ( ) {
@@ -2185,8 +2193,16 @@ impl Function {
21852193 class : profiled_type. class ( ) ,
21862194 profiled_type,
21872195 } ;
2196+ } else if entry_type_summary. is_skewed_megamorphic ( ) {
2197+ let profiled_type = entry_type_summary. bucket ( 0 ) ;
2198+ return ReceiverTypeResolution :: SkewedMegamorphic {
2199+ class : profiled_type. class ( ) ,
2200+ profiled_type,
2201+ } ;
21882202 } else if entry_type_summary. is_polymorphic ( ) {
21892203 return ReceiverTypeResolution :: Polymorphic ;
2204+ } else if entry_type_summary. is_megamorphic ( ) {
2205+ return ReceiverTypeResolution :: Megamorphic ;
21902206 }
21912207 }
21922208 }
@@ -2342,6 +2358,14 @@ impl Function {
23422358 ReceiverTypeResolution :: StaticallyKnown { class } => ( class, None ) ,
23432359 ReceiverTypeResolution :: Monomorphic { class, profiled_type }
23442360 | ReceiverTypeResolution :: SkewedPolymorphic { class, profiled_type } => ( class, Some ( profiled_type) ) ,
2361+ ReceiverTypeResolution :: SkewedMegamorphic { .. }
2362+ | ReceiverTypeResolution :: Megamorphic => {
2363+ if get_option ! ( stats) {
2364+ self . set_dynamic_send_reason ( insn_id, SendWithoutBlockMegamorphic ) ;
2365+ }
2366+ self . push_insn_id ( block, insn_id) ;
2367+ continue ;
2368+ }
23452369 ReceiverTypeResolution :: Polymorphic => {
23462370 if get_option ! ( stats) {
23472371 self . set_dynamic_send_reason ( insn_id, SendWithoutBlockPolymorphic ) ;
@@ -2535,6 +2559,14 @@ impl Function {
25352559 ReceiverTypeResolution :: StaticallyKnown { class } => class,
25362560 ReceiverTypeResolution :: Monomorphic { class, .. }
25372561 | ReceiverTypeResolution :: SkewedPolymorphic { class, .. } => class,
2562+ ReceiverTypeResolution :: SkewedMegamorphic { .. }
2563+ | ReceiverTypeResolution :: Megamorphic => {
2564+ if get_option ! ( stats) {
2565+ self . set_dynamic_send_reason ( insn_id, SendMegamorphic ) ;
2566+ }
2567+ self . push_insn_id ( block, insn_id) ;
2568+ continue ;
2569+ }
25382570 ReceiverTypeResolution :: Polymorphic => {
25392571 if get_option ! ( stats) {
25402572 self . set_dynamic_send_reason ( insn_id, SendPolymorphic ) ;
@@ -2815,7 +2847,7 @@ impl Function {
28152847 ReceiverTypeResolution :: StaticallyKnown { class } => ( class, None ) ,
28162848 ReceiverTypeResolution :: Monomorphic { class, profiled_type }
28172849 | ReceiverTypeResolution :: SkewedPolymorphic { class, profiled_type } => ( class, Some ( profiled_type) ) ,
2818- ReceiverTypeResolution :: Polymorphic | ReceiverTypeResolution :: NoProfile => return Err ( ( ) ) ,
2850+ ReceiverTypeResolution :: SkewedMegamorphic { .. } | ReceiverTypeResolution :: Polymorphic | ReceiverTypeResolution :: Megamorphic | ReceiverTypeResolution :: NoProfile => return Err ( ( ) ) ,
28192851 } ;
28202852
28212853 // Do method lookup
@@ -2920,7 +2952,7 @@ impl Function {
29202952 ReceiverTypeResolution :: StaticallyKnown { class } => ( class, None ) ,
29212953 ReceiverTypeResolution :: Monomorphic { class, profiled_type }
29222954 | ReceiverTypeResolution :: SkewedPolymorphic { class, profiled_type } => ( class, Some ( profiled_type) ) ,
2923- ReceiverTypeResolution :: Polymorphic | ReceiverTypeResolution :: NoProfile => return Err ( ( ) ) ,
2955+ ReceiverTypeResolution :: SkewedMegamorphic { .. } | ReceiverTypeResolution :: Polymorphic | ReceiverTypeResolution :: Megamorphic | ReceiverTypeResolution :: NoProfile => return Err ( ( ) ) ,
29242956 } ;
29252957
29262958 // Do method lookup
0 commit comments