@@ -540,6 +540,15 @@ pub enum SideExitReason {
540540 InvokeBlockNotIfunc ,
541541}
542542
543+ /// Controls how a side exit triggers recompilation.
544+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
545+ pub enum Recompile {
546+ /// Profile receiver + arguments from the stack (for sends without profile data).
547+ ProfileSend { argc : i32 } ,
548+ /// Profile self from the CFP (for shape guard failures).
549+ ProfileSelf ,
550+ }
551+
543552#[ derive( Debug , Clone , Copy ) ]
544553pub enum MethodType {
545554 Iseq ,
@@ -1090,9 +1099,7 @@ pub enum Insn {
10901099 GuardType { val : InsnId , guard_type : Type , state : InsnId } ,
10911100 GuardTypeNot { val : InsnId , guard_type : Type , state : InsnId } ,
10921101 /// Side-exit if val is not the expected Const.
1093- /// `recompile`: if Some(argc), the side exit triggers exit_recompile.
1094- /// argc >= 0 profiles receiver + args from stack; argc == -1 profiles self from CFP.
1095- GuardBitEquals { val : InsnId , expected : Const , reason : SideExitReason , state : InsnId , recompile : Option < i32 > } ,
1102+ GuardBitEquals { val : InsnId , expected : Const , reason : SideExitReason , state : InsnId , recompile : Option < Recompile > } ,
10961103 /// Side-exit if (val & mask) == 0
10971104 GuardAnyBitSet { val : InsnId , mask : Const , mask_name : Option < ID > , reason : SideExitReason , state : InsnId } ,
10981105 /// Side-exit if (val & mask) != 0
@@ -1107,9 +1114,9 @@ pub enum Insn {
11071114 PatchPoint { invariant : Invariant , state : InsnId } ,
11081115
11091116 /// Side-exit into the interpreter.
1110- /// If ` recompile` is set , the side exit will profile the send and invalidate the ISEQ
1117+ /// If recompile is not None , the side exit will profile and invalidate the ISEQ
11111118 /// so that it gets recompiled with the new profile data.
1112- SideExit { state : InsnId , reason : SideExitReason , recompile : Option < i32 > } ,
1119+ SideExit { state : InsnId , reason : SideExitReason , recompile : Option < Recompile > } ,
11131120
11141121 /// Increment a counter in ZJIT stats
11151122 IncrCounter ( Counter ) ,
@@ -4392,7 +4399,7 @@ impl Function {
43924399 } )
43934400 }
43944401
4395- fn guard_shape ( & mut self , block : BlockId , val : InsnId , expected : ShapeId , state : InsnId , recompile : Option < i32 > ) -> InsnId {
4402+ fn guard_shape ( & mut self , block : BlockId , val : InsnId , expected : ShapeId , state : InsnId , recompile : Option < Recompile > ) -> InsnId {
43964403 self . push_insn ( block, Insn :: GuardBitEquals {
43974404 val,
43984405 expected : Const :: CShape ( expected) ,
@@ -4543,7 +4550,7 @@ impl Function {
45434550 }
45444551 let self_val = self . load_ivar_guard_type ( block, self_val, recv_type, state) ;
45454552 let shape = self . load_shape ( block, self_val) ;
4546- self . guard_shape ( block, shape, recv_type. shape ( ) , state, Some ( - 1 ) ) ;
4553+ self . guard_shape ( block, shape, recv_type. shape ( ) , state, Some ( Recompile :: ProfileSelf ) ) ;
45474554 let replacement = self . load_ivar ( block, self_val, recv_type, id, state) ;
45484555 self . make_equal_to ( insn_id, replacement) ;
45494556 }
@@ -5178,7 +5185,7 @@ impl Function {
51785185 match self . find ( insn_id) {
51795186 Insn :: Send { cd, state, reason : SendFallbackReason :: SendWithoutBlockNoProfiles | SendFallbackReason :: SendNoProfiles , .. } => {
51805187 let argc = unsafe { vm_ci_argc ( ( * cd) . ci ) } as i32 ;
5181- self . push_insn ( block, Insn :: SideExit { state, reason : SideExitReason :: NoProfileSend , recompile : Some ( argc) } ) ;
5188+ self . push_insn ( block, Insn :: SideExit { state, reason : SideExitReason :: NoProfileSend , recompile : Some ( Recompile :: ProfileSend { argc } ) } ) ;
51825189 // SideExit is a terminator; don't add remaining instructions
51835190 break ;
51845191 }
0 commit comments