@@ -1147,7 +1147,7 @@ pub enum Insn {
11471147 HasType { val : InsnId , expected : Type } ,
11481148
11491149 /// Side-exit if val doesn't have the expected type.
1150- GuardType { val : InsnId , guard_type : Type , state : InsnId } ,
1150+ GuardType { val : InsnId , guard_type : Type , state : InsnId , recompile : Option < Recompile > } ,
11511151 /// Side-exit if val is not the expected Const.
11521152 GuardBitEquals { val : InsnId , expected : Const , reason : SideExitReason , state : InsnId , recompile : Option < Recompile > } ,
11531153 /// Side-exit if (val & mask) == 0
@@ -3428,7 +3428,7 @@ impl Function {
34283428
34293429 pub fn coerce_to ( & mut self , block : BlockId , val : InsnId , guard_type : Type , state : InsnId ) -> InsnId {
34303430 if self . is_a ( val, guard_type) { return val; }
3431- self . push_insn ( block, Insn :: GuardType { val, guard_type, state } )
3431+ self . push_insn ( block, Insn :: GuardType { val, guard_type, state , recompile : None } )
34323432 }
34333433
34343434 fn count_complex_call_features ( & mut self , block : BlockId , ci_flags : c_uint ) {
@@ -3671,7 +3671,7 @@ impl Function {
36713671
36723672 // Add GuardType for profiled receiver
36733673 if let Some ( profiled_type) = profiled_type {
3674- recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
3674+ recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
36753675 }
36763676
36773677 let send_direct = self . push_insn ( block, Insn :: SendDirect { recv, cd, cme, iseq, args : processed_args, kw_bits, state : send_state, block : send_block } ) ;
@@ -3714,7 +3714,7 @@ impl Function {
37143714 self . push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: MethodRedefined { klass, method : mid, cme } , state } ) ;
37153715
37163716 if let Some ( profiled_type) = profiled_type {
3717- recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
3717+ recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
37183718 }
37193719
37203720 let send_direct = self . push_insn ( block, Insn :: SendDirect { recv, cd, cme, iseq, args : processed_args, kw_bits, state : send_state, block : None } ) ;
@@ -3734,7 +3734,7 @@ impl Function {
37343734
37353735 self . push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: MethodRedefined { klass, method : mid, cme } , state } ) ;
37363736 if let Some ( profiled_type) = profiled_type {
3737- recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
3737+ recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
37383738 }
37393739 let id = unsafe { get_cme_def_body_attr_id ( cme) } ;
37403740
@@ -3750,7 +3750,7 @@ impl Function {
37503750
37513751 self . push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: MethodRedefined { klass, method : mid, cme } , state } ) ;
37523752 if let Some ( profiled_type) = profiled_type {
3753- recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
3753+ recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
37543754 }
37553755 let id = unsafe { get_cme_def_body_attr_id ( cme) } ;
37563756
@@ -3772,7 +3772,7 @@ impl Function {
37723772 }
37733773 self . push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: MethodRedefined { klass, method : mid, cme } , state } ) ;
37743774 if let Some ( profiled_type) = profiled_type {
3775- recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
3775+ recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
37763776 }
37773777 let kw_splat = flags & VM_CALL_KW_SPLAT != 0 ;
37783778 let invoke_proc = self . push_insn ( block, Insn :: InvokeProc { recv, args : args. clone ( ) , state, kw_splat } ) ;
@@ -3810,7 +3810,7 @@ impl Function {
38103810 }
38113811 self . push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: MethodRedefined { klass, method : mid, cme } , state } ) ;
38123812 if let Some ( profiled_type) = profiled_type {
3813- recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
3813+ recv = self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
38143814 }
38153815 // All structs from the same Struct class should have the same
38163816 // length. So if our recv is embedded all runtime
@@ -3881,12 +3881,12 @@ impl Function {
38813881
38823882 if recv_type. is_string ( ) {
38833883 self . push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: NoSingletonClass { klass : recv_type. class ( ) } , state } ) ;
3884- let guard = self . push_insn ( block, Insn :: GuardType { val, guard_type : types:: String , state } ) ;
3884+ let guard = self . push_insn ( block, Insn :: GuardType { val, guard_type : types:: String , state, recompile : None } ) ;
38853885 // Infer type so AnyToString can fold off this
38863886 self . insn_types [ guard. 0 ] = self . infer_type ( guard) ;
38873887 self . make_equal_to ( insn_id, guard) ;
38883888 } else {
3889- let recv = self . push_insn ( block, Insn :: GuardType { val, guard_type : Type :: from_profiled_type ( recv_type) , state} ) ;
3889+ let recv = self . push_insn ( block, Insn :: GuardType { val, guard_type : Type :: from_profiled_type ( recv_type) , state, recompile : None } ) ;
38903890 let send_to_s = self . push_insn ( block, Insn :: Send { recv, cd, block : None , args : vec ! [ ] , state, reason : ObjToStringNotString } ) ;
38913891 self . make_equal_to ( insn_id, send_to_s) ;
38923892 }
@@ -4333,16 +4333,16 @@ impl Function {
43334333 fn load_ivar_guard_type ( & mut self , block : BlockId , recv : InsnId , recv_type : ProfiledType , state : InsnId ) -> InsnId {
43344334 if recv_type. flags ( ) . is_t_class ( ) {
43354335 // Check class first since `Class < Module`
4336- self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: Class , state } )
4336+ self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: Class , state , recompile : None } )
43374337 } else if recv_type. flags ( ) . is_t_module ( ) {
4338- self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: Module , state } )
4338+ self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: Module , state , recompile : None } )
43394339 } else if recv_type. flags ( ) . is_t_data ( ) {
4340- self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: TData , state } )
4340+ self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: TData , state , recompile : None } )
43414341 } else {
43424342 // HeapBasicObject is wider than T_OBJECT, but shapes for T_OBJECTs are in a pool of
43434343 // its own and are guaranteed to be different from shapes of any other T_* types. So
43444344 // the shape check that follows already covers checking for T_OBJECT.
4345- self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: HeapBasicObject , state } )
4345+ self . push_insn ( block, Insn :: GuardType { val : recv, guard_type : types:: HeapBasicObject , state , recompile : None } )
43464346 }
43474347 }
43484348
@@ -4731,7 +4731,7 @@ impl Function {
47314731
47324732 if let Some ( profiled_type) = profiled_type {
47334733 // Guard receiver class
4734- recv = fun. push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
4734+ recv = fun. push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
47354735 fun. insn_types [ recv. 0 ] = fun. infer_type ( recv) ;
47364736 }
47374737
@@ -4797,7 +4797,7 @@ impl Function {
47974797
47984798 if let Some ( profiled_type) = profiled_type {
47994799 // Guard receiver class
4800- recv = fun. push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state } ) ;
4800+ recv = fun. push_insn ( block, Insn :: GuardType { val : recv, guard_type : Type :: from_profiled_type ( profiled_type) , state, recompile : None } ) ;
48014801 fun. insn_types [ recv. 0 ] = fun. infer_type ( recv) ;
48024802 }
48034803
@@ -7017,9 +7017,9 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
70177017 }
70187018 let ty = Type :: from_profiled_type ( summary. bucket ( 0 ) ) ;
70197019 let obj = if ty. is_subtype ( types:: NilClass ) {
7020- fun. push_insn ( block, Insn :: GuardType { val : hash, guard_type : types:: NilClass , state : exit_id } )
7020+ fun. push_insn ( block, Insn :: GuardType { val : hash, guard_type : types:: NilClass , state : exit_id , recompile : None } )
70217021 } else if ty. is_subtype ( types:: HashExact ) {
7022- fun. push_insn ( block, Insn :: GuardType { val : hash, guard_type : types:: HashExact , state : exit_id } )
7022+ fun. push_insn ( block, Insn :: GuardType { val : hash, guard_type : types:: HashExact , state : exit_id , recompile : None } )
70237023 } else {
70247024 fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: SplatKwNotNilOrHash , recompile : None } ) ;
70257025 break ; // End the block
@@ -8195,7 +8195,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
81958195 break ; // End the block
81968196 }
81978197 if let Some ( summary) = fun. polymorphic_summary ( & profiles, self_param, exit_state. insn_idx ) {
8198- self_param = fun. push_insn ( block, Insn :: GuardType { val : self_param, guard_type : types:: HeapBasicObject , state : exit_id } ) ;
8198+ self_param = fun. push_insn ( block, Insn :: GuardType { val : self_param, guard_type : types:: HeapBasicObject , state : exit_id, recompile : None } ) ;
81998199 let rbasic_flags = fun. load_rbasic_flags ( block, self_param) ;
82008200 let join_block = insn_idx_to_block. get ( & insn_idx) . copied ( ) . unwrap_or_else ( || fun. new_block ( insn_idx) ) ;
82018201 let join_param = fun. push_insn ( join_block, Insn :: Param ) ;
@@ -8403,7 +8403,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
84038403 break ; // End the block
84048404 }
84058405 let val = state. stack_pop ( ) ?;
8406- let array = fun. push_insn ( block, Insn :: GuardType { val, guard_type : types:: ArrayExact , state : exit_id, } ) ;
8406+ let array = fun. push_insn ( block, Insn :: GuardType { val, guard_type : types:: ArrayExact , state : exit_id, recompile : None } ) ;
84078407 let length = fun. push_insn ( block, Insn :: ArrayLength { array } ) ;
84088408 let expected = fun. push_insn ( block, Insn :: Const { val : Const :: CInt64 ( num as i64 ) } ) ;
84098409 fun. push_insn ( block, Insn :: GuardGreaterEq { left : length, right : expected, reason : SideExitReason :: ExpandArray , state : exit_id } ) ;
0 commit comments