aboutsummaryrefslogtreecommitdiffstats
path: root/variable.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-11-06 08:32:32 -0500
committerPeter Zhu <peter@peterzhu.ca>2023-11-06 11:10:41 -0500
commit18f675912e975037962f8939456379e276722a23 (patch)
treeaa17fa2da60298b5a0939e8ccc090a8c8690b43e /variable.c
parent679e98dc27c4711601801db8852c5b4bc5a9da76 (diff)
downloadruby-18f675912e975037962f8939456379e276722a23.tar.gz
Use general_ivar_set for Class ivars
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c91
1 files changed, 42 insertions, 49 deletions
diff --git a/variable.c b/variable.c
index f86d6210cb..c2e5634b3a 100644
--- a/variable.c
+++ b/variable.c
@@ -4196,66 +4196,59 @@ rb_iv_set(VALUE obj, const char *name, VALUE val)
return rb_ivar_set(obj, id, val);
}
-/* tbl = xx(obj); tbl[key] = value; */
-int
-rb_class_ivar_set(VALUE obj, ID key, VALUE value)
+static VALUE *
+class_ivar_set_shape_ivptr(VALUE obj, void *_data)
{
- RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
- int found = 0;
- rb_check_frozen(obj);
-
- RB_VM_LOCK_ENTER();
- {
- rb_shape_t * shape = rb_shape_get_shape(obj);
- if (shape->type == SHAPE_OBJ_TOO_COMPLEX) {
- found = rb_complex_ivar_set(obj, key, value);
- goto finish;
- }
-
- attr_index_t idx;
- found = rb_shape_get_iv_index(shape, key, &idx);
-
- if (!found) {
- idx = shape->next_iv_index;
+ RUBY_ASSERT(!rb_shape_obj_too_complex(obj));
- if (UNLIKELY(idx >= shape->capacity)) {
- RUBY_ASSERT(shape->next_iv_index == shape->capacity);
+ return RCLASS_IVPTR(obj);
+}
- rb_shape_t *next_shape = rb_shape_transition_shape_capa(shape);
- if (next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
- rb_evict_ivars_to_hash(obj, shape);
- rb_complex_ivar_set(obj, key, value);
- goto finish;
- }
+static void
+class_ivar_set_shape_resize_ivptr(VALUE obj, attr_index_t _old_capa, attr_index_t new_capa, void *_data)
+{
+ REALLOC_N(RCLASS_IVPTR(obj), VALUE, new_capa);
+}
- REALLOC_N(RCLASS_IVPTR(obj), VALUE, next_shape->capacity);
+static void
+class_ivar_set_set_shape(VALUE obj, rb_shape_t *shape, void *_data)
+{
+ rb_shape_set_shape(obj, shape);
+}
- shape = next_shape;
- RUBY_ASSERT(shape->type == SHAPE_CAPACITY_CHANGE);
- }
+static void
+class_ivar_set_transition_too_complex(VALUE obj, void *_data)
+{
+ rb_evict_ivars_to_hash(obj, rb_shape_get_shape_by_id(SHAPE_OBJ_TOO_COMPLEX));
+}
- rb_shape_t *next_shape = rb_shape_get_next(shape, obj, key);
- if (next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
- rb_evict_ivars_to_hash(obj, shape);
- rb_complex_ivar_set(obj, key, value);
- goto finish;
- }
- else {
- rb_shape_set_shape(obj, next_shape);
+static st_table *
+class_ivar_set_too_complex_table(VALUE obj, void *_data)
+{
+ RUBY_ASSERT(rb_shape_obj_too_complex(obj));
- RUBY_ASSERT(next_shape->type == SHAPE_IVAR);
- RUBY_ASSERT(idx == (next_shape->next_iv_index - 1));
- }
- }
+ return RCLASS_IV_HASH(obj);
+}
- RUBY_ASSERT(RCLASS_IVPTR(obj));
+int
+rb_class_ivar_set(VALUE obj, ID id, VALUE val)
+{
+ RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
+ bool existing = false;
+ rb_check_frozen(obj);
- RB_OBJ_WRITE(obj, &RCLASS_IVPTR(obj)[idx], value);
- }
-finish:
+ RB_VM_LOCK_ENTER();
+ {
+ existing = general_ivar_set(obj, id, val, NULL,
+ class_ivar_set_shape_ivptr,
+ class_ivar_set_shape_resize_ivptr,
+ class_ivar_set_set_shape,
+ class_ivar_set_transition_too_complex,
+ class_ivar_set_too_complex_table).existing;
+}
RB_VM_LOCK_LEAVE();
- return found;
+ return existing;
}
static int