@@ -903,7 +903,8 @@ pub enum Insn {
903903 /// Side-exit if the block param has been modified or the block handler for the frame
904904 /// is neither ISEQ nor ifunc, which makes it incompatible with rb_block_param_proxy.
905905 GuardBlockParamProxy { level : u32 , state : InsnId } ,
906- /// Side-exit if val is frozen.
906+ /// Side-exit if val is frozen. Does *not* check if the val is an immediate; assumes that it is
907+ /// a heap object.
907908 GuardNotFrozen { recv : InsnId , state : InsnId } ,
908909 /// Side-exit if left is not greater than or equal to right (both operands are C long).
909910 GuardGreaterEq { left : InsnId , right : InsnId , state : InsnId } ,
@@ -2553,6 +2554,7 @@ impl Function {
25532554 //
25542555 // No need for a GuardShape.
25552556 if let OptimizedMethodType :: StructAset = opt_type {
2557+ // We know that all Struct are HeapObject, so no need to insert a GuardType(HeapObject).
25562558 recv = self . push_insn ( block, Insn :: GuardNotFrozen { recv, state } ) ;
25572559 }
25582560
@@ -4150,7 +4152,6 @@ impl Function {
41504152 | Insn :: IsNil { val }
41514153 | Insn :: IsMethodCfunc { val, .. }
41524154 | Insn :: GuardShape { val, .. }
4153- | Insn :: GuardNotFrozen { recv : val, .. }
41544155 | Insn :: SetGlobal { val, .. }
41554156 | Insn :: SetLocal { val, .. }
41564157 | Insn :: SetClassVar { val, .. }
@@ -4169,6 +4170,9 @@ impl Function {
41694170 | Insn :: DefinedIvar { self_val : val, .. } => {
41704171 self . assert_subtype ( insn_id, val, types:: BasicObject )
41714172 }
4173+ Insn :: GuardNotFrozen { recv, .. } => {
4174+ self . assert_subtype ( insn_id, recv, types:: HeapBasicObject )
4175+ }
41724176 // Instructions with 2 Ruby object operands
41734177 Insn :: SetIvar { self_val : left, val : right, .. }
41744178 | Insn :: NewRange { low : left, high : right, .. }
0 commit comments