@@ -3056,6 +3056,15 @@ impl Function {
30563056 self . infer_types ( ) ;
30573057 }
30583058
3059+ fn load_shape ( & mut self , block : BlockId , recv : InsnId ) -> InsnId {
3060+ self . push_insn ( block, Insn :: LoadField {
3061+ recv,
3062+ id : ID ! ( _shape_id) ,
3063+ offset : unsafe { rb_shape_id_offset ( ) } as i32 ,
3064+ return_type : types:: CShape
3065+ } )
3066+ }
3067+
30593068 fn optimize_getivar ( & mut self ) {
30603069 for block in self . rpo ( ) {
30613070 let old_insns = std:: mem:: take ( & mut self . blocks [ block. 0 ] . insns ) ;
@@ -3081,7 +3090,8 @@ impl Function {
30813090 self . push_insn_id ( block, insn_id) ; continue ;
30823091 }
30833092 let self_val = self . push_insn ( block, Insn :: GuardType { val : self_val, guard_type : types:: HeapBasicObject , state } ) ;
3084- let self_val = self . push_insn ( block, Insn :: GuardShape { val : self_val, shape : recv_type. shape ( ) , state } ) ;
3093+ let shape = self . load_shape ( block, self_val) ;
3094+ self . push_insn ( block, Insn :: GuardBitEquals { val : shape, expected : Const :: CShape ( recv_type. shape ( ) ) , state } ) ;
30853095 let mut ivar_index: u16 = 0 ;
30863096 let replacement = if ! unsafe { rb_shape_get_iv_index ( recv_type. shape ( ) . 0 , id, & mut ivar_index) } {
30873097 // If there is no IVAR index, then the ivar was undefined when we
@@ -3135,7 +3145,8 @@ impl Function {
31353145 self . push_insn_id ( block, insn_id) ; continue ;
31363146 }
31373147 let self_val = self . push_insn ( block, Insn :: GuardType { val : self_val, guard_type : types:: HeapBasicObject , state } ) ;
3138- let _ = self . push_insn ( block, Insn :: GuardShape { val : self_val, shape : recv_type. shape ( ) , state } ) ;
3148+ let shape = self . load_shape ( block, self_val) ;
3149+ self . push_insn ( block, Insn :: GuardBitEquals { val : shape, expected : Const :: CShape ( recv_type. shape ( ) ) , state } ) ;
31393150 let mut ivar_index: u16 = 0 ;
31403151 let replacement = if unsafe { rb_shape_get_iv_index ( recv_type. shape ( ) . 0 , id, & mut ivar_index) } {
31413152 self . push_insn ( block, Insn :: Const { val : Const :: Value ( pushval) } )
@@ -3206,7 +3217,8 @@ impl Function {
32063217 // Fall through to emitting the ivar write
32073218 }
32083219 let self_val = self . push_insn ( block, Insn :: GuardType { val : self_val, guard_type : types:: HeapBasicObject , state } ) ;
3209- let self_val = self . push_insn ( block, Insn :: GuardShape { val : self_val, shape : recv_type. shape ( ) , state } ) ;
3220+ let shape = self . load_shape ( block, self_val) ;
3221+ self . push_insn ( block, Insn :: GuardBitEquals { val : shape, expected : Const :: CShape ( recv_type. shape ( ) ) , state } ) ;
32103222 // Current shape contains this ivar
32113223 let ( ivar_storage, offset) = if recv_type. flags ( ) . is_embedded ( ) {
32123224 // See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h
0 commit comments