Revert "Revert "Remove SHAPE_CAPACITY_CHANGE shapes""

This reverts commit 5f3fb4f4e397735783743fe52a7899b614bece20.
This commit is contained in:
Peter Zhu 2023-11-10 16:17:39 -05:00
parent b41270842a
commit 68869e9bd9
7 changed files with 13 additions and 60 deletions

View File

@ -791,11 +791,6 @@ shape_i(rb_shape_t *shape, void *data)
case SHAPE_FROZEN:
dump_append(dc, "\"FROZEN\"");
break;
case SHAPE_CAPACITY_CHANGE:
dump_append(dc, "\"CAPACITY_CHANGE\"");
dump_append(dc, ", \"capacity\":");
dump_append_sizet(dc, shape->capacity);
break;
case SHAPE_T_OBJECT:
dump_append(dc, "\"T_OBJECT\"");
break;

View File

@ -406,7 +406,6 @@ module RubyVM::RJIT # :nodoc: all
C::RUBY_T_OBJECT = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_OBJECT) }
C::RUBY_T_STRING = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_STRING) }
C::RUBY_T_SYMBOL = Primitive.cexpr! %q{ SIZET2NUM(RUBY_T_SYMBOL) }
C::SHAPE_CAPACITY_CHANGE = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_CAPACITY_CHANGE) }
C::SHAPE_FLAG_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FLAG_SHIFT) }
C::SHAPE_FROZEN = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FROZEN) }
C::SHAPE_ID_NUM_BITS = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_ID_NUM_BITS) }

53
shape.c
View File

@ -44,8 +44,6 @@ static ID id_frozen;
static ID id_t_object;
static ID size_pool_edge_names[SIZE_POOL_COUNT];
rb_shape_t * rb_shape_transition_shape_capa(rb_shape_t * shape);
#define LEAF 0
#define BLACK 0x0
#define RED 0x1
@ -434,12 +432,16 @@ rb_shape_alloc_new_child(ID id, rb_shape_t * shape, enum shape_type shape_type)
switch (shape_type) {
case SHAPE_IVAR:
if (UNLIKELY(shape->next_iv_index >= shape->capacity)) {
RUBY_ASSERT(shape->next_iv_index == shape->capacity);
new_shape->capacity = (uint32_t)rb_malloc_grow_capa(shape->capacity, sizeof(VALUE));
}
RUBY_ASSERT(new_shape->capacity > shape->next_iv_index);
new_shape->next_iv_index = shape->next_iv_index + 1;
if (new_shape->next_iv_index > ANCESTOR_CACHE_THRESHOLD) {
redblack_cache_ancestors(new_shape);
}
break;
case SHAPE_CAPACITY_CHANGE:
case SHAPE_FROZEN:
case SHAPE_T_OBJECT:
new_shape->next_iv_index = shape->next_iv_index;
@ -680,16 +682,8 @@ rb_shape_get_next(rb_shape_t* shape, VALUE obj, ID id)
allow_new_shape = RCLASS_EXT(klass)->variation_count < SHAPE_MAX_VARIATIONS;
}
if (UNLIKELY(shape->next_iv_index >= shape->capacity)) {
RUBY_ASSERT(shape->next_iv_index == shape->capacity);
shape = rb_shape_transition_shape_capa(shape);
if (UNLIKELY(shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
return shape;
}
}
bool variation_created = false;
rb_shape_t * new_shape = get_next_shape_internal(shape, id, SHAPE_IVAR, &variation_created, allow_new_shape);
rb_shape_t *new_shape = get_next_shape_internal(shape, id, SHAPE_IVAR, &variation_created, allow_new_shape);
// Check if we should update max_iv_count on the object's class
if (BUILTIN_TYPE(obj) == T_OBJECT) {
@ -716,29 +710,6 @@ rb_shape_get_next(rb_shape_t* shape, VALUE obj, ID id)
return new_shape;
}
static inline rb_shape_t *
rb_shape_transition_shape_capa_create(rb_shape_t* shape, size_t new_capacity)
{
RUBY_ASSERT(new_capacity < (size_t)MAX_IVARS);
ID edge_name = rb_make_temporary_id(new_capacity);
bool dont_care;
rb_shape_t * new_shape = get_next_shape_internal(shape, edge_name, SHAPE_CAPACITY_CHANGE, &dont_care, true);
if (rb_shape_id(new_shape) != OBJ_TOO_COMPLEX_SHAPE_ID) {
new_shape->capacity = (uint32_t)new_capacity;
}
return new_shape;
}
rb_shape_t *
rb_shape_transition_shape_capa(rb_shape_t* shape)
{
if (UNLIKELY(shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
return shape;
}
return rb_shape_transition_shape_capa_create(shape, rb_malloc_grow_capa(shape->capacity, sizeof(VALUE)));
}
// Same as rb_shape_get_iv_index, but uses a provided valid shape id and index
// to return a result faster if branches of the shape tree are closely related.
bool
@ -825,7 +796,6 @@ rb_shape_get_iv_index(rb_shape_t * shape, ID id, attr_index_t *value)
RUBY_ASSERT(shape->next_iv_index > 0);
*value = shape->next_iv_index - 1;
return true;
case SHAPE_CAPACITY_CHANGE:
case SHAPE_ROOT:
case SHAPE_T_OBJECT:
return false;
@ -892,7 +862,6 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap
}
break;
case SHAPE_ROOT:
case SHAPE_CAPACITY_CHANGE:
case SHAPE_T_OBJECT:
break;
case SHAPE_OBJ_TOO_COMPLEX:
@ -925,18 +894,10 @@ rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape)
switch ((enum shape_type)dest_shape->type) {
case SHAPE_IVAR:
if (midway_shape->capacity <= midway_shape->next_iv_index) {
// There isn't enough room to write this IV, so we need to increase the capacity
midway_shape = rb_shape_transition_shape_capa(midway_shape);
}
if (LIKELY(rb_shape_id(midway_shape) != OBJ_TOO_COMPLEX_SHAPE_ID)) {
midway_shape = rb_shape_get_next_iv_shape(midway_shape, dest_shape->edge_name);
}
midway_shape = rb_shape_get_next_iv_shape(midway_shape, dest_shape->edge_name);
break;
case SHAPE_ROOT:
case SHAPE_FROZEN:
case SHAPE_CAPACITY_CHANGE:
case SHAPE_T_OBJECT:
break;
case SHAPE_OBJ_TOO_COMPLEX:

View File

@ -64,7 +64,6 @@ enum shape_type {
SHAPE_ROOT,
SHAPE_IVAR,
SHAPE_FROZEN,
SHAPE_CAPACITY_CHANGE,
SHAPE_T_OBJECT,
SHAPE_OBJ_TOO_COMPLEX,
};

View File

@ -435,7 +435,6 @@ generator = BindingGenerator.new(
RUBY_T_STRING
RUBY_T_SYMBOL
RUBY_T_OBJECT
SHAPE_CAPACITY_CHANGE
SHAPE_FLAG_SHIFT
SHAPE_FROZEN
SHAPE_ID_NUM_BITS

View File

@ -1509,7 +1509,7 @@ generic_ivar_lookup_ensure_size(st_data_t *k, st_data_t *v, st_data_t u, int exi
if (!existing || ivar_lookup->resize) {
if (existing) {
RUBY_ASSERT(ivar_lookup->shape->type == SHAPE_IVAR);
RUBY_ASSERT(rb_shape_get_shape_by_id(ivar_lookup->shape->parent_id)->type == SHAPE_CAPACITY_CHANGE);
RUBY_ASSERT(rb_shape_get_shape_by_id(ivar_lookup->shape->parent_id)->capacity < ivar_lookup->shape->capacity);
}
else {
FL_SET_RAW((VALUE)*k, FL_EXIVAR);
@ -1895,7 +1895,6 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu
}
}
return false;
case SHAPE_CAPACITY_CHANGE:
case SHAPE_FROZEN:
case SHAPE_T_OBJECT:
return iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data);

View File

@ -1460,11 +1460,11 @@ vm_setivar_default(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_i
RUBY_ASSERT(dest_shape_id != INVALID_SHAPE_ID && shape_id != INVALID_SHAPE_ID);
}
else if (dest_shape_id != INVALID_SHAPE_ID) {
rb_shape_t *shape = rb_shape_get_shape_by_id(shape_id);
rb_shape_t *dest_shape = rb_shape_get_shape_by_id(dest_shape_id);
if (shape_id == dest_shape->parent_id && dest_shape->edge_name == id && dest_shape->type == SHAPE_IVAR) {
RUBY_ASSERT(rb_shape_get_shape_by_id(shape_id)->capacity == dest_shape->capacity);
RUBY_ASSERT(index < rb_shape_get_shape_by_id(shape_id)->capacity);
if (shape_id == dest_shape->parent_id && dest_shape->edge_name == id && shape->capacity == dest_shape->capacity) {
RUBY_ASSERT(index < dest_shape->capacity);
}
else {
return Qundef;
@ -1508,10 +1508,11 @@ vm_setivar(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_index_t i
VM_ASSERT(!rb_ractor_shareable_p(obj));
}
else if (dest_shape_id != INVALID_SHAPE_ID) {
rb_shape_t *shape = rb_shape_get_shape_by_id(shape_id);
rb_shape_t *dest_shape = rb_shape_get_shape_by_id(dest_shape_id);
shape_id_t source_shape_id = dest_shape->parent_id;
if (shape_id == source_shape_id && dest_shape->edge_name == id) {
if (shape_id == source_shape_id && dest_shape->edge_name == id && shape->capacity == dest_shape->capacity) {
RUBY_ASSERT(dest_shape_id != INVALID_SHAPE_ID && shape_id != INVALID_SHAPE_ID);
ROBJECT_SET_SHAPE_ID(obj, dest_shape_id);