diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2025-06-24 16:09:52 +0200 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2025-06-24 16:19:16 +0100 |
commit | b2849876512c0df4759b589e3f8c2d6065bff2f7 (patch) | |
tree | 53134ae2a3b0b00d98d5dac80d93476c6f65bcf7 /shape.h | |
parent | 5bcc639b341291fe0584d11c6bdd1add29f40087 (diff) |
Cleanup and document `shape_id_t` layout
Diffstat (limited to 'shape.h')
-rw-r--r-- | shape.h | 45 |
1 files changed, 36 insertions, 9 deletions
@@ -12,16 +12,39 @@ STATIC_ASSERT(shape_id_num_bits, SHAPE_ID_NUM_BITS == sizeof(shape_id_t) * CHAR_ #define SHAPE_BUFFER_SIZE (1 << SHAPE_ID_OFFSET_NUM_BITS) #define SHAPE_ID_OFFSET_MASK (SHAPE_BUFFER_SIZE - 1) -#define SHAPE_ID_FLAGS_MASK (shape_id_t)(((1 << (SHAPE_ID_NUM_BITS - SHAPE_ID_OFFSET_NUM_BITS)) - 1) << SHAPE_ID_OFFSET_NUM_BITS) -#define SHAPE_ID_FL_FROZEN (SHAPE_FL_FROZEN << SHAPE_ID_OFFSET_NUM_BITS) -#define SHAPE_ID_FL_HAS_OBJECT_ID (SHAPE_FL_HAS_OBJECT_ID << SHAPE_ID_OFFSET_NUM_BITS) -#define SHAPE_ID_FL_TOO_COMPLEX (SHAPE_FL_TOO_COMPLEX << SHAPE_ID_OFFSET_NUM_BITS) -#define SHAPE_ID_FL_NON_CANONICAL_MASK (SHAPE_FL_NON_CANONICAL_MASK << SHAPE_ID_OFFSET_NUM_BITS) #define SHAPE_ID_HEAP_INDEX_BITS 3 -#define SHAPE_ID_HEAP_INDEX_OFFSET (SHAPE_ID_NUM_BITS - SHAPE_ID_HEAP_INDEX_BITS) #define SHAPE_ID_HEAP_INDEX_MAX ((1 << SHAPE_ID_HEAP_INDEX_BITS) - 1) -#define SHAPE_ID_HEAP_INDEX_MASK (SHAPE_ID_HEAP_INDEX_MAX << SHAPE_ID_HEAP_INDEX_OFFSET) + +#define SHAPE_ID_FL_USHIFT (SHAPE_ID_OFFSET_NUM_BITS + SHAPE_ID_HEAP_INDEX_BITS) +#define SHAPE_ID_HEAP_INDEX_OFFSET SHAPE_ID_FL_USHIFT + +// shape_id_t bits: +// 0-18 SHAPE_ID_OFFSET_MASK +// index in rb_shape_tree.shape_list. Allow to access `rb_shape_t *`. +// 19-21 SHAPE_ID_HEAP_INDEX_MASK +// index in rb_shape_tree.capacities. Allow to access slot size. +// 22 SHAPE_ID_FL_FROZEN +// Whether the object is frozen or not. +// 23 SHAPE_ID_FL_HAS_OBJECT_ID +// Whether the object has an `SHAPE_OBJ_ID` transition. +// 24 SHAPE_ID_FL_TOO_COMPLEX +// The object is backed by a `st_table`. + +enum shape_id_fl_type { +#define RBIMPL_SHAPE_ID_FL(n) (1<<(SHAPE_ID_FL_USHIFT+n)) + + SHAPE_ID_HEAP_INDEX_MASK = RBIMPL_SHAPE_ID_FL(0) | RBIMPL_SHAPE_ID_FL(1) | RBIMPL_SHAPE_ID_FL(2), + + SHAPE_ID_FL_FROZEN = RBIMPL_SHAPE_ID_FL(3), + SHAPE_ID_FL_HAS_OBJECT_ID = RBIMPL_SHAPE_ID_FL(4), + SHAPE_ID_FL_TOO_COMPLEX = RBIMPL_SHAPE_ID_FL(5), + + SHAPE_ID_FL_NON_CANONICAL_MASK = SHAPE_ID_FL_FROZEN | SHAPE_ID_FL_HAS_OBJECT_ID, + SHAPE_ID_FLAGS_MASK = SHAPE_ID_HEAP_INDEX_MASK | SHAPE_ID_FL_NON_CANONICAL_MASK | SHAPE_ID_FL_TOO_COMPLEX, + +#undef RBIMPL_SHAPE_ID_FL +}; // This masks allows to check if a shape_id contains any ivar. // It rely on ROOT_SHAPE_WITH_OBJ_ID==1. @@ -229,9 +252,13 @@ rb_shape_heap_index(shape_id_t shape_id) static inline shape_id_t rb_shape_root(size_t heap_id) { - shape_id_t heap_index = (shape_id_t)heap_id; + shape_id_t heap_index = (shape_id_t)(heap_id + 1); + shape_id_t heap_flags = heap_index << SHAPE_ID_HEAP_INDEX_OFFSET; + + RUBY_ASSERT((heap_flags & SHAPE_ID_HEAP_INDEX_MASK) == heap_flags); + RUBY_ASSERT(rb_shape_heap_index(heap_flags) == heap_index); - return ROOT_SHAPE_ID | ((heap_index + 1) << SHAPE_ID_HEAP_INDEX_OFFSET); + return ROOT_SHAPE_ID | heap_flags; } static inline shape_id_t |