Refactor rb_obj_shape out.

It still exists but only in `shape.c`.
This commit is contained in:
Jean Boussier 2025-05-27 13:16:50 +02:00
parent 97f44ac54e
commit a80a5000ab
Notes: git 2025-05-27 13:34:18 +00:00
5 changed files with 65 additions and 36 deletions

2
gc.c
View File

@ -1894,7 +1894,7 @@ object_id0(VALUE obj)
{
VALUE id = Qfalse;
if (rb_shape_has_object_id(rb_obj_shape(obj))) {
if (rb_shape_id_has_object_id(RBASIC_SHAPE_ID(obj))) {
shape_id_t object_id_shape_id = rb_shape_transition_object_id(obj);
id = rb_obj_field_get(obj, object_id_shape_id);
RUBY_ASSERT(id, "object_id missing");

View File

@ -128,7 +128,7 @@ rb_class_allocate_instance(VALUE klass)
T_OBJECT | ROBJECT_EMBED | (RGENGC_WB_PROTECTED_OBJECT ? FL_WB_PROTECTED : 0), size, 0);
VALUE obj = (VALUE)o;
RUBY_ASSERT(rb_obj_shape(obj)->type == SHAPE_ROOT);
RUBY_ASSERT(RSHAPE_TYPE_P(RBASIC_SHAPE_ID(obj), SHAPE_ROOT));
RBASIC_SET_SHAPE_ID(obj, rb_shape_root(rb_gc_heap_id_for_size(size)));

18
shape.c
View File

@ -372,6 +372,12 @@ rb_shape_depth(shape_id_t shape_id)
return depth;
}
static inline rb_shape_t *
obj_shape(VALUE obj)
{
return RSHAPE(rb_obj_shape_id(obj));
}
static rb_shape_t *
shape_alloc(void)
{
@ -676,7 +682,7 @@ shape_transition_too_complex(rb_shape_t *original_shape)
shape_id_t
rb_shape_transition_complex(VALUE obj)
{
rb_shape_t *original_shape = rb_obj_shape(obj);
rb_shape_t *original_shape = obj_shape(obj);
return rb_shape_id(shape_transition_too_complex(original_shape));
}
@ -695,7 +701,7 @@ rb_shape_id_has_object_id(shape_id_t shape_id)
shape_id_t
rb_shape_transition_object_id(VALUE obj)
{
rb_shape_t* shape = rb_obj_shape(obj);
rb_shape_t* shape = obj_shape(obj);
RUBY_ASSERT(shape);
if (shape->flags & SHAPE_FL_HAS_OBJECT_ID) {
@ -817,13 +823,13 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
shape_id_t
rb_shape_transition_add_ivar(VALUE obj, ID id)
{
return rb_shape_id(shape_get_next(rb_obj_shape(obj), obj, id, true));
return rb_shape_id(shape_get_next(obj_shape(obj), obj, id, true));
}
shape_id_t
rb_shape_transition_add_ivar_no_warnings(VALUE obj, ID id)
{
return rb_shape_id(shape_get_next(rb_obj_shape(obj), obj, id, false));
return rb_shape_id(shape_get_next(obj_shape(obj), obj, id, false));
}
// Same as rb_shape_get_iv_index, but uses a provided valid shape id and index
@ -1085,7 +1091,7 @@ rb_shape_copy_complex_ivars(VALUE dest, VALUE obj, shape_id_t src_shape_id, st_t
RUBY_FUNC_EXPORTED bool
rb_shape_obj_too_complex_p(VALUE obj)
{
return rb_shape_too_complex_p(rb_obj_shape(obj));
return rb_shape_too_complex_p(obj_shape(obj));
}
bool
@ -1248,7 +1254,7 @@ rb_shape_parent(VALUE self)
static VALUE
rb_shape_debug_shape(VALUE self, VALUE obj)
{
return rb_shape_t_to_rb_cShape(rb_obj_shape(obj));
return rb_shape_t_to_rb_cShape(obj_shape(obj));
}
static VALUE

38
shape.h
View File

@ -143,12 +143,6 @@ shape_id_t rb_shape_rebuild(shape_id_t initial_shape_id, shape_id_t dest_shape_i
void rb_shape_copy_fields(VALUE dest, VALUE *dest_buf, shape_id_t dest_shape_id, VALUE src, VALUE *src_buf, shape_id_t src_shape_id);
void rb_shape_copy_complex_ivars(VALUE dest, VALUE obj, shape_id_t src_shape_id, st_table *fields_table);
static inline rb_shape_t *
rb_obj_shape(VALUE obj)
{
return RSHAPE(rb_obj_shape_id(obj));
}
static inline bool
rb_shape_id_canonical_p(shape_id_t shape_id)
{
@ -161,6 +155,36 @@ rb_shape_root(size_t heap_id)
return (shape_id_t)(heap_id + FIRST_T_OBJECT_SHAPE_ID);
}
static inline bool
RSHAPE_TYPE_P(shape_id_t shape_id, enum shape_type type)
{
return RSHAPE(shape_id)->type == type;
}
static inline attr_index_t
RSHAPE_CAPACITY(shape_id_t shape_id)
{
return RSHAPE(shape_id)->capacity;
}
static inline attr_index_t
RSHAPE_LEN(shape_id_t shape_id)
{
return RSHAPE(shape_id)->next_field_index;
}
static inline attr_index_t
RSHAPE_INDEX(shape_id_t shape_id)
{
return RSHAPE_LEN(shape_id) - 1;
}
static inline ID
RSHAPE_EDGE_NAME(shape_id_t shape_id)
{
return RSHAPE(shape_id)->edge_name;
}
static inline uint32_t
ROBJECT_FIELDS_CAPACITY(VALUE obj)
{
@ -213,7 +237,7 @@ bool rb_shape_set_shape_id(VALUE obj, shape_id_t shape_id);
static inline bool
rb_shape_obj_has_id(VALUE obj)
{
return rb_shape_has_object_id(rb_obj_shape(obj));
return rb_shape_id_has_object_id(RBASIC_SHAPE_ID(obj));
}
// For ext/objspace

View File

@ -1660,7 +1660,7 @@ rb_obj_init_too_complex(VALUE obj, st_table *table)
// This method is meant to be called on newly allocated object.
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
RUBY_ASSERT(rb_shape_id_canonical_p(RBASIC_SHAPE_ID(obj)));
RUBY_ASSERT(rb_obj_shape(obj)->next_field_index == 0);
RUBY_ASSERT(RSHAPE_LEN(RBASIC_SHAPE_ID(obj)) == 0);
obj_transition_too_complex(obj, table);
}
@ -1673,8 +1673,7 @@ rb_evict_fields_to_hash(VALUE obj)
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
rb_shape_t *shape = rb_obj_shape(obj);
st_table *table = st_init_numtable_with_size(shape->next_field_index);
st_table *table = st_init_numtable_with_size(RSHAPE_LEN(RBASIC_SHAPE_ID(obj)));
rb_obj_copy_fields_to_hash_table(obj, table);
obj_transition_too_complex(obj, table);
@ -1771,28 +1770,28 @@ general_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val, void *data,
void (*transition_too_complex_func)(VALUE, void *),
st_table *(*too_complex_table_func)(VALUE, void *))
{
rb_shape_t *current_shape = rb_obj_shape(obj);
shape_id_t current_shape_id = RBASIC_SHAPE_ID(obj);
if (UNLIKELY(rb_shape_id_too_complex_p(target_shape_id))) {
if (UNLIKELY(!rb_shape_too_complex_p(current_shape))) {
if (UNLIKELY(!rb_shape_id_too_complex_p(current_shape_id))) {
transition_too_complex_func(obj, data);
}
st_table *table = too_complex_table_func(obj, data);
if (RSHAPE(target_shape_id)->next_field_index > current_shape->next_field_index) {
if (RSHAPE_LEN(target_shape_id) > RSHAPE_LEN(current_shape_id)) {
set_shape_id_func(obj, target_shape_id, data);
}
st_insert(table, (st_data_t)RSHAPE(target_shape_id)->edge_name, (st_data_t)val);
st_insert(table, (st_data_t)RSHAPE_EDGE_NAME(target_shape_id), (st_data_t)val);
RB_OBJ_WRITTEN(obj, Qundef, val);
}
else {
attr_index_t index = RSHAPE(target_shape_id)->next_field_index - 1;
if (index >= current_shape->capacity) {
shape_resize_fields_func(obj, current_shape->capacity, RSHAPE(target_shape_id)->capacity, data);
attr_index_t index = RSHAPE_INDEX(target_shape_id);
if (index >= RSHAPE_CAPACITY(current_shape_id)) {
shape_resize_fields_func(obj, RSHAPE_CAPACITY(current_shape_id), RSHAPE_CAPACITY(target_shape_id), data);
}
if (RSHAPE(target_shape_id)->next_field_index > current_shape->next_field_index) {
if (RSHAPE_LEN(target_shape_id) > RSHAPE_LEN(current_shape_id)) {
set_shape_id_func(obj, target_shape_id, data);
}
@ -2257,19 +2256,18 @@ obj_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, b
.ivar_only = ivar_only,
};
rb_shape_t *shape = rb_obj_shape(obj);
if (rb_shape_too_complex_p(shape)) {
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
if (rb_shape_id_too_complex_p(shape_id)) {
rb_st_foreach(ROBJECT_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
}
else {
iterate_over_shapes_with_callback(shape, func, &itr_data);
iterate_over_shapes_with_callback(RSHAPE(shape_id), func, &itr_data);
}
}
static void
gen_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, bool ivar_only)
{
rb_shape_t *shape = rb_obj_shape(obj);
struct gen_fields_tbl *fields_tbl;
if (!rb_gen_fields_tbl_get(obj, 0, &fields_tbl)) return;
@ -2281,11 +2279,12 @@ gen_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, b
.ivar_only = ivar_only,
};
if (rb_shape_obj_too_complex_p(obj)) {
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
if (rb_shape_id_too_complex_p(shape_id)) {
rb_st_foreach(fields_tbl->as.complex.table, each_hash_iv, (st_data_t)&itr_data);
}
else {
iterate_over_shapes_with_callback(shape, func, &itr_data);
iterate_over_shapes_with_callback(RSHAPE(shape_id), func, &itr_data);
}
}
@ -2294,7 +2293,6 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg,
{
RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
rb_shape_t *shape = rb_obj_shape(obj);
struct iv_itr_data itr_data = {
.obj = obj,
.arg = arg,
@ -2302,11 +2300,12 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg,
.ivar_only = ivar_only,
};
if (rb_shape_obj_too_complex_p(obj)) {
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
if (rb_shape_id_too_complex_p(shape_id)) {
rb_st_foreach(RCLASS_WRITABLE_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
}
else {
iterate_over_shapes_with_callback(shape, func, &itr_data);
iterate_over_shapes_with_callback(RSHAPE(shape_id), func, &itr_data);
}
}
@ -4738,7 +4737,7 @@ rb_fields_tbl_copy(VALUE dst, VALUE src)
RUBY_ASSERT(rb_type(dst) == rb_type(src));
RUBY_ASSERT(RB_TYPE_P(dst, T_CLASS) || RB_TYPE_P(dst, T_MODULE));
RUBY_ASSERT(rb_obj_shape(dst)->type == SHAPE_ROOT);
RUBY_ASSERT(RSHAPE_TYPE_P(RBASIC_SHAPE_ID(dst), SHAPE_ROOT));
RUBY_ASSERT(!RCLASS_PRIME_FIELDS(dst));
rb_ivar_foreach(src, tbl_copy_i, dst);