@@ -1670,6 +1670,22 @@ imemo_fields_complex_from_obj(VALUE klass, VALUE source_fields_obj, shape_id_t s
16701670 return fields_obj ;
16711671}
16721672
1673+ static VALUE
1674+ imemo_fields_copy_capa (VALUE klass , VALUE source_fields_obj , attr_index_t new_size )
1675+ {
1676+ VALUE fields_obj = rb_imemo_fields_new (klass , new_size );
1677+ if (source_fields_obj ) {
1678+ attr_index_t fields_count = RSHAPE_LEN (RBASIC_SHAPE_ID (source_fields_obj ));
1679+ VALUE * fields = rb_imemo_fields_ptr (fields_obj );
1680+ MEMCPY (fields , rb_imemo_fields_ptr (source_fields_obj ), VALUE , fields_count );
1681+ RBASIC_SET_SHAPE_ID (fields_obj , RBASIC_SHAPE_ID (source_fields_obj ));
1682+ for (attr_index_t i = 0 ; i < fields_count ; i ++ ) {
1683+ RB_OBJ_WRITTEN (fields_obj , Qundef , fields [i ]);
1684+ }
1685+ }
1686+ return fields_obj ;
1687+ }
1688+
16731689void rb_obj_copy_fields_to_hash_table (VALUE obj , st_table * table );
16741690
16751691// Copy all object fields, including ivars and internal object_id, etc
@@ -1846,15 +1862,7 @@ imemo_fields_set(VALUE klass, VALUE fields_obj, shape_id_t target_shape_id, ID f
18461862 else {
18471863 attr_index_t index = RSHAPE_INDEX (target_shape_id );
18481864 if (concurrent || index >= RSHAPE_CAPACITY (current_shape_id )) {
1849- fields_obj = rb_imemo_fields_new (klass , RSHAPE_CAPACITY (target_shape_id ));
1850- if (original_fields_obj ) {
1851- attr_index_t fields_count = RSHAPE_LEN (current_shape_id );
1852- VALUE * fields = rb_imemo_fields_ptr (fields_obj );
1853- MEMCPY (fields , rb_imemo_fields_ptr (original_fields_obj ), VALUE , fields_count );
1854- for (attr_index_t i = 0 ; i < fields_count ; i ++ ) {
1855- RB_OBJ_WRITTEN (fields_obj , Qundef , fields [i ]);
1856- }
1857- }
1865+ fields_obj = imemo_fields_copy_capa (klass , original_fields_obj , RSHAPE_CAPACITY (target_shape_id ));
18581866 }
18591867
18601868 VALUE * table = rb_imemo_fields_ptr (fields_obj );
@@ -4677,15 +4685,7 @@ class_fields_ivar_set(VALUE klass, VALUE fields_obj, ID id, VALUE val, bool conc
46774685
46784686 // We allocate a new fields_obj even when concurrency isn't a concern
46794687 // so that we're embedded as long as possible.
4680- fields_obj = rb_imemo_fields_new (rb_singleton_class (klass ), next_capacity );
4681- if (original_fields_obj ) {
4682- VALUE * fields = rb_imemo_fields_ptr (fields_obj );
4683- attr_index_t fields_count = RSHAPE_LEN (current_shape_id );
4684- MEMCPY (fields , rb_imemo_fields_ptr (original_fields_obj ), VALUE , fields_count );
4685- for (attr_index_t i = 0 ; i < fields_count ; i ++ ) {
4686- RB_OBJ_WRITTEN (fields_obj , Qundef , fields [i ]);
4687- }
4688- }
4688+ fields_obj = imemo_fields_copy_capa (rb_singleton_class (klass ), fields_obj , next_capacity );
46894689 }
46904690
46914691 RUBY_ASSERT (RSHAPE (next_shape_id )-> type == SHAPE_IVAR );
0 commit comments