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 MAX_IVARS (attr_index_t)(-1)
28# define SHAPE_MASK (((uintptr_t)1 << SHAPE_ID_NUM_BITS) - 1)
29# define SHAPE_FLAG_MASK (((VALUE)-1) >> SHAPE_ID_NUM_BITS)
31# define SHAPE_FLAG_SHIFT ((SIZEOF_VALUE * 8) - SHAPE_ID_NUM_BITS)
33# define SHAPE_MAX_VARIATIONS 8
35# define INVALID_SHAPE_ID SHAPE_MASK
36# define ROOT_SHAPE_ID 0x0
38# define SPECIAL_CONST_SHAPE_ID (SIZE_POOL_COUNT * 2)
39# define OBJ_TOO_COMPLEX_SHAPE_ID (SPECIAL_CONST_SHAPE_ID + 1)
46 attr_index_t next_iv_index;
49 uint8_t size_pool_index;
51 redblack_node_t * ancestor_index;
68 SHAPE_OBJ_TOO_COMPLEX,
73 rb_shape_t *shape_list;
74 rb_shape_t *root_shape;
75 shape_id_t next_shape_id;
77 redblack_node_t *shape_cache;
78 unsigned int cache_size;
83rb_current_shape_tree(
void)
85 return rb_shape_tree_ptr;
87#define GET_SHAPE_TREE() rb_current_shape_tree()
89static inline shape_id_t
90get_shape_id_from_flags(
VALUE obj)
93 return (shape_id_t)(SHAPE_MASK & ((
RBASIC(obj)->flags) >> SHAPE_FLAG_SHIFT));
97set_shape_id_in_flags(
VALUE obj, shape_id_t shape_id)
101 RBASIC(obj)->flags &= SHAPE_FLAG_MASK;
102 RBASIC(obj)->flags |= ((
VALUE)(shape_id) << SHAPE_FLAG_SHIFT);
106#if SHAPE_IN_BASIC_FLAGS
107static inline shape_id_t
108RBASIC_SHAPE_ID(
VALUE obj)
110 return get_shape_id_from_flags(obj);
114RBASIC_SET_SHAPE_ID(
VALUE obj, shape_id_t shape_id)
116 set_shape_id_in_flags(obj, shape_id);
120static inline shape_id_t
121ROBJECT_SHAPE_ID(
VALUE obj)
124 return get_shape_id_from_flags(obj);
128ROBJECT_SET_SHAPE_ID(
VALUE obj, shape_id_t shape_id)
131 set_shape_id_in_flags(obj, shape_id);
134static inline shape_id_t
135RCLASS_SHAPE_ID(
VALUE obj)
138 return get_shape_id_from_flags(obj);
142RCLASS_SET_SHAPE_ID(
VALUE obj, shape_id_t shape_id)
145 set_shape_id_in_flags(obj, shape_id);
148rb_shape_t * rb_shape_get_root_shape(
void);
149int32_t rb_shape_id_offset(
void);
151rb_shape_t * rb_shape_get_parent(rb_shape_t * shape);
153rb_shape_t* rb_shape_get_shape_by_id(shape_id_t shape_id);
154shape_id_t rb_shape_get_shape_id(
VALUE obj);
155rb_shape_t * rb_shape_get_next_iv_shape(rb_shape_t * shape,
ID id);
156bool rb_shape_get_iv_index(rb_shape_t * shape,
ID id, attr_index_t * value);
157bool rb_shape_get_iv_index_with_hint(shape_id_t shape_id,
ID id, attr_index_t * value, shape_id_t *shape_id_hint);
158bool rb_shape_obj_too_complex(
VALUE obj);
160void rb_shape_set_shape(
VALUE obj, rb_shape_t* shape);
161rb_shape_t* rb_shape_get_shape(
VALUE obj);
162int rb_shape_frozen_shape_p(rb_shape_t* shape);
163rb_shape_t* rb_shape_transition_shape_frozen(
VALUE obj);
164bool rb_shape_transition_shape_remove_ivar(
VALUE obj,
ID id, rb_shape_t *shape,
VALUE * removed);
165rb_shape_t* rb_shape_get_next(rb_shape_t* shape,
VALUE obj,
ID id);
166rb_shape_t* rb_shape_get_next_no_warnings(rb_shape_t* shape,
VALUE obj,
ID id);
168rb_shape_t * rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape);
170static inline uint32_t
171ROBJECT_IV_CAPACITY(
VALUE obj)
177 return rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj))->capacity;
180static inline st_table *
181ROBJECT_IV_HASH(
VALUE obj)
185 return (st_table *)
ROBJECT(obj)->as.heap.ivptr;
189ROBJECT_SET_IV_HASH(
VALUE obj,
const st_table *tbl)
196size_t rb_id_table_size(
const struct rb_id_table *tbl);
198static inline uint32_t
199ROBJECT_IV_COUNT(
VALUE obj)
201 if (rb_shape_obj_too_complex(obj)) {
202 return (uint32_t)rb_st_table_size(ROBJECT_IV_HASH(obj));
207 return rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj))->next_iv_index;
211static inline uint32_t
212RBASIC_IV_COUNT(
VALUE obj)
214 return rb_shape_get_shape_by_id(rb_shape_get_shape_id(obj))->next_iv_index;
217rb_shape_t *rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *orig_shape);
219bool rb_shape_set_shape_id(
VALUE obj, shape_id_t shape_id);
224RUBY_SYMBOL_EXPORT_BEGIN
225typedef void each_shape_callback(rb_shape_t * shape,
void *data);
226void rb_shape_each_shape(each_shape_callback callback,
void *data);
227size_t rb_shape_memsize(rb_shape_t *shape);
228size_t rb_shape_edges_count(rb_shape_t *shape);
229size_t rb_shape_depth(rb_shape_t *shape);
230shape_id_t rb_shape_id(rb_shape_t * shape);
231RUBY_SYMBOL_EXPORT_END
#define RUBY_ASSERT(expr)
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_MODULE
Old name of RUBY_T_MODULE.
#define T_CLASS
Old name of RUBY_T_CLASS.
#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.