Revert "Revert "Remove SHAPE_CAPACITY_CHANGE shapes""
This reverts commit 5f3fb4f4e397735783743fe52a7899b614bece20.
This commit is contained in:
parent
b41270842a
commit
68869e9bd9
@ -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;
|
||||
|
@ -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
53
shape.c
@ -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:
|
||||
|
1
shape.h
1
shape.h
@ -64,7 +64,6 @@ enum shape_type {
|
||||
SHAPE_ROOT,
|
||||
SHAPE_IVAR,
|
||||
SHAPE_FROZEN,
|
||||
SHAPE_CAPACITY_CHANGE,
|
||||
SHAPE_T_OBJECT,
|
||||
SHAPE_OBJ_TOO_COMPLEX,
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user