@@ -1090,7 +1090,10 @@ rb_shape_traverse_from_new_root(shape_id_t initial_shape_id, shape_id_t dest_sha
10901090{
10911091 rb_shape_t * initial_shape = RSHAPE (initial_shape_id );
10921092 rb_shape_t * dest_shape = RSHAPE (dest_shape_id );
1093- return shape_id (shape_traverse_from_new_root (initial_shape , dest_shape ), dest_shape_id );
1093+
1094+ // Keep all dest_shape_id flags except for the heap_index.
1095+ shape_id_t dest_flags = (dest_shape_id & ~SHAPE_ID_HEAP_INDEX_MASK ) | (initial_shape_id & SHAPE_ID_HEAP_INDEX_MASK );
1096+ return shape_id (shape_traverse_from_new_root (initial_shape , dest_shape ), dest_flags );
10941097}
10951098
10961099// Rebuild a similar shape with the same ivars but starting from
@@ -1134,7 +1137,7 @@ rb_shape_rebuild(shape_id_t initial_shape_id, shape_id_t dest_shape_id)
11341137 RUBY_ASSERT (!rb_shape_too_complex_p (initial_shape_id ));
11351138 RUBY_ASSERT (!rb_shape_too_complex_p (dest_shape_id ));
11361139
1137- return raw_shape_id (shape_rebuild (RSHAPE (initial_shape_id ), RSHAPE (dest_shape_id )));
1140+ return shape_id (shape_rebuild (RSHAPE (initial_shape_id ), RSHAPE (dest_shape_id )), initial_shape_id );
11381141}
11391142
11401143void
@@ -1236,6 +1239,14 @@ rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
12361239 }
12371240 }
12381241
1242+ // All complex shape are in heap_index=0, it's a limitation
1243+ if (!rb_shape_too_complex_p (shape_id )) {
1244+ uint8_t flags_heap_index = rb_shape_heap_index (shape_id );
1245+ if (flags_heap_index != shape -> heap_index ) {
1246+ rb_bug ("shape_id heap_index flags mismatch: flags=%u, transition=%u\n" , flags_heap_index , shape -> heap_index );
1247+ }
1248+ }
1249+
12391250 return true;
12401251}
12411252#endif
@@ -1286,6 +1297,7 @@ shape_id_t_to_rb_cShape(shape_id_t shape_id)
12861297
12871298 VALUE obj = rb_struct_new (rb_cShape ,
12881299 INT2NUM (shape_id ),
1300+ INT2NUM (shape_id & SHAPE_ID_OFFSET_MASK ),
12891301 INT2NUM (shape -> parent_id ),
12901302 rb_shape_edge_name (shape ),
12911303 INT2NUM (shape -> next_field_index ),
@@ -1526,7 +1538,7 @@ Init_default_shapes(void)
15261538 for (int i = 0 ; sizes [i ] > 0 ; i ++ ) {
15271539 rb_shape_t * t_object_shape = rb_shape_alloc_with_parent_id (0 , INVALID_SHAPE_ID );
15281540 t_object_shape -> type = SHAPE_T_OBJECT ;
1529- t_object_shape -> heap_index = i ;
1541+ t_object_shape -> heap_index = i + 1 ;
15301542 t_object_shape -> capacity = (uint32_t )((sizes [i ] - offsetof(struct RObject , as .ary )) / sizeof (VALUE ));
15311543 t_object_shape -> edges = rb_managed_id_table_new (256 );
15321544 t_object_shape -> ancestor_index = LEAF ;
@@ -1550,6 +1562,7 @@ Init_shape(void)
15501562 * :nodoc: */
15511563 VALUE rb_cShape = rb_struct_define_under (rb_cRubyVM , "Shape" ,
15521564 "id" ,
1565+ "raw_id" ,
15531566 "parent_id" ,
15541567 "edge_name" ,
15551568 "next_field_index" ,
0 commit comments