@@ -801,7 +801,7 @@ shape_get_iv_index(rb_shape_t *shape, ID id, attr_index_t *value)
801801}
802802
803803static inline rb_shape_t *
804- shape_get_next (rb_shape_t * shape , enum shape_type shape_type , VALUE obj , ID id , bool emit_warnings )
804+ shape_get_next (rb_shape_t * shape , enum shape_type shape_type , VALUE klass , ID id , bool emit_warnings )
805805{
806806 RUBY_ASSERT (!is_instance_id (id ) || RTEST (rb_sym2str (ID2SYM (id ))));
807807
@@ -812,23 +812,6 @@ shape_get_next(rb_shape_t *shape, enum shape_type shape_type, VALUE obj, ID id,
812812 }
813813#endif
814814
815- VALUE klass ;
816- if (IMEMO_TYPE_P (obj , imemo_fields )) {
817- VALUE owner = rb_imemo_fields_owner (obj );
818- switch (BUILTIN_TYPE (owner )) {
819- case T_CLASS :
820- case T_MODULE :
821- klass = rb_singleton_class (owner );
822- break ;
823- default :
824- klass = rb_obj_class (owner );
825- break ;
826- }
827- }
828- else {
829- klass = rb_obj_class (obj );
830- }
831-
832815 bool allow_new_shape = RCLASS_VARIATION_COUNT (klass ) < SHAPE_MAX_VARIATIONS ;
833816 bool variation_created = false;
834817 rb_shape_t * new_shape = get_next_shape_internal (shape , id , shape_type , & variation_created , allow_new_shape );
@@ -862,6 +845,28 @@ shape_get_next(rb_shape_t *shape, enum shape_type shape_type, VALUE obj, ID id,
862845 return new_shape ;
863846}
864847
848+ static VALUE
849+ obj_get_owner_class (VALUE obj )
850+ {
851+ VALUE klass ;
852+ if (IMEMO_TYPE_P (obj , imemo_fields )) {
853+ VALUE owner = rb_imemo_fields_owner (obj );
854+ switch (BUILTIN_TYPE (owner )) {
855+ case T_CLASS :
856+ case T_MODULE :
857+ klass = rb_singleton_class (owner );
858+ break ;
859+ default :
860+ klass = rb_obj_class (owner );
861+ break ;
862+ }
863+ }
864+ else {
865+ klass = rb_obj_class (obj );
866+ }
867+ return klass ;
868+ }
869+
865870static rb_shape_t *
866871remove_shape_recursive (VALUE obj , rb_shape_t * shape , ID id , rb_shape_t * * removed_shape )
867872{
@@ -884,7 +889,8 @@ remove_shape_recursive(VALUE obj, rb_shape_t *shape, ID id, rb_shape_t **removed
884889 // We found a new parent. Create a child of the new parent that
885890 // has the same attributes as this shape.
886891 if (new_parent ) {
887- rb_shape_t * new_child = shape_get_next (new_parent , shape -> type , obj , shape -> edge_name , true);
892+ VALUE klass = obj_get_owner_class (obj );
893+ rb_shape_t * new_child = shape_get_next (new_parent , shape -> type , klass , shape -> edge_name , true);
888894 RUBY_ASSERT (!new_child || new_child -> capacity <= shape -> capacity );
889895 return new_child ;
890896 }
@@ -933,7 +939,8 @@ rb_shape_transition_add_ivar(VALUE obj, ID id)
933939 shape_id_t original_shape_id = RBASIC_SHAPE_ID (obj );
934940 RUBY_ASSERT (!shape_frozen_p (original_shape_id ));
935941
936- rb_shape_t * next_shape = shape_get_next (RSHAPE (original_shape_id ), SHAPE_IVAR , obj , id , true);
942+ VALUE klass = obj_get_owner_class (obj );
943+ rb_shape_t * next_shape = shape_get_next (RSHAPE (original_shape_id ), SHAPE_IVAR , klass , id , true);
937944 if (next_shape ) {
938945 return shape_id (next_shape , original_shape_id );
939946 }
@@ -948,7 +955,8 @@ rb_shape_transition_add_ivar_no_warnings(VALUE obj, ID id)
948955 shape_id_t original_shape_id = RBASIC_SHAPE_ID (obj );
949956 RUBY_ASSERT (!shape_frozen_p (original_shape_id ));
950957
951- rb_shape_t * next_shape = shape_get_next (RSHAPE (original_shape_id ), SHAPE_IVAR , obj , id , false);
958+ VALUE klass = obj_get_owner_class (obj );
959+ rb_shape_t * next_shape = shape_get_next (RSHAPE (original_shape_id ), SHAPE_IVAR , klass , id , false);
952960 if (next_shape ) {
953961 return shape_id (next_shape , original_shape_id );
954962 }
0 commit comments