@@ -1092,7 +1092,10 @@ rb_shape_traverse_from_new_root(shape_id_t initial_shape_id, shape_id_t dest_sha
10921092{
10931093 rb_shape_t * initial_shape = RSHAPE (initial_shape_id );
10941094 rb_shape_t * dest_shape = RSHAPE (dest_shape_id );
1095- return shape_id (shape_traverse_from_new_root (initial_shape , dest_shape ), dest_shape_id );
1095+
1096+ // Keep all dest_shape_id flags except for the heap_index.
1097+ shape_id_t dest_flags = (dest_shape_id & ~SHAPE_ID_HEAP_INDEX_MASK ) | (initial_shape_id & SHAPE_ID_HEAP_INDEX_MASK );
1098+ return shape_id (shape_traverse_from_new_root (initial_shape , dest_shape ), dest_flags );
10961099}
10971100
10981101// Rebuild a similar shape with the same ivars but starting from
@@ -1136,7 +1139,7 @@ rb_shape_rebuild(shape_id_t initial_shape_id, shape_id_t dest_shape_id)
11361139 RUBY_ASSERT (!rb_shape_too_complex_p (initial_shape_id ));
11371140 RUBY_ASSERT (!rb_shape_too_complex_p (dest_shape_id ));
11381141
1139- return raw_shape_id (shape_rebuild (RSHAPE (initial_shape_id ), RSHAPE (dest_shape_id )));
1142+ return shape_id (shape_rebuild (RSHAPE (initial_shape_id ), RSHAPE (dest_shape_id )), initial_shape_id );
11401143}
11411144
11421145void
@@ -1238,6 +1241,14 @@ rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
12381241 }
12391242 }
12401243
1244+ // All complex shape are in heap_index=0, it's a limitation
1245+ if (!rb_shape_too_complex_p (shape_id )) {
1246+ uint8_t flags_heap_index = rb_shape_heap_index (shape_id );
1247+ if (flags_heap_index != shape -> heap_index ) {
1248+ rb_bug ("shape_id heap_index flags mismatch: flags=%u, transition=%u\n" , flags_heap_index , shape -> heap_index );
1249+ }
1250+ }
1251+
12411252 return true;
12421253}
12431254#endif
@@ -1288,6 +1299,7 @@ shape_id_t_to_rb_cShape(shape_id_t shape_id)
12881299
12891300 VALUE obj = rb_struct_new (rb_cShape ,
12901301 INT2NUM (shape_id ),
1302+ INT2NUM (shape_id & SHAPE_ID_OFFSET_MASK ),
12911303 INT2NUM (shape -> parent_id ),
12921304 rb_shape_edge_name (shape ),
12931305 INT2NUM (shape -> next_field_index ),
@@ -1528,7 +1540,7 @@ Init_default_shapes(void)
15281540 for (int i = 0 ; sizes [i ] > 0 ; i ++ ) {
15291541 rb_shape_t * t_object_shape = rb_shape_alloc_with_parent_id (0 , INVALID_SHAPE_ID );
15301542 t_object_shape -> type = SHAPE_T_OBJECT ;
1531- t_object_shape -> heap_index = i ;
1543+ t_object_shape -> heap_index = i + 1 ;
15321544 t_object_shape -> capacity = (uint32_t )((sizes [i ] - offsetof(struct RObject , as .ary )) / sizeof (VALUE ));
15331545 t_object_shape -> edges = rb_managed_id_table_new (256 );
15341546 t_object_shape -> ancestor_index = LEAF ;
@@ -1552,6 +1564,7 @@ Init_shape(void)
15521564 * :nodoc: */
15531565 VALUE rb_cShape = rb_struct_define_under (rb_cRubyVM , "Shape" ,
15541566 "id" ,
1567+ "raw_id" ,
15551568 "parent_id" ,
15561569 "edge_name" ,
15571570 "next_field_index" ,
0 commit comments