@@ -3069,6 +3069,15 @@ impl Function {
30693069 self . infer_types ( ) ;
30703070 }
30713071
3072+ fn load_shape ( & mut self , block : BlockId , recv : InsnId ) -> InsnId {
3073+ self . push_insn ( block, Insn :: LoadField {
3074+ recv,
3075+ id : ID ! ( _shape_id) ,
3076+ offset : unsafe { rb_shape_id_offset ( ) } as i32 ,
3077+ return_type : types:: CShape
3078+ } )
3079+ }
3080+
30723081 fn optimize_getivar ( & mut self ) {
30733082 for block in self . rpo ( ) {
30743083 let old_insns = std:: mem:: take ( & mut self . blocks [ block. 0 ] . insns ) ;
@@ -3094,7 +3103,8 @@ impl Function {
30943103 self . push_insn_id ( block, insn_id) ; continue ;
30953104 }
30963105 let self_val = self . push_insn ( block, Insn :: GuardType { val : self_val, guard_type : types:: HeapBasicObject , state } ) ;
3097- let self_val = self . push_insn ( block, Insn :: GuardShape { val : self_val, shape : recv_type. shape ( ) , state } ) ;
3106+ let shape = self . load_shape ( block, self_val) ;
3107+ self . push_insn ( block, Insn :: GuardBitEquals { val : shape, expected : Const :: CShape ( recv_type. shape ( ) ) , state } ) ;
30983108 let mut ivar_index: u16 = 0 ;
30993109 let replacement = if ! unsafe { rb_shape_get_iv_index ( recv_type. shape ( ) . 0 , id, & mut ivar_index) } {
31003110 // If there is no IVAR index, then the ivar was undefined when we
@@ -3148,7 +3158,8 @@ impl Function {
31483158 self . push_insn_id ( block, insn_id) ; continue ;
31493159 }
31503160 let self_val = self . push_insn ( block, Insn :: GuardType { val : self_val, guard_type : types:: HeapBasicObject , state } ) ;
3151- let _ = self . push_insn ( block, Insn :: GuardShape { val : self_val, shape : recv_type. shape ( ) , state } ) ;
3161+ let shape = self . load_shape ( block, self_val) ;
3162+ self . push_insn ( block, Insn :: GuardBitEquals { val : shape, expected : Const :: CShape ( recv_type. shape ( ) ) , state } ) ;
31523163 let mut ivar_index: u16 = 0 ;
31533164 let replacement = if unsafe { rb_shape_get_iv_index ( recv_type. shape ( ) . 0 , id, & mut ivar_index) } {
31543165 self . push_insn ( block, Insn :: Const { val : Const :: Value ( pushval) } )
@@ -3219,7 +3230,8 @@ impl Function {
32193230 // Fall through to emitting the ivar write
32203231 }
32213232 let self_val = self . push_insn ( block, Insn :: GuardType { val : self_val, guard_type : types:: HeapBasicObject , state } ) ;
3222- let self_val = self . push_insn ( block, Insn :: GuardShape { val : self_val, shape : recv_type. shape ( ) , state } ) ;
3233+ let shape = self . load_shape ( block, self_val) ;
3234+ self . push_insn ( block, Insn :: GuardBitEquals { val : shape, expected : Const :: CShape ( recv_type. shape ( ) ) , state } ) ;
32233235 // Current shape contains this ivar
32243236 let ( ivar_storage, offset) = if recv_type. flags ( ) . is_embedded ( ) {
32253237 // See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h
0 commit comments