summaryrefslogtreecommitdiff
path: root/variable.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2023-03-10 08:50:43 -0800
committerAaron Patterson <tenderlove@ruby-lang.org>2023-03-10 08:50:43 -0800
commit365fed6369cf490f44878322fcaeddf9dfcb02f5 (patch)
treea0c756ecd41538f82cfaa9acb0388e34e13f7ae0 /variable.c
parentf98a7fd28d6eedfb80e5d7d1a92d67aa3dc4783f (diff)
Revert "Allow classes and modules to become too complex"
This reverts commit 69465df4242f3b2d8e55fbe18d7c45b47b40a626.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c102
1 files changed, 23 insertions, 79 deletions
diff --git a/variable.c b/variable.c
index 64279d881b..c0b4625e2e 100644
--- a/variable.c
+++ b/variable.c
@@ -1136,16 +1136,6 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
shape_id = RCLASS_SHAPE_ID(obj);
#endif
- if (rb_shape_obj_too_complex(obj)) {
- struct rb_id_table * iv_table = RCLASS_TABLE_IVPTR(obj);
- if (rb_id_table_lookup(iv_table, id, &val)) {
- return val;
- }
- else {
- return undef;
- }
- }
-
attr_index_t index = 0;
shape = rb_shape_get_shape_by_id(shape_id);
found = rb_shape_get_iv_index(shape, id, &index);
@@ -1278,8 +1268,6 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
attr_index_t index;
// The returned shape will have `id` in its iv_table
rb_shape_t *shape = rb_shape_get_shape(obj);
-
- RUBY_ASSERT(!rb_shape_obj_too_complex(obj));
bool found = rb_shape_get_iv_index(shape, id, &index);
if (!found) {
index = shape->next_iv_index;
@@ -1667,7 +1655,6 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu
break;
case T_CLASS:
case T_MODULE:
- RUBY_ASSERT(!rb_shape_obj_too_complex(itr_data->obj));
iv_list = RCLASS_IVPTR(itr_data->obj);
break;
default:
@@ -1737,13 +1724,7 @@ class_ivar_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
struct iv_itr_data itr_data;
itr_data.obj = obj;
itr_data.arg = arg;
- itr_data.func = func;
- if (rb_shape_obj_too_complex(obj)) {
- rb_id_table_foreach(RCLASS_TABLE_IVPTR(obj), each_hash_iv, &itr_data);
- }
- else {
- iterate_over_shapes_with_callback(shape, func, &itr_data);
- }
+ iterate_over_shapes_with_callback(shape, func, &itr_data);
}
void
@@ -2003,14 +1984,7 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
case T_CLASS:
case T_MODULE:
IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(id);
- if (rb_shape_obj_too_complex(obj)) {
- if (rb_id_table_lookup(RCLASS_TABLE_IVPTR(obj), id, &val)) {
- rb_id_table_delete(RCLASS_TABLE_IVPTR(obj), id);
- }
- } else {
- rb_shape_transition_shape_remove_ivar(obj, id, shape, &val);
- }
-
+ rb_shape_transition_shape_remove_ivar(obj, id, shape, &val);
break;
case T_OBJECT: {
if (rb_shape_obj_too_complex(obj)) {
@@ -3987,65 +3961,35 @@ rb_class_ivar_set(VALUE obj, ID key, VALUE value)
RB_VM_LOCK_ENTER();
{
- if (rb_shape_obj_too_complex(obj)) {
- struct rb_id_table * iv_table = RCLASS_TABLE_IVPTR(obj);
- rb_id_table_insert(iv_table, key, value);
+ rb_shape_t * shape = rb_shape_get_shape(obj);
+ attr_index_t idx;
+ found = rb_shape_get_iv_index(shape, key, &idx);
+
+ if (found) {
+ // Changing an existing instance variable
+ RUBY_ASSERT(RCLASS_IVPTR(obj));
+
+ RCLASS_IVPTR(obj)[idx] = value;
RB_OBJ_WRITTEN(obj, Qundef, value);
- found = 0;
}
else {
- rb_shape_t * shape = rb_shape_get_shape(obj);
- attr_index_t idx;
- found = rb_shape_get_iv_index(shape, key, &idx);
+ // Creating and setting a new instance variable
- if (found) {
- // Changing an existing instance variable
- RUBY_ASSERT(RCLASS_IVPTR(obj));
+ // Move to a shape which fits the new ivar
+ idx = shape->next_iv_index;
+ shape = rb_shape_get_next(shape, obj, key);
- RCLASS_IVPTR(obj)[idx] = value;
- RB_OBJ_WRITTEN(obj, Qundef, value);
+ // We always allocate a power of two sized IV array. This way we
+ // only need to realloc when we expand into a new power of two size
+ if ((idx & (idx - 1)) == 0) {
+ size_t newsize = idx ? idx * 2 : 1;
+ REALLOC_N(RCLASS_IVPTR(obj), VALUE, newsize);
}
- else {
- // Creating and setting a new instance variable
-
- // Move to a shape which fits the new ivar
- idx = shape->next_iv_index;
- shape = rb_shape_get_next(shape, obj, key);
-
- // stop using shapes if we are now too complex
- if (shape->type == SHAPE_OBJ_TOO_COMPLEX) {
- struct rb_id_table * table = rb_id_table_create(shape->next_iv_index);
-
- // Evacuate all previous values from shape into id_table
- rb_ivar_foreach(obj, rb_obj_evacuate_ivs_to_hash_table, (st_data_t)table);
-
- // insert the new value
- rb_id_table_insert(table, key, value);
- RB_OBJ_WRITTEN(obj, Qundef, value);
- rb_shape_set_too_complex(obj);
- RUBY_ASSERT(rb_shape_obj_too_complex(obj));
+ RUBY_ASSERT(RCLASS_IVPTR(obj));
- if (RCLASS_IVPTR(obj)) {
- xfree(RCLASS_IVPTR(obj));
- }
-
- RCLASS_EXT(obj)->iv_ptr = (VALUE *)table;
- }
- else {
- // We always allocate a power of two sized IV array. This way we
- // only need to realloc when we expand into a new power of two size
- if ((idx & (idx - 1)) == 0) {
- size_t newsize = idx ? idx * 2 : 1;
- REALLOC_N(RCLASS_IVPTR(obj), VALUE, newsize);
- }
-
- RUBY_ASSERT(RCLASS_IVPTR(obj));
-
- RB_OBJ_WRITE(obj, &RCLASS_IVPTR(obj)[idx], value);
- rb_shape_set_shape(obj, shape);
- }
- }
+ RB_OBJ_WRITE(obj, &RCLASS_IVPTR(obj)[idx], value);
+ rb_shape_set_shape(obj, shape);
}
}
RB_VM_LOCK_LEAVE();