4#include "internal/gc.h"
6#if (SIZEOF_UINT64_T <= SIZEOF_VALUE)
8#define SIZEOF_SHAPE_T 4
9#define SHAPE_IN_BASIC_FLAGS 1
10typedef uint32_t attr_index_t;
11typedef uint32_t shape_id_t;
12# define SHAPE_ID_NUM_BITS 32
16#define SIZEOF_SHAPE_T 2
17#define SHAPE_IN_BASIC_FLAGS 0
18typedef uint16_t attr_index_t;
19typedef uint16_t shape_id_t;
20# define SHAPE_ID_NUM_BITS 16
24typedef uint32_t redblack_id_t;
26#define SHAPE_MAX_FIELDS (attr_index_t)(-1)
28# define SHAPE_FLAG_MASK (((VALUE)-1) >> SHAPE_ID_NUM_BITS)
30# define SHAPE_FLAG_SHIFT ((SIZEOF_VALUE * 8) - SHAPE_ID_NUM_BITS)
32# define SHAPE_MAX_VARIATIONS 8
34# define INVALID_SHAPE_ID (((uintptr_t)1 << SHAPE_ID_NUM_BITS) - 1)
36#define ROOT_SHAPE_ID 0x0
37#define SPECIAL_CONST_SHAPE_ID 0x1
39#define FIRST_T_OBJECT_SHAPE_ID 0x3
41extern ID ruby_internal_object_id;
48 attr_index_t next_field_index;
49 attr_index_t capacity;
72 SHAPE_OBJ_TOO_COMPLEX,
79 shape_id_t next_shape_id;
82 unsigned int cache_size;
87rb_current_shape_tree(
void)
89 return rb_shape_tree_ptr;
91#define GET_SHAPE_TREE() rb_current_shape_tree()
93static inline shape_id_t
94get_shape_id_from_flags(
VALUE obj)
98 return (shape_id_t)((
RBASIC(obj)->flags) >> SHAPE_FLAG_SHIFT);
102set_shape_id_in_flags(
VALUE obj, shape_id_t shape_id)
108 RBASIC(obj)->flags &= SHAPE_FLAG_MASK;
109 RBASIC(obj)->flags |= ((
VALUE)(shape_id) << SHAPE_FLAG_SHIFT);
113#if SHAPE_IN_BASIC_FLAGS
114static inline shape_id_t
115RBASIC_SHAPE_ID(
VALUE obj)
117 return get_shape_id_from_flags(obj);
121RBASIC_SET_SHAPE_ID(
VALUE obj, shape_id_t shape_id)
123 set_shape_id_in_flags(obj, shape_id);
127static inline shape_id_t
128ROBJECT_SHAPE_ID(
VALUE obj)
131 return get_shape_id_from_flags(obj);
135ROBJECT_SET_SHAPE_ID(
VALUE obj, shape_id_t shape_id)
138 set_shape_id_in_flags(obj, shape_id);
141static inline shape_id_t
142RCLASS_SHAPE_ID(
VALUE obj)
145 return get_shape_id_from_flags(obj);
149RCLASS_SET_SHAPE_ID(
VALUE obj, shape_id_t shape_id)
152 set_shape_id_in_flags(obj, shape_id);
155#define RSHAPE rb_shape_lookup
157int32_t rb_shape_id_offset(
void);
159RUBY_FUNC_EXPORTED
rb_shape_t *rb_shape_lookup(shape_id_t shape_id);
160RUBY_FUNC_EXPORTED shape_id_t rb_obj_shape_id(
VALUE obj);
161shape_id_t rb_shape_get_next_iv_shape(shape_id_t shape_id,
ID id);
162bool rb_shape_get_iv_index(
rb_shape_t *shape,
ID id, attr_index_t *value);
163bool rb_shape_get_iv_index_with_hint(shape_id_t shape_id,
ID id, attr_index_t *value, shape_id_t *shape_id_hint);
164RUBY_FUNC_EXPORTED
bool rb_shape_obj_too_complex_p(
VALUE obj);
165bool rb_shape_too_complex_p(
rb_shape_t *shape);
166bool rb_shape_id_too_complex_p(shape_id_t shape_id);
169shape_id_t rb_shape_transition_frozen(
VALUE obj);
170shape_id_t rb_shape_transition_complex(
VALUE obj);
171bool rb_shape_transition_remove_ivar(
VALUE obj,
ID id,
VALUE *removed);
172shape_id_t rb_shape_transition_add_ivar(
VALUE obj,
ID id);
173shape_id_t rb_shape_transition_add_ivar_no_warnings(
VALUE obj,
ID id);
174shape_id_t rb_shape_transition_object_id(
VALUE obj);
176bool rb_shape_has_object_id(
rb_shape_t *shape);
177void rb_shape_free_all(
void);
182rb_obj_shape(
VALUE obj)
184 return RSHAPE(rb_obj_shape_id(obj));
190 return !shape->flags;
193static inline shape_id_t
194rb_shape_root(
size_t heap_id)
196 return (shape_id_t)(heap_id + FIRST_T_OBJECT_SHAPE_ID);
199static inline uint32_t
200ROBJECT_FIELDS_CAPACITY(
VALUE obj)
206 return RSHAPE(ROBJECT_SHAPE_ID(obj))->capacity;
210ROBJECT_FIELDS_HASH(
VALUE obj)
225size_t rb_id_table_size(
const struct rb_id_table *tbl);
227static inline uint32_t
228ROBJECT_FIELDS_COUNT(
VALUE obj)
230 if (rb_shape_obj_too_complex_p(obj)) {
231 return (uint32_t)rb_st_table_size(ROBJECT_FIELDS_HASH(obj));
236 return RSHAPE(ROBJECT_SHAPE_ID(obj))->next_field_index;
240static inline uint32_t
241RBASIC_FIELDS_COUNT(
VALUE obj)
243 return RSHAPE(rb_obj_shape_id(obj))->next_field_index;
246shape_id_t rb_shape_traverse_from_new_root(shape_id_t initial_shape_id, shape_id_t orig_shape_id);
248bool rb_shape_set_shape_id(
VALUE obj, shape_id_t shape_id);
251rb_shape_obj_has_id(
VALUE obj)
253 return rb_shape_has_object_id(rb_obj_shape(obj));
257RUBY_SYMBOL_EXPORT_BEGIN
258typedef void each_shape_callback(
rb_shape_t *shape,
void *data);
259void rb_shape_each_shape(each_shape_callback callback,
void *data);
260size_t rb_shape_memsize(shape_id_t shape);
261size_t rb_shape_edges_count(shape_id_t shape_id);
262size_t rb_shape_depth(shape_id_t shape_id);
264RUBY_SYMBOL_EXPORT_END
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define RUBY_EXTERN
Declaration of externally visible global variables.
#define T_IMEMO
Old name of RUBY_T_IMEMO.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define T_CLASS
Old name of RUBY_T_CLASS.
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RBASIC(obj)
Convenient casting macro.
#define ROBJECT(obj)
Convenient casting macro.
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.