@@ -1227,12 +1227,6 @@ gen_fields_tbl_bytes(size_t n)
12271227 return offsetof(struct gen_fields_tbl , as .shape .fields ) + n * sizeof (VALUE );
12281228}
12291229
1230- static struct gen_fields_tbl *
1231- gen_fields_tbl_resize (struct gen_fields_tbl * old , uint32_t new_capa )
1232- {
1233- RUBY_ASSERT (new_capa > 0 );
1234- return xrealloc (old , gen_fields_tbl_bytes (new_capa ));
1235- }
12361230
12371231void
12381232rb_mark_generic_ivar (VALUE obj )
@@ -1837,13 +1831,28 @@ generic_ivar_set_shape_fields(VALUE obj, void *data)
18371831 int existing = st_lookup (tbl , (st_data_t )obj , (st_data_t * )& fields_tbl );
18381832
18391833 if (!existing || fields_lookup -> resize ) {
1834+ uint32_t new_capa = RSHAPE_CAPACITY (fields_lookup -> shape_id );
1835+ uint32_t old_capa = RSHAPE_CAPACITY (RSHAPE_PARENT (fields_lookup -> shape_id ));
1836+
18401837 if (existing ) {
18411838 RUBY_ASSERT (RSHAPE_TYPE_P (fields_lookup -> shape_id , SHAPE_IVAR ) || RSHAPE_TYPE_P (fields_lookup -> shape_id , SHAPE_OBJ_ID ));
1842- RUBY_ASSERT (RSHAPE_CAPACITY (RSHAPE_PARENT (fields_lookup -> shape_id )) < RSHAPE_CAPACITY (fields_lookup -> shape_id ));
1839+ RUBY_ASSERT (old_capa < new_capa );
1840+ RUBY_ASSERT (fields_tbl );
1841+ } else {
1842+ RUBY_ASSERT (!fields_tbl );
1843+ RUBY_ASSERT (old_capa == 0 );
18431844 }
1845+ RUBY_ASSERT (new_capa > 0 );
18441846
1845- fields_tbl = gen_fields_tbl_resize (fields_tbl , RSHAPE_CAPACITY (fields_lookup -> shape_id ));
1847+ struct gen_fields_tbl * old_fields_tbl = fields_tbl ;
1848+ fields_tbl = xmalloc (gen_fields_tbl_bytes (new_capa ));
1849+ if (old_fields_tbl ) {
1850+ memcpy (fields_tbl , old_fields_tbl , gen_fields_tbl_bytes (old_capa ));
1851+ }
18461852 st_insert (tbl , (st_data_t )obj , (st_data_t )fields_tbl );
1853+ if (old_fields_tbl ) {
1854+ xfree (old_fields_tbl );
1855+ }
18471856 }
18481857
18491858 if (fields_lookup -> shape_id ) {
@@ -2371,7 +2380,9 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj)
23712380 return ;
23722381 }
23732382
2374- new_fields_tbl = gen_fields_tbl_resize (0 , RSHAPE_CAPACITY (dest_shape_id ));
2383+ uint32_t dest_capa = RSHAPE_CAPACITY (dest_shape_id );
2384+ RUBY_ASSERT (dest_capa > 0 );
2385+ new_fields_tbl = xmalloc (gen_fields_tbl_bytes (dest_capa ));
23752386
23762387 VALUE * src_buf = obj_fields_tbl -> as .shape .fields ;
23772388 VALUE * dest_buf = new_fields_tbl -> as .shape .fields ;
0 commit comments