shape.c: ensure heap_index is consistent for complex shapes
This commit is contained in:
parent
54edc930f9
commit
8c4e368dcf
Notes:
git
2025-06-07 16:31:00 +00:00
@ -52,7 +52,7 @@ int rb_gen_fields_tbl_get(VALUE obj, ID id, struct gen_fields_tbl **fields_tbl);
|
|||||||
void rb_obj_copy_ivs_to_hash_table(VALUE obj, st_table *table);
|
void rb_obj_copy_ivs_to_hash_table(VALUE obj, st_table *table);
|
||||||
void rb_obj_init_too_complex(VALUE obj, st_table *table);
|
void rb_obj_init_too_complex(VALUE obj, st_table *table);
|
||||||
void rb_evict_ivars_to_hash(VALUE obj);
|
void rb_evict_ivars_to_hash(VALUE obj);
|
||||||
void rb_evict_fields_to_hash(VALUE obj);
|
shape_id_t rb_evict_fields_to_hash(VALUE obj);
|
||||||
VALUE rb_obj_field_get(VALUE obj, shape_id_t target_shape_id);
|
VALUE rb_obj_field_get(VALUE obj, shape_id_t target_shape_id);
|
||||||
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
|
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
|
||||||
void rb_obj_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val);
|
void rb_obj_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val);
|
||||||
|
142
shape.c
142
shape.c
@ -723,15 +723,67 @@ remove_shape_recursive(rb_shape_t *shape, ID id, rb_shape_t **removed_shape)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static shape_id_t
|
||||||
|
shape_transition_object_id(shape_id_t original_shape_id)
|
||||||
|
{
|
||||||
|
RUBY_ASSERT(!rb_shape_has_object_id(original_shape_id));
|
||||||
|
|
||||||
|
bool dont_care;
|
||||||
|
rb_shape_t *shape = get_next_shape_internal(RSHAPE(original_shape_id), ruby_internal_object_id, SHAPE_OBJ_ID, &dont_care, true);
|
||||||
|
|
||||||
|
RUBY_ASSERT(shape);
|
||||||
|
|
||||||
|
return shape_id(shape, original_shape_id) | SHAPE_ID_FL_HAS_OBJECT_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
shape_id_t
|
||||||
|
rb_shape_transition_object_id(VALUE obj)
|
||||||
|
{
|
||||||
|
return shape_transition_object_id(RBASIC_SHAPE_ID(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
shape_id_t
|
||||||
|
rb_shape_object_id(shape_id_t original_shape_id)
|
||||||
|
{
|
||||||
|
RUBY_ASSERT(rb_shape_has_object_id(original_shape_id));
|
||||||
|
|
||||||
|
rb_shape_t *shape = RSHAPE(original_shape_id);
|
||||||
|
while (shape->type != SHAPE_OBJ_ID) {
|
||||||
|
if (UNLIKELY(shape->parent_id == INVALID_SHAPE_ID)) {
|
||||||
|
rb_bug("Missing object_id in shape tree");
|
||||||
|
}
|
||||||
|
shape = RSHAPE(shape->parent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shape_id(shape, original_shape_id) | SHAPE_ID_FL_HAS_OBJECT_ID;
|
||||||
|
}
|
||||||
|
|
||||||
static inline shape_id_t
|
static inline shape_id_t
|
||||||
transition_complex(shape_id_t shape_id)
|
transition_complex(shape_id_t shape_id)
|
||||||
{
|
{
|
||||||
if (rb_shape_has_object_id(shape_id)) {
|
uint8_t heap_index = RSHAPE(shape_id)->heap_index;
|
||||||
return ROOT_TOO_COMPLEX_WITH_OBJ_ID | (shape_id & SHAPE_ID_FLAGS_MASK);
|
shape_id_t next_shape_id;
|
||||||
}
|
|
||||||
return ROOT_TOO_COMPLEX_SHAPE_ID | (shape_id & SHAPE_ID_FLAGS_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (heap_index) {
|
||||||
|
next_shape_id = rb_shape_root(heap_index - 1) | SHAPE_ID_FL_TOO_COMPLEX;
|
||||||
|
if (rb_shape_has_object_id(shape_id)) {
|
||||||
|
next_shape_id = shape_transition_object_id(next_shape_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (rb_shape_has_object_id(shape_id)) {
|
||||||
|
next_shape_id = ROOT_TOO_COMPLEX_WITH_OBJ_ID | (shape_id & SHAPE_ID_FLAGS_MASK);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
next_shape_id = ROOT_TOO_COMPLEX_SHAPE_ID | (shape_id & SHAPE_ID_FLAGS_MASK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RUBY_ASSERT(rb_shape_has_object_id(shape_id) == rb_shape_has_object_id(next_shape_id));
|
||||||
|
|
||||||
|
return next_shape_id;
|
||||||
|
}
|
||||||
|
|
||||||
shape_id_t
|
shape_id_t
|
||||||
rb_shape_transition_remove_ivar(VALUE obj, ID id, shape_id_t *removed_shape_id)
|
rb_shape_transition_remove_ivar(VALUE obj, ID id, shape_id_t *removed_shape_id)
|
||||||
@ -754,7 +806,9 @@ rb_shape_transition_remove_ivar(VALUE obj, ID id, shape_id_t *removed_shape_id)
|
|||||||
else if (removed_shape) {
|
else if (removed_shape) {
|
||||||
// We found the shape to remove, but couldn't create a new variation.
|
// We found the shape to remove, but couldn't create a new variation.
|
||||||
// We must transition to TOO_COMPLEX.
|
// We must transition to TOO_COMPLEX.
|
||||||
return transition_complex(original_shape_id);
|
shape_id_t next_shape_id = transition_complex(original_shape_id);
|
||||||
|
RUBY_ASSERT(rb_shape_has_object_id(next_shape_id) == rb_shape_has_object_id(original_shape_id));
|
||||||
|
return next_shape_id;
|
||||||
}
|
}
|
||||||
return original_shape_id;
|
return original_shape_id;
|
||||||
}
|
}
|
||||||
@ -774,41 +828,6 @@ rb_shape_transition_complex(VALUE obj)
|
|||||||
return transition_complex(RBASIC_SHAPE_ID(obj));
|
return transition_complex(RBASIC_SHAPE_ID(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
shape_id_t
|
|
||||||
rb_shape_transition_object_id(VALUE obj)
|
|
||||||
{
|
|
||||||
shape_id_t original_shape_id = RBASIC_SHAPE_ID(obj);
|
|
||||||
|
|
||||||
RUBY_ASSERT(!rb_shape_has_object_id(original_shape_id));
|
|
||||||
|
|
||||||
rb_shape_t *shape = NULL;
|
|
||||||
if (!rb_shape_too_complex_p(original_shape_id)) {
|
|
||||||
bool dont_care;
|
|
||||||
shape = get_next_shape_internal(RSHAPE(original_shape_id), ruby_internal_object_id, SHAPE_OBJ_ID, &dont_care, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shape) {
|
|
||||||
shape = RSHAPE(ROOT_TOO_COMPLEX_WITH_OBJ_ID);
|
|
||||||
}
|
|
||||||
return shape_id(shape, original_shape_id) | SHAPE_ID_FL_HAS_OBJECT_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
shape_id_t
|
|
||||||
rb_shape_object_id(shape_id_t original_shape_id)
|
|
||||||
{
|
|
||||||
RUBY_ASSERT(rb_shape_has_object_id(original_shape_id));
|
|
||||||
|
|
||||||
rb_shape_t *shape = RSHAPE(original_shape_id);
|
|
||||||
while (shape->type != SHAPE_OBJ_ID) {
|
|
||||||
if (UNLIKELY(shape->parent_id == INVALID_SHAPE_ID)) {
|
|
||||||
rb_bug("Missing object_id in shape tree");
|
|
||||||
}
|
|
||||||
shape = RSHAPE(shape->parent_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return shape_id(shape, original_shape_id) | SHAPE_ID_FL_HAS_OBJECT_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is used for assertions where we don't want to increment
|
* This function is used for assertions where we don't want to increment
|
||||||
* max_iv_count
|
* max_iv_count
|
||||||
@ -918,7 +937,13 @@ rb_shape_transition_add_ivar(VALUE obj, ID id)
|
|||||||
shape_id_t original_shape_id = RBASIC_SHAPE_ID(obj);
|
shape_id_t original_shape_id = RBASIC_SHAPE_ID(obj);
|
||||||
RUBY_ASSERT(!shape_frozen_p(original_shape_id));
|
RUBY_ASSERT(!shape_frozen_p(original_shape_id));
|
||||||
|
|
||||||
return shape_id(shape_get_next(RSHAPE(original_shape_id), obj, id, true), original_shape_id);
|
rb_shape_t *next_shape = shape_get_next(RSHAPE(original_shape_id), obj, id, true);
|
||||||
|
if (next_shape) {
|
||||||
|
return shape_id(next_shape, original_shape_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return transition_complex(original_shape_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shape_id_t
|
shape_id_t
|
||||||
@ -927,7 +952,13 @@ rb_shape_transition_add_ivar_no_warnings(VALUE obj, ID id)
|
|||||||
shape_id_t original_shape_id = RBASIC_SHAPE_ID(obj);
|
shape_id_t original_shape_id = RBASIC_SHAPE_ID(obj);
|
||||||
RUBY_ASSERT(!shape_frozen_p(original_shape_id));
|
RUBY_ASSERT(!shape_frozen_p(original_shape_id));
|
||||||
|
|
||||||
return shape_id(shape_get_next(RSHAPE(original_shape_id), obj, id, false), original_shape_id);
|
rb_shape_t *next_shape = shape_get_next(RSHAPE(original_shape_id), obj, id, false);
|
||||||
|
if (next_shape) {
|
||||||
|
return shape_id(next_shape, original_shape_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return transition_complex(original_shape_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as rb_shape_get_iv_index, but uses a provided valid shape id and index
|
// Same as rb_shape_get_iv_index, but uses a provided valid shape id and index
|
||||||
@ -1139,7 +1170,13 @@ rb_shape_rebuild(shape_id_t initial_shape_id, shape_id_t dest_shape_id)
|
|||||||
RUBY_ASSERT(!rb_shape_too_complex_p(initial_shape_id));
|
RUBY_ASSERT(!rb_shape_too_complex_p(initial_shape_id));
|
||||||
RUBY_ASSERT(!rb_shape_too_complex_p(dest_shape_id));
|
RUBY_ASSERT(!rb_shape_too_complex_p(dest_shape_id));
|
||||||
|
|
||||||
return shape_id(shape_rebuild(RSHAPE(initial_shape_id), RSHAPE(dest_shape_id)), initial_shape_id);
|
rb_shape_t *next_shape = shape_rebuild(RSHAPE(initial_shape_id), RSHAPE(dest_shape_id));
|
||||||
|
if (next_shape) {
|
||||||
|
return shape_id(next_shape, initial_shape_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return transition_complex(initial_shape_id | (dest_shape_id & SHAPE_ID_FL_HAS_OBJECT_ID));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1217,6 +1254,10 @@ rb_shape_memsize(shape_id_t shape_id)
|
|||||||
bool
|
bool
|
||||||
rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
|
rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
|
||||||
{
|
{
|
||||||
|
if (shape_id == INVALID_SHAPE_ID) {
|
||||||
|
rb_bug("Can't set INVALID_SHAPE_ID on an object");
|
||||||
|
}
|
||||||
|
|
||||||
rb_shape_t *shape = RSHAPE(shape_id);
|
rb_shape_t *shape = RSHAPE(shape_id);
|
||||||
|
|
||||||
bool has_object_id = false;
|
bool has_object_id = false;
|
||||||
@ -1241,13 +1282,10 @@ rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All complex shape are in heap_index=0, it's a limitation
|
|
||||||
if (!rb_shape_too_complex_p(shape_id)) {
|
|
||||||
uint8_t flags_heap_index = rb_shape_heap_index(shape_id);
|
uint8_t flags_heap_index = rb_shape_heap_index(shape_id);
|
||||||
if (flags_heap_index != shape->heap_index) {
|
if (flags_heap_index != shape->heap_index) {
|
||||||
rb_bug("shape_id heap_index flags mismatch: flags=%u, transition=%u\n", flags_heap_index, shape->heap_index);
|
rb_bug("shape_id heap_index flags mismatch: flags=%u, transition=%u\n", flags_heap_index, shape->heap_index);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1537,7 +1575,8 @@ Init_default_shapes(void)
|
|||||||
|
|
||||||
// Make shapes for T_OBJECT
|
// Make shapes for T_OBJECT
|
||||||
size_t *sizes = rb_gc_heap_sizes();
|
size_t *sizes = rb_gc_heap_sizes();
|
||||||
for (int i = 0; sizes[i] > 0; i++) {
|
int i;
|
||||||
|
for (i = 0; sizes[i] > 0; i++) {
|
||||||
rb_shape_t *t_object_shape = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
|
rb_shape_t *t_object_shape = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
|
||||||
t_object_shape->type = SHAPE_T_OBJECT;
|
t_object_shape->type = SHAPE_T_OBJECT;
|
||||||
t_object_shape->heap_index = i + 1;
|
t_object_shape->heap_index = i + 1;
|
||||||
@ -1546,6 +1585,13 @@ Init_default_shapes(void)
|
|||||||
t_object_shape->ancestor_index = LEAF;
|
t_object_shape->ancestor_index = LEAF;
|
||||||
RUBY_ASSERT(t_object_shape == RSHAPE(rb_shape_root(i)));
|
RUBY_ASSERT(t_object_shape == RSHAPE(rb_shape_root(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prebuild all ROOT + OBJ_ID shapes so that even when we run out of shape we can always transtion to
|
||||||
|
// COMPLEX + OBJ_ID.
|
||||||
|
bool dont_care;
|
||||||
|
for (i = 0; sizes[i] > 0; i++) {
|
||||||
|
get_next_shape_internal(RSHAPE(rb_shape_root(i)), ruby_internal_object_id, SHAPE_OBJ_ID, &dont_care, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
30
variable.c
30
variable.c
@ -1611,7 +1611,7 @@ rb_attr_delete(VALUE obj, ID id)
|
|||||||
return rb_ivar_delete(obj, id, Qnil);
|
return rb_ivar_delete(obj, id, Qnil);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static shape_id_t
|
||||||
obj_transition_too_complex(VALUE obj, st_table *table)
|
obj_transition_too_complex(VALUE obj, st_table *table)
|
||||||
{
|
{
|
||||||
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
|
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
|
||||||
@ -1659,6 +1659,7 @@ obj_transition_too_complex(VALUE obj, st_table *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xfree(old_fields);
|
xfree(old_fields);
|
||||||
|
return shape_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1673,7 +1674,7 @@ rb_obj_init_too_complex(VALUE obj, st_table *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy all object fields, including ivars and internal object_id, etc
|
// Copy all object fields, including ivars and internal object_id, etc
|
||||||
void
|
shape_id_t
|
||||||
rb_evict_fields_to_hash(VALUE obj)
|
rb_evict_fields_to_hash(VALUE obj)
|
||||||
{
|
{
|
||||||
void rb_obj_copy_fields_to_hash_table(VALUE obj, st_table *table);
|
void rb_obj_copy_fields_to_hash_table(VALUE obj, st_table *table);
|
||||||
@ -1682,9 +1683,10 @@ rb_evict_fields_to_hash(VALUE obj)
|
|||||||
|
|
||||||
st_table *table = st_init_numtable_with_size(RSHAPE_LEN(RBASIC_SHAPE_ID(obj)));
|
st_table *table = st_init_numtable_with_size(RSHAPE_LEN(RBASIC_SHAPE_ID(obj)));
|
||||||
rb_obj_copy_fields_to_hash_table(obj, table);
|
rb_obj_copy_fields_to_hash_table(obj, table);
|
||||||
obj_transition_too_complex(obj, table);
|
shape_id_t new_shape_id = obj_transition_too_complex(obj, table);
|
||||||
|
|
||||||
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
||||||
|
return new_shape_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1711,7 +1713,7 @@ general_ivar_set(VALUE obj, ID id, VALUE val, void *data,
|
|||||||
VALUE *(*shape_fields_func)(VALUE, void *),
|
VALUE *(*shape_fields_func)(VALUE, void *),
|
||||||
void (*shape_resize_fields_func)(VALUE, attr_index_t, attr_index_t, void *),
|
void (*shape_resize_fields_func)(VALUE, attr_index_t, attr_index_t, void *),
|
||||||
void (*set_shape_id_func)(VALUE, shape_id_t, void *),
|
void (*set_shape_id_func)(VALUE, shape_id_t, void *),
|
||||||
void (*transition_too_complex_func)(VALUE, void *),
|
shape_id_t (*transition_too_complex_func)(VALUE, void *),
|
||||||
st_table *(*too_complex_table_func)(VALUE, void *))
|
st_table *(*too_complex_table_func)(VALUE, void *))
|
||||||
{
|
{
|
||||||
struct general_ivar_set_result result = {
|
struct general_ivar_set_result result = {
|
||||||
@ -1736,7 +1738,7 @@ general_ivar_set(VALUE obj, ID id, VALUE val, void *data,
|
|||||||
|
|
||||||
shape_id_t next_shape_id = rb_shape_transition_add_ivar(obj, id);
|
shape_id_t next_shape_id = rb_shape_transition_add_ivar(obj, id);
|
||||||
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
|
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
|
||||||
transition_too_complex_func(obj, data);
|
current_shape_id = transition_too_complex_func(obj, data);
|
||||||
goto too_complex;
|
goto too_complex;
|
||||||
}
|
}
|
||||||
else if (UNLIKELY(RSHAPE_CAPACITY(next_shape_id) != RSHAPE_CAPACITY(current_shape_id))) {
|
else if (UNLIKELY(RSHAPE_CAPACITY(next_shape_id) != RSHAPE_CAPACITY(current_shape_id))) {
|
||||||
@ -1772,14 +1774,14 @@ general_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val, void *data,
|
|||||||
VALUE *(*shape_fields_func)(VALUE, void *),
|
VALUE *(*shape_fields_func)(VALUE, void *),
|
||||||
void (*shape_resize_fields_func)(VALUE, attr_index_t, attr_index_t, void *),
|
void (*shape_resize_fields_func)(VALUE, attr_index_t, attr_index_t, void *),
|
||||||
void (*set_shape_id_func)(VALUE, shape_id_t, void *),
|
void (*set_shape_id_func)(VALUE, shape_id_t, void *),
|
||||||
void (*transition_too_complex_func)(VALUE, void *),
|
shape_id_t (*transition_too_complex_func)(VALUE, void *),
|
||||||
st_table *(*too_complex_table_func)(VALUE, void *))
|
st_table *(*too_complex_table_func)(VALUE, void *))
|
||||||
{
|
{
|
||||||
shape_id_t current_shape_id = RBASIC_SHAPE_ID(obj);
|
shape_id_t current_shape_id = RBASIC_SHAPE_ID(obj);
|
||||||
|
|
||||||
if (UNLIKELY(rb_shape_too_complex_p(target_shape_id))) {
|
if (UNLIKELY(rb_shape_too_complex_p(target_shape_id))) {
|
||||||
if (UNLIKELY(!rb_shape_too_complex_p(current_shape_id))) {
|
if (UNLIKELY(!rb_shape_too_complex_p(current_shape_id))) {
|
||||||
transition_too_complex_func(obj, data);
|
current_shape_id = transition_too_complex_func(obj, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
st_table *table = too_complex_table_func(obj, data);
|
st_table *table = too_complex_table_func(obj, data);
|
||||||
@ -1788,6 +1790,7 @@ general_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val, void *data,
|
|||||||
RBASIC_SET_SHAPE_ID(obj, target_shape_id);
|
RBASIC_SET_SHAPE_ID(obj, target_shape_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RUBY_ASSERT(RSHAPE_EDGE_NAME(target_shape_id));
|
||||||
st_insert(table, (st_data_t)RSHAPE_EDGE_NAME(target_shape_id), (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);
|
RB_OBJ_WRITTEN(obj, Qundef, val);
|
||||||
}
|
}
|
||||||
@ -1877,11 +1880,12 @@ generic_ivar_set_set_shape_id(VALUE obj, shape_id_t shape_id, void *data)
|
|||||||
fields_lookup->shape_id = shape_id;
|
fields_lookup->shape_id = shape_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static shape_id_t
|
||||||
generic_ivar_set_transition_too_complex(VALUE obj, void *_data)
|
generic_ivar_set_transition_too_complex(VALUE obj, void *_data)
|
||||||
{
|
{
|
||||||
rb_evict_fields_to_hash(obj);
|
shape_id_t new_shape_id = rb_evict_fields_to_hash(obj);
|
||||||
FL_SET_RAW(obj, FL_EXIVAR);
|
FL_SET_RAW(obj, FL_EXIVAR);
|
||||||
|
return new_shape_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static st_table *
|
static st_table *
|
||||||
@ -1997,10 +2001,10 @@ obj_ivar_set_set_shape_id(VALUE obj, shape_id_t shape_id, void *_data)
|
|||||||
rb_obj_set_shape_id(obj, shape_id);
|
rb_obj_set_shape_id(obj, shape_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static shape_id_t
|
||||||
obj_ivar_set_transition_too_complex(VALUE obj, void *_data)
|
obj_ivar_set_transition_too_complex(VALUE obj, void *_data)
|
||||||
{
|
{
|
||||||
rb_evict_fields_to_hash(obj);
|
return rb_evict_fields_to_hash(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static st_table *
|
static st_table *
|
||||||
@ -4691,10 +4695,10 @@ class_ivar_set_set_shape_id(VALUE obj, shape_id_t shape_id, void *_data)
|
|||||||
rb_obj_set_shape_id(obj, shape_id);
|
rb_obj_set_shape_id(obj, shape_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static shape_id_t
|
||||||
class_ivar_set_transition_too_complex(VALUE obj, void *_data)
|
class_ivar_set_transition_too_complex(VALUE obj, void *_data)
|
||||||
{
|
{
|
||||||
rb_evict_fields_to_hash(obj);
|
return rb_evict_fields_to_hash(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static st_table *
|
static st_table *
|
||||||
|
Loading…
x
Reference in New Issue
Block a user