Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Refactor class_fields_ivar_set #13741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 30, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 23 additions & 24 deletions variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,22 @@ imemo_fields_complex_from_obj(VALUE klass, VALUE source_fields_obj, shape_id_t s
return fields_obj;
}

static VALUE
imemo_fields_copy_capa(VALUE klass, VALUE source_fields_obj, attr_index_t new_size)
{
VALUE fields_obj = rb_imemo_fields_new(klass, new_size);
if (source_fields_obj) {
attr_index_t fields_count = RSHAPE_LEN(RBASIC_SHAPE_ID(source_fields_obj));
VALUE *fields = rb_imemo_fields_ptr(fields_obj);
MEMCPY(fields, rb_imemo_fields_ptr(source_fields_obj), VALUE, fields_count);
RBASIC_SET_SHAPE_ID(fields_obj, RBASIC_SHAPE_ID(source_fields_obj));
for (attr_index_t i = 0; i < fields_count; i++) {
RB_OBJ_WRITTEN(fields_obj, Qundef, fields[i]);
}
}
return fields_obj;
}

void rb_obj_copy_fields_to_hash_table(VALUE obj, st_table *table);

// Copy all object fields, including ivars and internal object_id, etc
Expand Down Expand Up @@ -1846,15 +1862,7 @@ imemo_fields_set(VALUE klass, VALUE fields_obj, shape_id_t target_shape_id, ID f
else {
attr_index_t index = RSHAPE_INDEX(target_shape_id);
if (concurrent || index >= RSHAPE_CAPACITY(current_shape_id)) {
fields_obj = rb_imemo_fields_new(klass, RSHAPE_CAPACITY(target_shape_id));
if (original_fields_obj) {
attr_index_t fields_count = RSHAPE_LEN(current_shape_id);
VALUE *fields = rb_imemo_fields_ptr(fields_obj);
MEMCPY(fields, rb_imemo_fields_ptr(original_fields_obj), VALUE, fields_count);
for (attr_index_t i = 0; i < fields_count; i++) {
RB_OBJ_WRITTEN(fields_obj, Qundef, fields[i]);
}
}
fields_obj = imemo_fields_copy_capa(klass, original_fields_obj, RSHAPE_CAPACITY(target_shape_id));
}

VALUE *table = rb_imemo_fields_ptr(fields_obj);
Expand Down Expand Up @@ -4665,12 +4673,7 @@ class_fields_ivar_set(VALUE klass, VALUE fields_obj, ID id, VALUE val, bool conc

next_shape_id = rb_shape_transition_add_ivar(fields_obj, id);
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
attr_index_t current_len = RSHAPE_LEN(current_shape_id);
fields_obj = rb_imemo_fields_new_complex(rb_singleton_class(klass), current_len + 1);
if (current_len) {
rb_obj_copy_fields_to_hash_table(original_fields_obj, rb_imemo_fields_complex_tbl(fields_obj));
RBASIC_SET_SHAPE_ID(fields_obj, next_shape_id);
}
fields_obj = imemo_fields_complex_from_obj(rb_singleton_class(klass), fields_obj, next_shape_id);
goto too_complex;
}

Expand All @@ -4682,15 +4685,7 @@ class_fields_ivar_set(VALUE klass, VALUE fields_obj, ID id, VALUE val, bool conc

// We allocate a new fields_obj even when concurrency isn't a concern
// so that we're embedded as long as possible.
fields_obj = rb_imemo_fields_new(rb_singleton_class(klass), next_capacity);
if (original_fields_obj) {
VALUE *fields = rb_imemo_fields_ptr(fields_obj);
attr_index_t fields_count = RSHAPE_LEN(current_shape_id);
MEMCPY(fields, rb_imemo_fields_ptr(original_fields_obj), VALUE, fields_count);
for (attr_index_t i = 0; i < fields_count; i++) {
RB_OBJ_WRITTEN(fields_obj, Qundef, fields[i]);
}
}
fields_obj = imemo_fields_copy_capa(rb_singleton_class(klass), fields_obj, next_capacity);
}

RUBY_ASSERT(RSHAPE(next_shape_id)->type == SHAPE_IVAR);
Expand All @@ -4709,6 +4704,10 @@ class_fields_ivar_set(VALUE klass, VALUE fields_obj, ID id, VALUE val, bool conc

too_complex:
{
if (concurrent && fields_obj == original_fields_obj) {
// If we're in the multi-ractor mode, we can't directly insert in the table.
fields_obj = rb_imemo_fields_clone(fields_obj);
}
st_table *table = rb_imemo_fields_complex_tbl(fields_obj);
existing = st_insert(table, (st_data_t)id, (st_data_t)val);
RB_OBJ_WRITTEN(fields_obj, Qundef, val);
Expand Down
Loading