diff options
author | Jean Boussier <[email protected]> | 2025-06-13 15:49:17 +0200 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2025-06-13 23:50:30 +0200 |
commit | 6dbe24fe5641e5c86638ff5c5d9fe08ea31d196d (patch) | |
tree | bb982fdb111a536a47bfa4d9eb3bfa059e33ae2e /variable.c | |
parent | b51078f82ee35d532dfd5b6981733f757d410d79 (diff) |
Use the `shape_id` rather than `FL_EXIVAR`
We still keep setting `FL_EXIVAR` so that `rb_shape_verify_consistency`
can detect discrepancies.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13612
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/variable.c b/variable.c index 0dd0a500bb..f2561c0dfa 100644 --- a/variable.c +++ b/variable.c @@ -1255,22 +1255,25 @@ rb_mark_generic_ivar(VALUE obj) void rb_free_generic_ivar(VALUE obj) { - st_data_t key = (st_data_t)obj, value; + if (rb_obj_exivar_p(obj)) { + st_data_t key = (st_data_t)obj, value; - bool too_complex = rb_shape_obj_too_complex_p(obj); + bool too_complex = rb_shape_obj_too_complex_p(obj); - RB_VM_LOCKING() { - if (st_delete(generic_fields_tbl_no_ractor_check(obj), &key, &value)) { - struct gen_fields_tbl *fields_tbl = (struct gen_fields_tbl *)value; + RB_VM_LOCKING() { + if (st_delete(generic_fields_tbl_no_ractor_check(obj), &key, &value)) { + struct gen_fields_tbl *fields_tbl = (struct gen_fields_tbl *)value; - if (UNLIKELY(too_complex)) { - st_free_table(fields_tbl->as.complex.table); - } + if (UNLIKELY(too_complex)) { + st_free_table(fields_tbl->as.complex.table); + } - xfree(fields_tbl); + xfree(fields_tbl); + } } + FL_UNSET_RAW(obj, FL_EXIVAR); + RBASIC_SET_SHAPE_ID(obj, ROOT_SHAPE_ID); } - FL_UNSET_RAW(obj, FL_EXIVAR); } size_t @@ -1327,6 +1330,7 @@ rb_obj_field_get(VALUE obj, shape_id_t target_shape_id) break; default: RUBY_ASSERT(FL_TEST_RAW(obj, FL_EXIVAR)); + RUBY_ASSERT(rb_obj_exivar_p(obj)); struct gen_fields_tbl *fields_tbl = NULL; rb_ivar_generic_fields_tbl_lookup(obj, &fields_tbl); RUBY_ASSERT(fields_tbl); @@ -1358,6 +1362,7 @@ rb_obj_field_get(VALUE obj, shape_id_t target_shape_id) break; default: RUBY_ASSERT(FL_TEST_RAW(obj, FL_EXIVAR)); + RUBY_ASSERT(rb_obj_exivar_p(obj)); struct gen_fields_tbl *fields_tbl = NULL; rb_ivar_generic_fields_tbl_lookup(obj, &fields_tbl); RUBY_ASSERT(fields_tbl); @@ -1435,7 +1440,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef) } default: shape_id = RBASIC_SHAPE_ID(obj); - if (FL_TEST_RAW(obj, FL_EXIVAR)) { + if (rb_obj_exivar_p(obj)) { struct gen_fields_tbl *fields_tbl; rb_gen_fields_tbl_get(obj, id, &fields_tbl); @@ -1551,22 +1556,20 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef) size_t trailing_fields = new_fields_count - removed_index; MEMMOVE(&fields[removed_index], &fields[removed_index + 1], VALUE, trailing_fields); - - if (RB_TYPE_P(obj, T_OBJECT) && - !RB_FL_TEST_RAW(obj, ROBJECT_EMBED) && - rb_obj_embedded_size(new_fields_count) <= rb_gc_obj_slot_size(obj)) { - // Re-embed objects when instances become small enough - // This is necessary because YJIT assumes that objects with the same shape - // have the same embeddedness for efficiency (avoid extra checks) - RB_FL_SET_RAW(obj, ROBJECT_EMBED); - MEMCPY(ROBJECT_FIELDS(obj), fields, VALUE, new_fields_count); - xfree(fields); - } } else { - if (FL_TEST_RAW(obj, FL_EXIVAR)) { - rb_free_generic_ivar(obj); - } + rb_free_generic_ivar(obj); + } + + if (RB_TYPE_P(obj, T_OBJECT) && + !RB_FL_TEST_RAW(obj, ROBJECT_EMBED) && + rb_obj_embedded_size(new_fields_count) <= rb_gc_obj_slot_size(obj)) { + // Re-embed objects when instances become small enough + // This is necessary because YJIT assumes that objects with the same shape + // have the same embeddedness for efficiency (avoid extra checks) + RB_FL_SET_RAW(obj, ROBJECT_EMBED); + MEMCPY(ROBJECT_FIELDS(obj), fields, VALUE, new_fields_count); + xfree(fields); } rb_obj_set_shape_id(obj, next_shape_id); @@ -1844,13 +1847,14 @@ generic_fields_lookup_ensure_size(st_data_t *k, st_data_t *v, st_data_t u, int e *v = (st_data_t)fields_tbl; } - RUBY_ASSERT(FL_TEST((VALUE)*k, FL_EXIVAR)); - fields_lookup->fields_tbl = fields_tbl; if (fields_lookup->shape_id) { rb_obj_set_shape_id(fields_lookup->obj, fields_lookup->shape_id); } + RUBY_ASSERT(FL_TEST((VALUE)*k, FL_EXIVAR)); + RUBY_ASSERT(rb_obj_exivar_p((VALUE)*k)); + return ST_CONTINUE; } @@ -2349,8 +2353,8 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj) rb_check_frozen(dest); - if (!FL_TEST(obj, FL_EXIVAR)) { - goto clear; + if (!rb_obj_exivar_p(obj)) { + return; } unsigned long src_num_ivs = rb_ivar_count(obj); @@ -2414,11 +2418,7 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj) return; clear: - if (FL_TEST(dest, FL_EXIVAR)) { - rb_free_generic_ivar(dest); - FL_UNSET(dest, FL_EXIVAR); - RBASIC_SET_SHAPE_ID(dest, ROOT_SHAPE_ID); - } + rb_free_generic_ivar(dest); } void @@ -2464,7 +2464,7 @@ rb_field_foreach(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, } break; default: - if (FL_TEST_RAW(obj, FL_EXIVAR)) { + if (rb_obj_exivar_p(obj)) { gen_fields_each(obj, func, arg, ivar_only); } break; @@ -2500,7 +2500,7 @@ rb_ivar_count(VALUE obj) return RBASIC_FIELDS_COUNT(fields_obj); } default: - if (FL_TEST(obj, FL_EXIVAR)) { + if (rb_obj_exivar_p(obj)) { struct gen_fields_tbl *fields_tbl; if (rb_gen_fields_tbl_get(obj, 0, &fields_tbl)) { |