Skip to content

Commit b284987

Browse files
committed
Cleanup and document shape_id_t layout
1 parent 5bcc639 commit b284987

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

shape.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,7 @@ rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
12611261

12621262
uint8_t flags_heap_index = rb_shape_heap_index(shape_id);
12631263
if (RB_TYPE_P(obj, T_OBJECT)) {
1264+
RUBY_ASSERT(flags_heap_index > 0);
12641265
size_t shape_id_slot_size = rb_shape_tree.capacities[flags_heap_index - 1] * sizeof(VALUE) + sizeof(struct RBasic);
12651266
size_t actual_slot_size = rb_gc_obj_slot_size(obj);
12661267

shape.h

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,39 @@ STATIC_ASSERT(shape_id_num_bits, SHAPE_ID_NUM_BITS == sizeof(shape_id_t) * CHAR_
1212

1313
#define SHAPE_BUFFER_SIZE (1 << SHAPE_ID_OFFSET_NUM_BITS)
1414
#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)
2015

2116
#define SHAPE_ID_HEAP_INDEX_BITS 3
22-
#define SHAPE_ID_HEAP_INDEX_OFFSET (SHAPE_ID_NUM_BITS - SHAPE_ID_HEAP_INDEX_BITS)
2317
#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+
};
2548

2649
// This masks allows to check if a shape_id contains any ivar.
2750
// It rely on ROOT_SHAPE_WITH_OBJ_ID==1.
@@ -229,9 +252,13 @@ rb_shape_heap_index(shape_id_t shape_id)
229252
static inline shape_id_t
230253
rb_shape_root(size_t heap_id)
231254
{
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);
233260

234-
return ROOT_SHAPE_ID | ((heap_index + 1) << SHAPE_ID_HEAP_INDEX_OFFSET);
261+
return ROOT_SHAPE_ID | heap_flags;
235262
}
236263

237264
static inline shape_id_t

0 commit comments

Comments
 (0)