diff options
| -rw-r--r-- | class.c | 69 | ||||
| -rw-r--r-- | debug_counter.h | 1 | ||||
| -rw-r--r-- | ext/objspace/objspace.c | 1 | ||||
| -rw-r--r-- | gc.c | 51 | ||||
| -rw-r--r-- | id_table.c | 79 | ||||
| -rw-r--r-- | id_table.h | 10 | ||||
| -rw-r--r-- | imemo.c | 13 | ||||
| -rw-r--r-- | internal/class.h | 17 | ||||
| -rw-r--r-- | internal/imemo.h | 1 | ||||
| -rw-r--r-- | iseq.c | 4 | ||||
| -rw-r--r-- | test/ruby/test_box.rb | 31 | ||||
| -rw-r--r-- | variable.c | 29 | ||||
| -rw-r--r-- | vm_insnhelper.c | 7 | ||||
| -rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 2 | ||||
| -rw-r--r-- | zjit/src/cruby_bindings.inc.rs | 2 |
15 files changed, 196 insertions, 121 deletions
@@ -84,13 +84,6 @@ static void rb_class_remove_from_super_subclasses(VALUE klass); static void rb_class_remove_from_module_subclasses(VALUE klass); static void rb_class_classext_free_subclasses(rb_classext_t *ext); -static enum rb_id_table_iterator_result -cvar_table_free_i(VALUE value, void *ctx) -{ - xfree((void *)value); - return ID_TABLE_CONTINUE; -} - rb_classext_t * rb_class_unlink_classext(VALUE klass, const rb_box_t *box) { @@ -113,11 +106,6 @@ rb_class_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime) rb_free_const_table(tbl); } - if ((tbl = RCLASSEXT_CVC_TBL(ext)) != NULL) { - rb_id_table_foreach_values(tbl, cvar_table_free_i, NULL); - rb_id_table_free(tbl); - } - if (is_prime) { rb_class_remove_from_super_subclasses(klass); rb_class_classext_free_subclasses(ext); @@ -222,14 +210,6 @@ struct duplicate_id_tbl_data { }; static enum rb_id_table_iterator_result -duplicate_classext_id_table_i(ID key, VALUE value, void *data) -{ - struct rb_id_table *tbl = (struct rb_id_table *)data; - rb_id_table_insert(tbl, key, value); - return ID_TABLE_CONTINUE; -} - -static enum rb_id_table_iterator_result duplicate_classext_m_tbl_i(ID key, VALUE value, void *data) { struct duplicate_id_tbl_data *arg = (struct duplicate_id_tbl_data *)data; @@ -257,22 +237,6 @@ duplicate_classext_m_tbl(struct rb_id_table *orig, VALUE klass, bool init_missin return tbl; } -static struct rb_id_table * -duplicate_classext_id_table(struct rb_id_table *orig, bool init_missing) -{ - struct rb_id_table *tbl; - - if (!orig) { - if (init_missing) - return rb_id_table_create(0); - else - return NULL; - } - tbl = rb_id_table_create(rb_id_table_size(orig)); - rb_id_table_foreach(orig, duplicate_classext_id_table_i, tbl); - return tbl; -} - static rb_const_entry_t * duplicate_classext_const_entry(rb_const_entry_t *src, VALUE klass) { @@ -406,7 +370,14 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_box_t *bo * RCLASSEXT_CC_TBL(copy) = NULL */ - RCLASSEXT_CVC_TBL(ext) = duplicate_classext_id_table(RCLASSEXT_CVC_TBL(orig), dup_iclass); + VALUE cvc_table = RCLASSEXT_CVC_TBL(orig); + if (cvc_table) { + cvc_table = rb_marked_id_table_dup(cvc_table); + } + else if (dup_iclass) { + cvc_table = rb_marked_id_table_new(2); + } + RB_OBJ_WRITE(klass, &RCLASSEXT_CVC_TBL(ext), cvc_table); // Subclasses/back-pointers are only in the prime classext. @@ -964,9 +935,15 @@ class_init_copy_check(VALUE clone, VALUE orig) struct cvc_table_copy_ctx { VALUE clone; - struct rb_id_table * new_table; + VALUE new_table; }; +static struct rb_cvar_class_tbl_entry * +cvc_table_entry_alloc(void) +{ + return (struct rb_cvar_class_tbl_entry *)SHAREABLE_IMEMO_NEW(struct rb_cvar_class_tbl_entry, imemo_cvar_entry, 0); +} + static enum rb_id_table_iterator_result cvc_table_copy(ID id, VALUE val, void *data) { @@ -976,13 +953,11 @@ cvc_table_copy(ID id, VALUE val, void *data) struct rb_cvar_class_tbl_entry *ent; - ent = ALLOC(struct rb_cvar_class_tbl_entry); - ent->class_value = ctx->clone; - ent->cref = orig_entry->cref; + ent = cvc_table_entry_alloc(); + RB_OBJ_WRITE((VALUE)ent, &ent->class_value, ctx->clone); + RB_OBJ_WRITE(ctx->clone, &ent->cref, orig_entry->cref); ent->global_cvar_state = orig_entry->global_cvar_state; - rb_id_table_insert(ctx->new_table, id, (VALUE)ent); - - RB_OBJ_WRITTEN(ctx->clone, Qundef, ent->cref); + rb_marked_id_table_insert(ctx->new_table, id, (VALUE)ent); return ID_TABLE_CONTINUE; } @@ -995,13 +970,13 @@ copy_tables(VALUE clone, VALUE orig) RCLASS_WRITE_CONST_TBL(clone, 0, false); } if (RCLASS_CVC_TBL(orig)) { - struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(orig); - struct rb_id_table *rb_cvc_tbl_dup = rb_id_table_create(rb_id_table_size(rb_cvc_tbl)); + VALUE rb_cvc_tbl = RCLASS_CVC_TBL(orig); + VALUE rb_cvc_tbl_dup = rb_marked_id_table_new(rb_marked_id_table_size(rb_cvc_tbl)); struct cvc_table_copy_ctx ctx; ctx.clone = clone; ctx.new_table = rb_cvc_tbl_dup; - rb_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx); + rb_marked_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx); RCLASS_WRITE_CVC_TBL(clone, rb_cvc_tbl_dup); } rb_id_table_free(RCLASS_M_TBL(clone)); diff --git a/debug_counter.h b/debug_counter.h index c8d8ed8f11..723e9e1249 100644 --- a/debug_counter.h +++ b/debug_counter.h @@ -305,6 +305,7 @@ RB_DEBUG_COUNTER(obj_imemo_ment) RB_DEBUG_COUNTER(obj_imemo_iseq) RB_DEBUG_COUNTER(obj_imemo_env) RB_DEBUG_COUNTER(obj_imemo_tmpbuf) +RB_DEBUG_COUNTER(obj_imemo_cvar_entry) RB_DEBUG_COUNTER(obj_imemo_cref) RB_DEBUG_COUNTER(obj_imemo_svar) RB_DEBUG_COUNTER(obj_imemo_throw_data) diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c index 8b3045fda3..248647f0ed 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -500,6 +500,7 @@ count_imemo_objects(int argc, VALUE *argv, VALUE self) INIT_IMEMO_TYPE_ID(imemo_ment); INIT_IMEMO_TYPE_ID(imemo_iseq); INIT_IMEMO_TYPE_ID(imemo_tmpbuf); + INIT_IMEMO_TYPE_ID(imemo_cvar_entry); INIT_IMEMO_TYPE_ID(imemo_callinfo); INIT_IMEMO_TYPE_ID(imemo_callcache); INIT_IMEMO_TYPE_ID(imemo_constcache); @@ -2270,9 +2270,6 @@ classext_memsize(rb_classext_t *ext, bool prime, VALUE box_value, void *arg) if (RCLASSEXT_M_TBL(ext)) { s += rb_id_table_memsize(RCLASSEXT_M_TBL(ext)); } - if (RCLASSEXT_CVC_TBL(ext)) { - s += rb_id_table_memsize(RCLASSEXT_CVC_TBL(ext)); - } if (RCLASSEXT_CONST_TBL(ext)) { s += rb_id_table_memsize(RCLASSEXT_CONST_TBL(ext)); } @@ -2818,26 +2815,6 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl) rb_id_table_foreach_values(tbl, mark_const_entry_i, objspace); } -static enum rb_id_table_iterator_result -mark_cvc_tbl_i(VALUE cvc_entry, void *objspace) -{ - struct rb_cvar_class_tbl_entry *entry; - - entry = (struct rb_cvar_class_tbl_entry *)cvc_entry; - - RUBY_ASSERT(entry->cref == 0 || (BUILTIN_TYPE((VALUE)entry->cref) == T_IMEMO && IMEMO_TYPE_P(entry->cref, imemo_cref))); - gc_mark_internal((VALUE)entry->cref); - - return ID_TABLE_CONTINUE; -} - -static void -mark_cvc_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl) -{ - if (!tbl) return; - rb_id_table_foreach_values(tbl, mark_cvc_tbl_i, objspace); -} - #if STACK_GROW_DIRECTION < 0 #define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_END, (end) = STACK_START) #elif STACK_GROW_DIRECTION > 0 @@ -3082,6 +3059,7 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE box_value, void *a if (!rb_gc_checking_shareable()) { // unshareable gc_mark_internal(RCLASSEXT_FIELDS_OBJ(ext)); + gc_mark_internal(RCLASSEXT_CVC_TBL(ext)); } if (!RCLASSEXT_SHARED_CONST_TBL(ext) && RCLASSEXT_CONST_TBL(ext)) { @@ -3089,7 +3067,6 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE box_value, void *a } mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext)); gc_mark_internal(RCLASSEXT_CC_TBL(ext)); - mark_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext)); gc_mark_internal(RCLASSEXT_CLASSPATH(ext)); } @@ -3716,29 +3693,6 @@ update_m_tbl(void *objspace, struct rb_id_table *tbl) } static enum rb_id_table_iterator_result -update_cvc_tbl_i(VALUE cvc_entry, void *objspace) -{ - struct rb_cvar_class_tbl_entry *entry; - - entry = (struct rb_cvar_class_tbl_entry *)cvc_entry; - - if (entry->cref) { - TYPED_UPDATE_IF_MOVED(objspace, rb_cref_t *, entry->cref); - } - - entry->class_value = gc_location_internal(objspace, entry->class_value); - - return ID_TABLE_CONTINUE; -} - -static void -update_cvc_tbl(void *objspace, struct rb_id_table *tbl) -{ - if (!tbl) return; - rb_id_table_foreach_values(tbl, update_cvc_tbl_i, objspace); -} - -static enum rb_id_table_iterator_result update_const_tbl_i(VALUE value, void *objspace) { rb_const_entry_t *ce = (rb_const_entry_t *)value; @@ -3812,7 +3766,7 @@ update_classext(rb_classext_t *ext, bool is_prime, VALUE box_value, void *arg) update_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext)); } UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext)); - update_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext)); + UPDATE_IF_MOVED(objspace, RCLASSEXT_CVC_TBL(ext)); update_superclasses(objspace, ext); update_subclasses(objspace, ext); @@ -3831,6 +3785,7 @@ update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE box_value, void update_m_tbl(objspace, RCLASSEXT_M_TBL(ext)); update_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext)); UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext)); + UPDATE_IF_MOVED(objspace, RCLASSEXT_CVC_TBL(ext)); update_subclasses(objspace, ext); update_classext_values(objspace, ext, true); diff --git a/id_table.c b/id_table.c index cece14c389..0bcdfaf408 100644 --- a/id_table.c +++ b/id_table.c @@ -438,3 +438,82 @@ rb_managed_id_table_delete(VALUE table, ID id) { return rb_id_table_delete(managed_id_table_ptr(table), id); } + +static enum rb_id_table_iterator_result +marked_id_table_mark_i(VALUE val, void *data) +{ + rb_gc_mark_movable(val); + return ID_TABLE_CONTINUE; +} + +static void +marked_id_table_mark(void *ptr) +{ + struct rb_id_table *tbl = (struct rb_id_table *)ptr; + rb_id_table_foreach_values(tbl, marked_id_table_mark_i, NULL); +} + +static enum rb_id_table_iterator_result +marked_id_table_compact_check_i(VALUE value, void *data) +{ + if (rb_gc_location(value) != value) { + return ID_TABLE_REPLACE; + } + return ID_TABLE_CONTINUE; +} + +static enum rb_id_table_iterator_result +marked_id_table_compact_replace_i(VALUE *value, void *data, int existing) +{ + *value = rb_gc_location(*value); + return ID_TABLE_CONTINUE; +} + +static void +marked_id_table_compact(void *ptr) +{ + struct rb_id_table *tbl = (struct rb_id_table *)ptr; + rb_id_table_foreach_values_with_replace(tbl, marked_id_table_compact_check_i, marked_id_table_compact_replace_i, NULL); +} + +const rb_data_type_t rb_marked_id_table_type = { + .wrap_struct_name = "VM/marked_id_table", + .function = { + .dmark = marked_id_table_mark, + .dfree = managed_id_table_free, + .dsize = managed_id_table_memsize, + .dcompact = marked_id_table_compact, + }, + .parent = &rb_managed_id_table_type, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, +}; + +VALUE +rb_marked_id_table_new(size_t capa) +{ + return rb_managed_id_table_create(&rb_marked_id_table_type, capa); +} + +int +rb_marked_id_table_insert(VALUE table, ID id, VALUE val) +{ + int result = rb_managed_id_table_insert(table, id, val); + RB_OBJ_WRITTEN(table, Qundef, val); + return result; +} + +static enum rb_id_table_iterator_result +marked_id_table_dup_i(VALUE val, void *data) +{ + VALUE new_table = (VALUE)data; + RB_OBJ_WRITTEN(new_table, Qundef, val); + return ID_TABLE_CONTINUE; +} + +VALUE +rb_marked_id_table_dup(VALUE old_table) +{ + VALUE new_table = rb_managed_id_table_dup(old_table); + rb_managed_id_table_foreach_values(new_table, marked_id_table_dup_i, (void *)new_table); + return new_table; +} diff --git a/id_table.h b/id_table.h index 0c8cd343ee..fde1a0a2c0 100644 --- a/id_table.h +++ b/id_table.h @@ -47,6 +47,16 @@ int rb_managed_id_table_delete(VALUE table, ID id); extern const rb_data_type_t rb_managed_id_table_type; +VALUE rb_marked_id_table_new(size_t capa); +int rb_marked_id_table_insert(VALUE table, ID id, VALUE val); +VALUE rb_marked_id_table_dup(VALUE table); + +// alisases +#define rb_marked_id_table_size rb_managed_id_table_size +#define rb_marked_id_table_lookup rb_managed_id_table_lookup +#define rb_marked_id_table_foreach rb_managed_id_table_foreach +#define rb_marked_id_table_foreach_values rb_managed_id_table_foreach_values + RUBY_SYMBOL_EXPORT_BEGIN size_t rb_id_table_size(const struct rb_id_table *tbl); RUBY_SYMBOL_EXPORT_END @@ -29,6 +29,7 @@ rb_imemo_name(enum imemo_type type) IMEMO_NAME(svar); IMEMO_NAME(throw_data); IMEMO_NAME(tmpbuf); + IMEMO_NAME(cvar_entry); IMEMO_NAME(fields); #undef IMEMO_NAME } @@ -247,6 +248,8 @@ rb_imemo_memsize(VALUE obj) size += ((rb_imemo_tmpbuf_t *)obj)->cnt * sizeof(VALUE); break; + case imemo_cvar_entry: + break; case imemo_fields: if (FL_TEST_RAW(obj, OBJ_FIELD_HEAP)) { if (rb_shape_obj_too_complex_p(obj)) { @@ -495,6 +498,12 @@ rb_imemo_mark_and_move(VALUE obj, bool reference_updating) break; } + case imemo_cvar_entry: { + struct rb_cvar_class_tbl_entry *ent = (struct rb_cvar_class_tbl_entry *)obj; + rb_gc_mark_and_move(&ent->class_value); + rb_gc_mark_and_move((VALUE *)&ent->cref); + break; + } case imemo_fields: { rb_gc_mark_and_move((VALUE *)&RBASIC(obj)->klass); @@ -624,6 +633,10 @@ rb_imemo_free(VALUE obj) RB_DEBUG_COUNTER_INC(obj_imemo_tmpbuf); break; + case imemo_cvar_entry: + RB_DEBUG_COUNTER_INC(obj_imemo_cvar_entry); + + break; case imemo_fields: imemo_fields_free(IMEMO_OBJ_FIELDS(obj)); RB_DEBUG_COUNTER_INC(obj_imemo_fields); diff --git a/internal/class.h b/internal/class.h index 164081b569..b2c6b45416 100644 --- a/internal/class.h +++ b/internal/class.h @@ -35,9 +35,10 @@ struct rb_subclass_entry { typedef struct rb_subclass_entry rb_subclass_entry_t; struct rb_cvar_class_tbl_entry { + VALUE imemo_flags; uint32_t index; rb_serial_t global_cvar_state; - const rb_cref_t * cref; + const rb_cref_t *cref; VALUE class_value; }; @@ -49,7 +50,7 @@ struct rb_classext_struct { struct rb_id_table *const_tbl; struct rb_id_table *callable_m_tbl; VALUE cc_tbl; /* { ID => { cme, [cc1, cc2, ...] }, ... } */ - struct rb_id_table *cvc_tbl; + VALUE cvc_tbl; VALUE *superclasses; /** * The head of the subclasses linked list. This is a dummy entry (klass == 0) @@ -226,8 +227,8 @@ static inline void RCLASS_SET_CONST_TBL(VALUE klass, struct rb_id_table *table, static inline void RCLASS_WRITE_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared); static inline void RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table); static inline void RCLASS_WRITE_CC_TBL(VALUE klass, VALUE table); -static inline void RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table); -static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table); +static inline void RCLASS_SET_CVC_TBL(VALUE klass, VALUE table); +static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, VALUE table); static inline void RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool with_self); static inline void RCLASS_SET_SUBCLASSES(VALUE klass, rb_subclass_entry_t *head); @@ -598,15 +599,15 @@ RCLASS_WRITE_CC_TBL(VALUE klass, VALUE table) } static inline void -RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table) +RCLASS_SET_CVC_TBL(VALUE klass, VALUE table) { - RCLASSEXT_CVC_TBL(RCLASS_EXT_PRIME(klass)) = table; + RB_OBJ_ATOMIC_WRITE(klass, &RCLASSEXT_CVC_TBL(RCLASS_EXT_PRIME(klass)), table); } static inline void -RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table) +RCLASS_WRITE_CVC_TBL(VALUE klass, VALUE table) { - RCLASSEXT_CVC_TBL(RCLASS_EXT_WRITABLE(klass)) = table; + RB_OBJ_ATOMIC_WRITE(klass, &RCLASSEXT_CVC_TBL(RCLASS_EXT_WRITABLE(klass)), table); } static inline void diff --git a/internal/imemo.h b/internal/imemo.h index f8bda26f0b..aeaf636a50 100644 --- a/internal/imemo.h +++ b/internal/imemo.h @@ -37,6 +37,7 @@ enum imemo_type { imemo_ment = 6, imemo_iseq = 7, imemo_tmpbuf = 8, + imemo_cvar_entry = 9, imemo_callinfo = 10, imemo_callcache = 11, imemo_constcache = 12, @@ -298,9 +298,7 @@ rb_iseq_mark_and_move_each_body_value(const rb_iseq_t *iseq, VALUE *original_ise for (unsigned int i = 0; i < body->icvarc_size; i++, is_entries++) { ICVARC icvarc = (ICVARC)is_entries; if (icvarc->entry) { - RUBY_ASSERT(!RB_TYPE_P(icvarc->entry->class_value, T_NONE)); - - rb_gc_mark_and_move(&icvarc->entry->class_value); + rb_gc_mark_and_move((VALUE *)&icvarc->entry); } } diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb index 313a013c07..d087f25b4d 100644 --- a/test/ruby/test_box.rb +++ b/test/ruby/test_box.rb @@ -154,6 +154,37 @@ class TestBox < Test::Unit::TestCase assert Ruby::Box.current.inspect.include?("main") end + def test_class_variables + # [Bug #21952] + assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "here = '#{__dir__}'; #{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true) + begin; + Ruby::Box.root.eval(<<~RUBY) + module M + @@x = 1 + end + + class A + include M + end + + class B < A + end + RUBY + + code = <<~REPRO + class ::B + @@x += 1 + end + REPRO + + b1 = Ruby::Box.new + assert_equal 2, b1.eval(code) + + b2 = Ruby::Box.new + assert_equal 2, b2.eval(code) + end; + end + def test_autoload_in_box setup_box diff --git a/variable.c b/variable.c index 04e2eaea52..aabe6b6c03 100644 --- a/variable.c +++ b/variable.c @@ -4278,22 +4278,29 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) bool new_cvar = rb_class_ivar_set(target, id, val); - struct rb_id_table *rb_cvc_tbl = RCLASS_WRITABLE_CVC_TBL(target); - - if (!rb_cvc_tbl) { - rb_cvc_tbl = rb_id_table_create(2); - RCLASS_WRITE_CVC_TBL(target, rb_cvc_tbl); - } + VALUE cvc_tbl = RCLASS_WRITABLE_CVC_TBL(target); struct rb_cvar_class_tbl_entry *ent; VALUE ent_data; - if (!rb_id_table_lookup(rb_cvc_tbl, id, &ent_data)) { - ent = ALLOC(struct rb_cvar_class_tbl_entry); - ent->class_value = target; + if (!cvc_tbl || !rb_marked_id_table_lookup(cvc_tbl, id, &ent_data)) { + ent = (struct rb_cvar_class_tbl_entry *)SHAREABLE_IMEMO_NEW(struct rb_cvar_class_tbl_entry, imemo_cvar_entry, 0); + RB_OBJ_WRITE((VALUE)ent, &ent->class_value, target); + RB_OBJ_WRITE((VALUE)ent, &ent->cref, 0); ent->global_cvar_state = GET_GLOBAL_CVAR_STATE(); - ent->cref = 0; - rb_id_table_insert(rb_cvc_tbl, id, (VALUE)ent); + + VALUE new_cvc_tbl = cvc_tbl; + if (!new_cvc_tbl) { + new_cvc_tbl = rb_marked_id_table_new(2); + } + else if (rb_multi_ractor_p()) { + new_cvc_tbl = rb_marked_id_table_new(rb_marked_id_table_size(cvc_tbl) + 1); + } + + rb_marked_id_table_insert(new_cvc_tbl, id, (VALUE)ent); + if (new_cvc_tbl != cvc_tbl) { + RCLASS_WRITE_CVC_TBL(target, new_cvc_tbl); + } RB_DEBUG_COUNTER_INC(cvar_inline_miss); } else { diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 2ad67461bb..b88873c0da 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1604,24 +1604,23 @@ update_classvariable_cache(const rb_iseq_t *iseq, VALUE klass, ID id, const rb_c defined_class = RBASIC(defined_class)->klass; } - struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(defined_class); + VALUE rb_cvc_tbl = RCLASS_CVC_TBL(defined_class); if (!rb_cvc_tbl) { rb_bug("the cvc table should be set"); } VALUE ent_data; - if (!rb_id_table_lookup(rb_cvc_tbl, id, &ent_data)) { + if (!rb_marked_id_table_lookup(rb_cvc_tbl, id, &ent_data)) { rb_bug("should have cvar cache entry"); } struct rb_cvar_class_tbl_entry *ent = (void *)ent_data; ent->global_cvar_state = GET_GLOBAL_CVAR_STATE(); - ent->cref = cref; + RB_OBJ_WRITE((VALUE)ent, &ent->cref, cref); ic->entry = ent; RUBY_ASSERT(BUILTIN_TYPE((VALUE)cref) == T_IMEMO && IMEMO_TYPE_P(cref, imemo_cref)); - RB_OBJ_WRITTEN(iseq, Qundef, ent->cref); RB_OBJ_WRITTEN(iseq, Qundef, ent->class_value); RB_OBJ_WRITTEN(ent->class_value, Qundef, ent->cref); diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 952cf88c20..586f9c1ebd 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -358,6 +358,7 @@ pub const imemo_memo: imemo_type = 5; pub const imemo_ment: imemo_type = 6; pub const imemo_iseq: imemo_type = 7; pub const imemo_tmpbuf: imemo_type = 8; +pub const imemo_cvar_entry: imemo_type = 9; pub const imemo_callinfo: imemo_type = 10; pub const imemo_callcache: imemo_type = 11; pub const imemo_constcache: imemo_type = 12; @@ -640,6 +641,7 @@ pub const SHAPE_ID_HAS_IVAR_MASK: shape_id_mask = 134742014; pub type shape_id_mask = u32; #[repr(C)] pub struct rb_cvar_class_tbl_entry { + pub imemo_flags: VALUE, pub index: u32, pub global_cvar_state: rb_serial_t, pub cref: *const rb_cref_t, diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 2689ec30cf..e1f446b0af 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -425,6 +425,7 @@ pub const imemo_memo: imemo_type = 5; pub const imemo_ment: imemo_type = 6; pub const imemo_iseq: imemo_type = 7; pub const imemo_tmpbuf: imemo_type = 8; +pub const imemo_cvar_entry: imemo_type = 9; pub const imemo_callinfo: imemo_type = 10; pub const imemo_callcache: imemo_type = 11; pub const imemo_constcache: imemo_type = 12; @@ -1429,6 +1430,7 @@ pub const SHAPE_ID_FLAGS_MASK: shape_id_fl_type = 264241152; pub type shape_id_fl_type = u32; #[repr(C)] pub struct rb_cvar_class_tbl_entry { + pub imemo_flags: VALUE, pub index: u32, pub global_cvar_state: rb_serial_t, pub cref: *const rb_cref_t, |
