@@ -10,6 +10,14 @@ typedef uint32_t shape_id_t;
1010
1111STATIC_ASSERT (shape_id_num_bits , SHAPE_ID_NUM_BITS == sizeof (shape_id_t ) * CHAR_BIT );
1212
13+ enum shape_flags {
14+ SHAPE_FL_FROZEN = 1 << 0 ,
15+ SHAPE_FL_HAS_OBJECT_ID = 1 << 1 ,
16+ SHAPE_FL_TOO_COMPLEX = 1 << 2 ,
17+
18+ SHAPE_FL_NON_CANONICAL_MASK = SHAPE_FL_FROZEN | SHAPE_FL_HAS_OBJECT_ID ,
19+ };
20+
1321#define SHAPE_BUFFER_SIZE (1 << SHAPE_ID_OFFSET_NUM_BITS)
1422#define SHAPE_ID_OFFSET_MASK (SHAPE_BUFFER_SIZE - 1)
1523#define SHAPE_ID_FLAGS_MASK (shape_id_t)(((1 << (SHAPE_ID_NUM_BITS - SHAPE_ID_OFFSET_NUM_BITS)) - 1) << SHAPE_ID_OFFSET_NUM_BITS)
@@ -23,6 +31,11 @@ STATIC_ASSERT(shape_id_num_bits, SHAPE_ID_NUM_BITS == sizeof(shape_id_t) * CHAR_
2331#define SHAPE_ID_HEAP_INDEX_MAX ((1 << SHAPE_ID_HEAP_INDEX_BITS) - 1)
2432#define SHAPE_ID_HEAP_INDEX_MASK (SHAPE_ID_HEAP_INDEX_MAX << SHAPE_ID_HEAP_INDEX_OFFSET)
2533
34+ // This masks allows to check if a shape_id contains any ivar.
35+ // It rely on ROOT_SHAPE_WITH_OBJ_ID==1.
36+ #define SHAPE_ID_HAS_IVAR_MASK 0x27fffe
37+ STATIC_ASSERT (shape_id_has_ivar_mask , SHAPE_ID_HAS_IVAR_MASK == (SHAPE_ID_FL_TOO_COMPLEX | (SHAPE_ID_OFFSET_MASK - 1 )));
38+
2639// The interpreter doesn't care about frozen status or slot size when reading ivars.
2740// So we normalize shape_id by clearing these bits to improve cache hits.
2841// JITs however might care about it.
@@ -72,14 +85,6 @@ enum shape_type {
7285 SHAPE_OBJ_ID ,
7386};
7487
75- enum shape_flags {
76- SHAPE_FL_FROZEN = 1 << 0 ,
77- SHAPE_FL_HAS_OBJECT_ID = 1 << 1 ,
78- SHAPE_FL_TOO_COMPLEX = 1 << 2 ,
79-
80- SHAPE_FL_NON_CANONICAL_MASK = SHAPE_FL_FROZEN | SHAPE_FL_HAS_OBJECT_ID ,
81- };
82-
8388typedef struct {
8489 /* object shapes */
8590 rb_shape_t * shape_list ;
@@ -327,6 +332,18 @@ rb_shape_obj_has_id(VALUE obj)
327332 return rb_shape_has_object_id (RBASIC_SHAPE_ID (obj ));
328333}
329334
335+ static inline bool
336+ rb_shape_has_ivars (shape_id_t shape_id )
337+ {
338+ return shape_id & SHAPE_ID_HAS_IVAR_MASK ;
339+ }
340+
341+ static inline bool
342+ rb_shape_obj_has_ivars (VALUE obj )
343+ {
344+ return rb_shape_has_ivars (RBASIC_SHAPE_ID (obj ));
345+ }
346+
330347// For ext/objspace
331348RUBY_SYMBOL_EXPORT_BEGIN
332349typedef void each_shape_callback (shape_id_t shape_id , void * data );
0 commit comments