summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/objspace/objspace_dump.c5
-rw-r--r--rjit_c.rb1
-rw-r--r--shape.c53
-rw-r--r--shape.h1
-rwxr-xr-xtool/rjit/bindgen.rb1
-rw-r--r--variable.c3
-rw-r--r--vm_insnhelper.c9
7 files changed, 13 insertions, 60 deletions
diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c
index c80c38eba4..963deb13fc 100644
--- a/ext/objspace/objspace_dump.c
+++ b/ext/objspace/objspace_dump.c
@@ -771,11 +771,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;
diff --git a/rjit_c.rb b/rjit_c.rb
index df30841d2b..7e00fad9b4 100644
--- a/rjit_c.rb
+++ b/rjit_c.rb
@@ -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) }
diff --git a/shape.c b/shape.c
index ef08030ad4..13c8d11b82 100644
--- a/shape.c
+++ b/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:
diff --git a/shape.h b/shape.h
index 6d4f3f9811..f1823258da 100644
--- a/shape.h
+++ b/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,
};
diff --git a/tool/rjit/bindgen.rb b/tool/rjit/bindgen.rb
index ebb58d8281..328c8b344b 100755
--- a/tool/rjit/bindgen.rb
+++ b/tool/rjit/bindgen.rb
@@ -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
diff --git a/variable.c b/variable.c
index 72c0fd7c2b..653fa58552 100644
--- a/variable.c
+++ b/variable.c
@@ -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);
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index bea80ed588..be70b93588 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -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);