@@ -12,16 +12,39 @@ STATIC_ASSERT(shape_id_num_bits, SHAPE_ID_NUM_BITS == sizeof(shape_id_t) * CHAR_
12
12
13
13
#define SHAPE_BUFFER_SIZE (1 << SHAPE_ID_OFFSET_NUM_BITS)
14
14
#define SHAPE_ID_OFFSET_MASK (SHAPE_BUFFER_SIZE - 1)
15
- #define SHAPE_ID_FLAGS_MASK (shape_id_t)(((1 << (SHAPE_ID_NUM_BITS - SHAPE_ID_OFFSET_NUM_BITS)) - 1) << SHAPE_ID_OFFSET_NUM_BITS)
16
- #define SHAPE_ID_FL_FROZEN (SHAPE_FL_FROZEN << SHAPE_ID_OFFSET_NUM_BITS)
17
- #define SHAPE_ID_FL_HAS_OBJECT_ID (SHAPE_FL_HAS_OBJECT_ID << SHAPE_ID_OFFSET_NUM_BITS)
18
- #define SHAPE_ID_FL_TOO_COMPLEX (SHAPE_FL_TOO_COMPLEX << SHAPE_ID_OFFSET_NUM_BITS)
19
- #define SHAPE_ID_FL_NON_CANONICAL_MASK (SHAPE_FL_NON_CANONICAL_MASK << SHAPE_ID_OFFSET_NUM_BITS)
20
15
21
16
#define SHAPE_ID_HEAP_INDEX_BITS 3
22
- #define SHAPE_ID_HEAP_INDEX_OFFSET (SHAPE_ID_NUM_BITS - SHAPE_ID_HEAP_INDEX_BITS)
23
17
#define SHAPE_ID_HEAP_INDEX_MAX ((1 << SHAPE_ID_HEAP_INDEX_BITS) - 1)
24
- #define SHAPE_ID_HEAP_INDEX_MASK (SHAPE_ID_HEAP_INDEX_MAX << SHAPE_ID_HEAP_INDEX_OFFSET)
18
+
19
+ #define SHAPE_ID_FL_USHIFT (SHAPE_ID_OFFSET_NUM_BITS + SHAPE_ID_HEAP_INDEX_BITS)
20
+ #define SHAPE_ID_HEAP_INDEX_OFFSET SHAPE_ID_FL_USHIFT
21
+
22
+ // shape_id_t bits:
23
+ // 0-18 SHAPE_ID_OFFSET_MASK
24
+ // index in rb_shape_tree.shape_list. Allow to access `rb_shape_t *`.
25
+ // 19-21 SHAPE_ID_HEAP_INDEX_MASK
26
+ // index in rb_shape_tree.capacities. Allow to access slot size.
27
+ // 22 SHAPE_ID_FL_FROZEN
28
+ // Whether the object is frozen or not.
29
+ // 23 SHAPE_ID_FL_HAS_OBJECT_ID
30
+ // Whether the object has an `SHAPE_OBJ_ID` transition.
31
+ // 24 SHAPE_ID_FL_TOO_COMPLEX
32
+ // The object is backed by a `st_table`.
33
+
34
+ enum shape_id_fl_type {
35
+ #define RBIMPL_SHAPE_ID_FL(n) (1<<(SHAPE_ID_FL_USHIFT+n))
36
+
37
+ SHAPE_ID_HEAP_INDEX_MASK = RBIMPL_SHAPE_ID_FL (0 ) | RBIMPL_SHAPE_ID_FL (1 ) | RBIMPL_SHAPE_ID_FL (2 ),
38
+
39
+ SHAPE_ID_FL_FROZEN = RBIMPL_SHAPE_ID_FL (3 ),
40
+ SHAPE_ID_FL_HAS_OBJECT_ID = RBIMPL_SHAPE_ID_FL (4 ),
41
+ SHAPE_ID_FL_TOO_COMPLEX = RBIMPL_SHAPE_ID_FL (5 ),
42
+
43
+ SHAPE_ID_FL_NON_CANONICAL_MASK = SHAPE_ID_FL_FROZEN | SHAPE_ID_FL_HAS_OBJECT_ID ,
44
+ SHAPE_ID_FLAGS_MASK = SHAPE_ID_HEAP_INDEX_MASK | SHAPE_ID_FL_NON_CANONICAL_MASK | SHAPE_ID_FL_TOO_COMPLEX ,
45
+
46
+ #undef RBIMPL_SHAPE_ID_FL
47
+ };
25
48
26
49
// This masks allows to check if a shape_id contains any ivar.
27
50
// It rely on ROOT_SHAPE_WITH_OBJ_ID==1.
@@ -229,9 +252,13 @@ rb_shape_heap_index(shape_id_t shape_id)
229
252
static inline shape_id_t
230
253
rb_shape_root (size_t heap_id )
231
254
{
232
- shape_id_t heap_index = (shape_id_t )heap_id ;
255
+ shape_id_t heap_index = (shape_id_t )(heap_id + 1 );
256
+ shape_id_t heap_flags = heap_index << SHAPE_ID_HEAP_INDEX_OFFSET ;
257
+
258
+ RUBY_ASSERT ((heap_flags & SHAPE_ID_HEAP_INDEX_MASK ) == heap_flags );
259
+ RUBY_ASSERT (rb_shape_heap_index (heap_flags ) == heap_index );
233
260
234
- return ROOT_SHAPE_ID | (( heap_index + 1 ) << SHAPE_ID_HEAP_INDEX_OFFSET ) ;
261
+ return ROOT_SHAPE_ID | heap_flags ;
235
262
}
236
263
237
264
static inline shape_id_t
0 commit comments