diff options
author | Satoshi Tagomori <[email protected]> | 2025-04-30 13:48:02 +0900 |
---|---|---|
committer | Satoshi Tagomori <[email protected]> | 2025-05-11 23:32:50 +0900 |
commit | 382645d440d5da66a0c04557f3ff2ca226de3a27 () | |
tree | b7453449930197237e739d0985561b664f51b0f3 | |
parent | 49742414f6444960838bb968bab43db27f5872c1 (diff) |
namespace on read
86 files changed, 5839 insertions, 691 deletions
@@ -32,8 +32,8 @@ builtin_lookup(const char *feature, size_t *psize) return bin; } -void -rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table) { // search binary size_t size; @@ -50,8 +50,22 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin ASSUME(iseq); // otherwise an exception should have raised vm->builtin_function_table = NULL; // exec - rb_iseq_eval(rb_iseq_check(iseq)); } #endif @@ -71,5 +85,5 @@ Init_builtin(void) void Init_builtin_features(void) { - rb_load_with_builtin_functions("gem_prelude", NULL); } @@ -24,6 +24,7 @@ #include "internal/class.h" #include "internal/eval.h" #include "internal/hash.h" #include "internal/object.h" #include "internal/string.h" #include "internal/variable.h" @@ -38,9 +39,7 @@ * This is done for classes defined from C to allow storing them in global variables. * 1: RUBY_FL_SINGLETON * This class is a singleton class. - * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF - * The RCLASS_SUPERCLASSES contains the class as the last element. - * This means that this class owns the RCLASS_SUPERCLASSES list. * if !SHAPE_IN_BASIC_FLAGS * 4-19: SHAPE_FLAG_MASK * Shape ID for the class. @@ -49,8 +48,8 @@ /* Flags of T_ICLASS * - * 0: RICLASS_IS_ORIGIN - * 3: RICLASS_ORIGIN_SHARED_MTBL * The T_ICLASS does not own the method table. * if !SHAPE_IN_BASIC_FLAGS * 4-19: SHAPE_FLAG_MASK @@ -65,8 +64,7 @@ * This is done for classes defined from C to allow storing them in global variables. * 1: RMODULE_ALLOCATED_BUT_NOT_INITIALIZED * Module has not been initialized. - * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF - * See RCLASS_SUPERCLASSES_INCLUDE_SELF in T_CLASS. * 3: RMODULE_IS_REFINEMENT * Module is used for refinements. * if !SHAPE_IN_BASIC_FLAGS @@ -80,124 +78,996 @@ RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state; -static rb_subclass_entry_t * -push_subclass_entry_to_list(VALUE super, VALUE klass) { - rb_subclass_entry_t *entry = ZALLOC(rb_subclass_entry_t); entry->klass = klass; RB_VM_LOCK_ENTER(); { - rb_subclass_entry_t *head = RCLASS_SUBCLASSES(super); - if (!head) { - head = ZALLOC(rb_subclass_entry_t); - RCLASS_SUBCLASSES(super) = head; - } - entry->next = head->next; - entry->prev = head; - if (head->next) { head->next->prev = entry; } head->next = entry; } RB_VM_LOCK_LEAVE(); - return entry; } void rb_class_subclass_add(VALUE super, VALUE klass) { if (super && !UNDEF_P(super)) { - rb_subclass_entry_t *entry = push_subclass_entry_to_list(super, klass); - RCLASS_SUBCLASS_ENTRY(klass) = entry; } } static void rb_module_add_to_subclasses_list(VALUE module, VALUE iclass) { - rb_subclass_entry_t *entry = push_subclass_entry_to_list(module, iclass); - RCLASS_MODULE_SUBCLASS_ENTRY(iclass) = entry; } void -rb_class_remove_subclass_head(VALUE klass) { - rb_subclass_entry_t *head = RCLASS_SUBCLASSES(klass); - if (head) { - if (head->next) { - head->next->prev = NULL; - } - RCLASS_SUBCLASSES(klass) = NULL; - xfree(head); } } -void -rb_class_remove_from_super_subclasses(VALUE klass) { - rb_subclass_entry_t *entry = RCLASS_SUBCLASS_ENTRY(klass); - if (entry) { - rb_subclass_entry_t *prev = entry->prev, *next = entry->next; - if (prev) { - prev->next = next; - } - if (next) { - next->prev = prev; - } - xfree(entry); } - RCLASS_SUBCLASS_ENTRY(klass) = NULL; } void rb_class_remove_from_module_subclasses(VALUE klass) { - rb_subclass_entry_t *entry = RCLASS_MODULE_SUBCLASS_ENTRY(klass); - if (entry) { - rb_subclass_entry_t *prev = entry->prev, *next = entry->next; - if (prev) { - prev->next = next; - } - if (next) { - next->prev = prev; - } xfree(entry); } - RCLASS_MODULE_SUBCLASS_ENTRY(klass) = NULL; } void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE arg) { - // RCLASS_SUBCLASSES should always point to our head element which has NULL klass - rb_subclass_entry_t *cur = RCLASS_SUBCLASSES(klass); - // if we have a subclasses list, then the head is a placeholder with no valid - // class. So ignore it and use the next element in the list (if one exists) - if (cur) { - RUBY_ASSERT(!cur->klass); - cur = cur->next; - } - /* do not be tempted to simplify this loop into a for loop, the order of operations is important here if `f` modifies the linked list */ while (cur) { VALUE curklass = cur->klass; - cur = cur->next; // do not trigger GC during f, otherwise the cur will become // a dangling pointer if the subclass is collected f(curklass, arg); } } @@ -225,6 +1095,13 @@ rb_class_detach_module_subclasses(VALUE klass) rb_class_foreach_subclass(klass, class_detach_module_subclasses, Qnil); } /** * Allocates a struct RClass for a new class. * @@ -240,6 +1117,9 @@ rb_class_detach_module_subclasses(VALUE klass) static VALUE class_alloc(VALUE flags, VALUE klass) { size_t alloc_size = sizeof(struct RClass) + sizeof(rb_classext_t); flags &= T_MASK; @@ -253,21 +1133,61 @@ class_alloc(VALUE flags, VALUE klass) RCLASS_M_TBL(obj) = 0; RCLASS_FIELDS(obj) = 0; RCLASS_SET_SUPER((VALUE)obj, 0); - RCLASS_SUBCLASSES(obj) = NULL; - RCLASS_PARENT_SUBCLASSES(obj) = NULL; - RCLASS_MODULE_SUBCLASSES(obj) = NULL; */ RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj); - RB_OBJ_WRITE(obj, &RCLASS_REFINED_CLASS(obj), Qnil); RCLASS_SET_ALLOCATOR((VALUE)obj, 0); return (VALUE)obj; } static void -RCLASS_M_TBL_INIT(VALUE c) { - RCLASS_M_TBL(c) = rb_id_table_create(0); } /** @@ -284,8 +1204,8 @@ rb_class_boot(VALUE super) { VALUE klass = class_alloc(T_CLASS, rb_cClass); - RCLASS_SET_SUPER(klass, super); - RCLASS_M_TBL_INIT(klass); return (VALUE)klass; } @@ -293,7 +1213,7 @@ rb_class_boot(VALUE super) static VALUE * class_superclasses_including_self(VALUE klass) { - if (FL_TEST_RAW(klass, RCLASS_SUPERCLASSES_INCLUDE_SELF)) return RCLASS_SUPERCLASSES(klass); size_t depth = RCLASS_SUPERCLASS_DEPTH(klass); @@ -302,14 +1222,14 @@ class_superclasses_including_self(VALUE klass) memcpy(superclasses, RCLASS_SUPERCLASSES(klass), sizeof(VALUE) * depth); superclasses[depth] = klass; - RCLASS_SUPERCLASSES(klass) = superclasses; - FL_SET_RAW(klass, RCLASS_SUPERCLASSES_INCLUDE_SELF); return superclasses; } void rb_class_update_superclasses(VALUE klass) { VALUE super = RCLASS_SUPER(klass); if (!RB_TYPE_P(klass, T_CLASS)) return; @@ -338,8 +1258,14 @@ rb_class_update_superclasses(VALUE klass) return; } - RCLASS_SUPERCLASSES(klass) = class_superclasses_including_self(super); - RCLASS_SUPERCLASS_DEPTH(klass) = RCLASS_SUPERCLASS_DEPTH(super) + 1; } void @@ -365,7 +1291,7 @@ rb_class_new(VALUE super) VALUE klass = rb_class_boot(super); if (super != rb_cObject && super != rb_cBasicObject) { - RCLASS_EXT(klass)->max_iv_count = RCLASS_EXT(super)->max_iv_count; } return klass; @@ -470,7 +1396,7 @@ copy_tables(VALUE clone, VALUE orig) { if (RCLASS_CONST_TBL(clone)) { rb_free_const_table(RCLASS_CONST_TBL(clone)); - RCLASS_CONST_TBL(clone) = 0; } if (RCLASS_CVC_TBL(orig)) { struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(orig); @@ -480,10 +1406,10 @@ copy_tables(VALUE clone, VALUE orig) ctx.clone = clone; ctx.new_table = rb_cvc_tbl_dup; rb_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx); - RCLASS_CVC_TBL(clone) = rb_cvc_tbl_dup; } rb_id_table_free(RCLASS_M_TBL(clone)); - RCLASS_M_TBL(clone) = 0; if (!RB_TYPE_P(clone, T_ICLASS)) { st_data_t id; @@ -495,10 +1421,11 @@ copy_tables(VALUE clone, VALUE orig) } if (RCLASS_CONST_TBL(orig)) { struct clone_const_arg arg; - - arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0); arg.klass = clone; rb_id_table_foreach(RCLASS_CONST_TBL(orig), clone_const_i, &arg); } } @@ -550,8 +1477,8 @@ rb_mod_init_copy(VALUE clone, VALUE orig) /* cloned flag is refer at constant inline cache * see vm_get_const_key_cref() in vm_insnhelper.c */ - RCLASS_EXT(clone)->cloned = true; - RCLASS_EXT(orig)->cloned = true; if (!RCLASS_SINGLETON_P(CLASS_OF(clone))) { RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig)); @@ -563,12 +1490,12 @@ rb_mod_init_copy(VALUE clone, VALUE orig) struct clone_method_arg arg; arg.old_klass = orig; arg.new_klass = clone; - RCLASS_M_TBL_INIT(clone); rb_id_table_foreach(RCLASS_M_TBL(orig), clone_method_i, &arg); } if (RCLASS_ORIGIN(orig) == orig) { - RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig)); } else { VALUE p = RCLASS_SUPER(orig); @@ -593,9 +1520,9 @@ rb_mod_init_copy(VALUE clone, VALUE orig) * that can trigger GC to avoid clone_p from becoming old and * needing to fire write barriers. */ RCLASS_SET_M_TBL(clone_p, RCLASS_M_TBL(p)); - RCLASS_SET_SUPER(prev_clone_p, clone_p); prev_clone_p = clone_p; - RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p); RCLASS_SET_ALLOCATOR(clone_p, RCLASS_ALLOCATOR(p)); if (RB_TYPE_P(clone, T_CLASS)) { RCLASS_SET_INCLUDER(clone_p, clone); @@ -608,8 +1535,8 @@ rb_mod_init_copy(VALUE clone, VALUE orig) } else if ((origin_len = RARRAY_LEN(origin_stack)) > 1 && RARRAY_AREF(origin_stack, origin_len - 1) == p) { - RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), clone_p); - RICLASS_SET_ORIGIN_SHARED_MTBL(clone_p); rb_ary_resize(origin_stack, origin_len); add_subclass = FALSE; } @@ -621,15 +1548,15 @@ rb_mod_init_copy(VALUE clone, VALUE orig) if (p == orig_origin) { if (clone_p) { - RCLASS_SET_SUPER(clone_p, clone_origin); - RCLASS_SET_SUPER(clone_origin, RCLASS_SUPER(orig_origin)); } copy_tables(clone_origin, orig_origin); if (RCLASS_M_TBL(orig_origin)) { struct clone_method_arg arg; arg.old_klass = orig; arg.new_klass = clone; - RCLASS_M_TBL_INIT(clone_origin); rb_id_table_foreach(RCLASS_M_TBL(orig_origin), clone_method_i, &arg); } } @@ -680,18 +1607,20 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) RBASIC_SET_CLASS(clone, klass_metaclass_clone); } - RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass)); rb_fields_tbl_copy(clone, klass); if (RCLASS_CONST_TBL(klass)) { struct clone_const_arg arg; - arg.tbl = RCLASS_CONST_TBL(clone) = rb_id_table_create(0); arg.klass = clone; rb_id_table_foreach(RCLASS_CONST_TBL(klass), clone_const_i, &arg); } if (!UNDEF_P(attach)) { rb_singleton_class_attached(clone, attach); } - RCLASS_M_TBL_INIT(clone); { struct clone_method_arg arg; arg.old_klass = klass; @@ -785,7 +1714,7 @@ make_metaclass(VALUE klass) super = RCLASS_SUPER(klass); while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); - RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass); // Full class ancestry may not have been filled until we reach here. rb_class_update_superclasses(METACLASS_OF(metaclass)); @@ -985,8 +1914,12 @@ rb_define_class(const char *name, VALUE super) { VALUE klass; ID id; id = rb_intern(name); if (rb_const_defined(rb_cObject, id)) { klass = rb_const_get(rb_cObject, id); if (!RB_TYPE_P(klass, T_CLASS)) { @@ -1063,7 +1996,7 @@ VALUE rb_module_s_alloc(VALUE klass) { VALUE mod = class_alloc(T_MODULE, klass); - RCLASS_M_TBL_INIT(mod); FL_SET(mod, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED); return mod; } @@ -1072,7 +2005,7 @@ static inline VALUE module_new(VALUE klass) { VALUE mdl = class_alloc(T_MODULE, klass); - RCLASS_M_TBL_INIT(mdl); return (VALUE)mdl; } @@ -1100,8 +2033,12 @@ rb_define_module(const char *name) { VALUE module; ID id; id = rb_intern(name); if (rb_const_defined(rb_cObject, id)) { module = rb_const_get(rb_cObject, id); if (!RB_TYPE_P(module, T_MODULE)) { @@ -1154,21 +2091,23 @@ rb_include_class_new(VALUE module, VALUE super) { VALUE klass = class_alloc(T_ICLASS, rb_cClass); - RCLASS_SET_M_TBL(klass, RCLASS_M_TBL(module)); RCLASS_SET_ORIGIN(klass, klass); if (BUILTIN_TYPE(module) == T_ICLASS) { module = METACLASS_OF(module); } RUBY_ASSERT(!RB_TYPE_P(module, T_ICLASS)); - if (!RCLASS_CONST_TBL(module)) { - RCLASS_CONST_TBL(module) = rb_id_table_create(0); } - RCLASS_CVC_TBL(klass) = RCLASS_CVC_TBL(module); - RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module); - RCLASS_SET_SUPER(klass, super); RBASIC_SET_CLASS(klass, module); return (VALUE)klass; @@ -1199,13 +2138,7 @@ rb_include_module(VALUE klass, VALUE module) rb_raise(rb_eArgError, "cyclic include detected"); if (RB_TYPE_P(klass, T_MODULE)) { - rb_subclass_entry_t *iclass = RCLASS_SUBCLASSES(klass); - // skip the placeholder subclass entry at the head of the list - if (iclass) { - RUBY_ASSERT(!iclass->klass); - iclass = iclass->next; - } - while (iclass) { int do_include = 1; VALUE check_class = iclass->klass; @@ -1336,7 +2269,7 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super // setup T_ICLASS for the include/prepend module iclass = rb_include_class_new(module, super_class); - c = RCLASS_SET_SUPER(c, iclass); RCLASS_SET_INCLUDER(iclass, klass); if (module != RCLASS_ORIGIN(module)) { if (!origin_stack) origin_stack = rb_ary_hidden_new(2); @@ -1345,8 +2278,8 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super } else if (origin_stack && (origin_len = RARRAY_LEN(origin_stack)) > 1 && RARRAY_AREF(origin_stack, origin_len - 1) == module) { - RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass); - RICLASS_SET_ORIGIN_SHARED_MTBL(iclass); rb_ary_resize(origin_stack, origin_len); } @@ -1385,7 +2318,7 @@ move_refined_method(ID key, VALUE value, void *data) if (me->def->type == VM_METHOD_TYPE_REFINED) { VALUE klass = (VALUE)data; - struct rb_id_table *tbl = RCLASS_M_TBL(klass); if (me->def->body.refined.orig_me) { const rb_method_entry_t *orig_me = me->def->body.refined.orig_me, *new_me; @@ -1427,10 +2360,10 @@ ensure_origin(VALUE klass) if (origin == klass) { origin = class_alloc(T_ICLASS, klass); RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass)); - RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass)); - RCLASS_SET_SUPER(klass, origin); - RCLASS_SET_ORIGIN(klass, origin); - RCLASS_M_TBL_INIT(klass); rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass); rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass); return true; @@ -1455,13 +2388,7 @@ rb_prepend_module(VALUE klass, VALUE module) rb_vm_check_redefinition_by_prepend(klass); } if (RB_TYPE_P(klass, T_MODULE)) { - rb_subclass_entry_t *iclass = RCLASS_SUBCLASSES(klass); - // skip the placeholder subclass entry at the head of the list if it exists - if (iclass) { - RUBY_ASSERT(!iclass->klass); - iclass = iclass->next; - } - VALUE klass_origin = RCLASS_ORIGIN(klass); struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass); struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin); @@ -1473,11 +2400,11 @@ rb_prepend_module(VALUE klass, VALUE module) if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(subclass)) { // backfill an origin iclass to handle refinements and future prepends rb_id_table_foreach(RCLASS_M_TBL(subclass), clear_module_cache_i, (void *)subclass); - RCLASS_M_TBL(subclass) = klass_m_tbl; VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(subclass)); - RCLASS_SET_SUPER(subclass, origin); RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(subclass)); - RCLASS_SET_ORIGIN(subclass, origin); RICLASS_SET_ORIGIN_SHARED_MTBL(origin); } include_modules_at(subclass, subclass, module, FALSE); @@ -1553,7 +2480,7 @@ rb_mod_include_p(VALUE mod, VALUE mod2) Check_Type(mod2, T_MODULE); for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) { - if (BUILTIN_TYPE(p) == T_ICLASS && !FL_TEST(p, RICLASS_IS_ORIGIN)) { if (METACLASS_OF(p) == mod2) return Qtrue; } } @@ -140,6 +140,7 @@ COMMONOBJS = array.$(OBJEXT) \ marshal.$(OBJEXT) \ math.$(OBJEXT) \ memory_view.$(OBJEXT) \ node.$(OBJEXT) \ node_dump.$(OBJEXT) \ numeric.$(OBJEXT) \ @@ -2116,6 +2117,7 @@ array.$(OBJEXT): $(top_srcdir)/internal/fixnum.h array.$(OBJEXT): $(top_srcdir)/internal/gc.h array.$(OBJEXT): $(top_srcdir)/internal/hash.h array.$(OBJEXT): $(top_srcdir)/internal/imemo.h array.$(OBJEXT): $(top_srcdir)/internal/numeric.h array.$(OBJEXT): $(top_srcdir)/internal/object.h array.$(OBJEXT): $(top_srcdir)/internal/proc.h @@ -2333,6 +2335,7 @@ ast.$(OBJEXT): $(top_srcdir)/internal/complex.h ast.$(OBJEXT): $(top_srcdir)/internal/fixnum.h ast.$(OBJEXT): $(top_srcdir)/internal/gc.h ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h ast.$(OBJEXT): $(top_srcdir)/internal/numeric.h ast.$(OBJEXT): $(top_srcdir)/internal/parse.h ast.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -2572,6 +2575,7 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/complex.h bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h bignum.$(OBJEXT): $(top_srcdir)/internal/imemo.h bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h bignum.$(OBJEXT): $(top_srcdir)/internal/object.h bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -2777,6 +2781,7 @@ builtin.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h builtin.$(OBJEXT): $(top_srcdir)/internal/compilers.h builtin.$(OBJEXT): $(top_srcdir)/internal/gc.h builtin.$(OBJEXT): $(top_srcdir)/internal/imemo.h builtin.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h builtin.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -3008,6 +3013,7 @@ class.$(OBJEXT): $(top_srcdir)/internal/eval.h class.$(OBJEXT): $(top_srcdir)/internal/gc.h class.$(OBJEXT): $(top_srcdir)/internal/hash.h class.$(OBJEXT): $(top_srcdir)/internal/imemo.h class.$(OBJEXT): $(top_srcdir)/internal/object.h class.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h class.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -3408,6 +3414,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/gc.h compile.$(OBJEXT): $(top_srcdir)/internal/hash.h compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h compile.$(OBJEXT): $(top_srcdir)/internal/io.h compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h compile.$(OBJEXT): $(top_srcdir)/internal/object.h compile.$(OBJEXT): $(top_srcdir)/internal/parse.h @@ -3669,6 +3676,7 @@ complex.$(OBJEXT): $(top_srcdir)/internal/fixnum.h complex.$(OBJEXT): $(top_srcdir)/internal/gc.h complex.$(OBJEXT): $(top_srcdir)/internal/imemo.h complex.$(OBJEXT): $(top_srcdir)/internal/math.h complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h complex.$(OBJEXT): $(top_srcdir)/internal/object.h complex.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -3881,6 +3889,7 @@ cont.$(OBJEXT): $(top_srcdir)/internal/cont.h cont.$(OBJEXT): $(top_srcdir)/internal/error.h cont.$(OBJEXT): $(top_srcdir)/internal/gc.h cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h cont.$(OBJEXT): $(top_srcdir)/internal/proc.h cont.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h cont.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -4120,6 +4129,7 @@ debug.$(OBJEXT): $(top_srcdir)/internal/class.h debug.$(OBJEXT): $(top_srcdir)/internal/compilers.h debug.$(OBJEXT): $(top_srcdir)/internal/gc.h debug.$(OBJEXT): $(top_srcdir)/internal/imemo.h debug.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h debug.$(OBJEXT): $(top_srcdir)/internal/serial.h debug.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -4500,6 +4510,7 @@ dir.$(OBJEXT): $(top_srcdir)/internal/file.h dir.$(OBJEXT): $(top_srcdir)/internal/gc.h dir.$(OBJEXT): $(top_srcdir)/internal/imemo.h dir.$(OBJEXT): $(top_srcdir)/internal/io.h dir.$(OBJEXT): $(top_srcdir)/internal/object.h dir.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h dir.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -4701,6 +4712,7 @@ dir.$(OBJEXT): {$(VPATH)}vm_core.h dir.$(OBJEXT): {$(VPATH)}vm_opts.h dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h dln.$(OBJEXT): {$(VPATH)}assert.h dln.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -6431,6 +6443,7 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/fixnum.h enumerator.$(OBJEXT): $(top_srcdir)/internal/gc.h enumerator.$(OBJEXT): $(top_srcdir)/internal/hash.h enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -6647,6 +6660,7 @@ error.$(OBJEXT): $(top_srcdir)/internal/hash.h error.$(OBJEXT): $(top_srcdir)/internal/imemo.h error.$(OBJEXT): $(top_srcdir)/internal/io.h error.$(OBJEXT): $(top_srcdir)/internal/load.h error.$(OBJEXT): $(top_srcdir)/internal/object.h error.$(OBJEXT): $(top_srcdir)/internal/process.h error.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -6871,6 +6885,7 @@ eval.$(OBJEXT): $(top_srcdir)/internal/hash.h eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h eval.$(OBJEXT): $(top_srcdir)/internal/inits.h eval.$(OBJEXT): $(top_srcdir)/internal/io.h eval.$(OBJEXT): $(top_srcdir)/internal/object.h eval.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h eval.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -7350,6 +7365,7 @@ gc.$(OBJEXT): $(top_srcdir)/internal/gc.h gc.$(OBJEXT): $(top_srcdir)/internal/hash.h gc.$(OBJEXT): $(top_srcdir)/internal/imemo.h gc.$(OBJEXT): $(top_srcdir)/internal/io.h gc.$(OBJEXT): $(top_srcdir)/internal/numeric.h gc.$(OBJEXT): $(top_srcdir)/internal/object.h gc.$(OBJEXT): $(top_srcdir)/internal/proc.h @@ -7614,6 +7630,7 @@ goruby.$(OBJEXT): $(top_srcdir)/internal/complex.h goruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h goruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h goruby.$(OBJEXT): $(top_srcdir)/internal/parse.h goruby.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -7855,6 +7872,7 @@ hash.$(OBJEXT): $(top_srcdir)/internal/error.h hash.$(OBJEXT): $(top_srcdir)/internal/gc.h hash.$(OBJEXT): $(top_srcdir)/internal/hash.h hash.$(OBJEXT): $(top_srcdir)/internal/imemo.h hash.$(OBJEXT): $(top_srcdir)/internal/object.h hash.$(OBJEXT): $(top_srcdir)/internal/proc.h hash.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -8478,6 +8496,7 @@ io.$(OBJEXT): $(top_srcdir)/internal/gc.h io.$(OBJEXT): $(top_srcdir)/internal/imemo.h io.$(OBJEXT): $(top_srcdir)/internal/inits.h io.$(OBJEXT): $(top_srcdir)/internal/io.h io.$(OBJEXT): $(top_srcdir)/internal/numeric.h io.$(OBJEXT): $(top_srcdir)/internal/object.h io.$(OBJEXT): $(top_srcdir)/internal/process.h @@ -8920,6 +8939,7 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h iseq.$(OBJEXT): $(top_srcdir)/internal/io.h iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -9406,12 +9426,14 @@ load.$(OBJEXT): $(top_srcdir)/internal/compilers.h load.$(OBJEXT): $(top_srcdir)/internal/complex.h load.$(OBJEXT): $(top_srcdir)/internal/dir.h load.$(OBJEXT): $(top_srcdir)/internal/error.h load.$(OBJEXT): $(top_srcdir)/internal/file.h load.$(OBJEXT): $(top_srcdir)/internal/fixnum.h load.$(OBJEXT): $(top_srcdir)/internal/gc.h load.$(OBJEXT): $(top_srcdir)/internal/hash.h load.$(OBJEXT): $(top_srcdir)/internal/imemo.h load.$(OBJEXT): $(top_srcdir)/internal/load.h load.$(OBJEXT): $(top_srcdir)/internal/numeric.h load.$(OBJEXT): $(top_srcdir)/internal/parse.h load.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -10156,6 +10178,7 @@ marshal.$(OBJEXT): $(top_srcdir)/internal/fixnum.h marshal.$(OBJEXT): $(top_srcdir)/internal/gc.h marshal.$(OBJEXT): $(top_srcdir)/internal/hash.h marshal.$(OBJEXT): $(top_srcdir)/internal/imemo.h marshal.$(OBJEXT): $(top_srcdir)/internal/numeric.h marshal.$(OBJEXT): $(top_srcdir)/internal/object.h marshal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -10547,6 +10570,7 @@ memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h memory_view.$(OBJEXT): $(top_srcdir)/internal/gc.h memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h memory_view.$(OBJEXT): $(top_srcdir)/internal/imemo.h memory_view.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h memory_view.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -10757,6 +10781,7 @@ miniinit.$(OBJEXT): $(top_srcdir)/internal/complex.h miniinit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h miniinit.$(OBJEXT): $(top_srcdir)/internal/numeric.h miniinit.$(OBJEXT): $(top_srcdir)/internal/parse.h miniinit.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -11002,6 +11027,206 @@ miniinit.$(OBJEXT): {$(VPATH)}warning.rb miniinit.$(OBJEXT): {$(VPATH)}yjit.rb miniinit.$(OBJEXT): {$(VPATH)}yjit_hook.rb miniinit.$(OBJEXT): {$(VPATH)}zjit.rb node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h node.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -11013,6 +11238,7 @@ node.$(OBJEXT): $(top_srcdir)/internal/compilers.h node.$(OBJEXT): $(top_srcdir)/internal/gc.h node.$(OBJEXT): $(top_srcdir)/internal/hash.h node.$(OBJEXT): $(top_srcdir)/internal/imemo.h node.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h node.$(OBJEXT): $(top_srcdir)/internal/serial.h node.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -11221,6 +11447,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/fixnum.h node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h node_dump.$(OBJEXT): $(top_srcdir)/internal/numeric.h node_dump.$(OBJEXT): $(top_srcdir)/internal/parse.h node_dump.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -11436,6 +11663,7 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/fixnum.h numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h numeric.$(OBJEXT): $(top_srcdir)/internal/imemo.h numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h numeric.$(OBJEXT): $(top_srcdir)/internal/object.h numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -11653,6 +11881,7 @@ object.$(OBJEXT): $(top_srcdir)/internal/fixnum.h object.$(OBJEXT): $(top_srcdir)/internal/gc.h object.$(OBJEXT): $(top_srcdir)/internal/imemo.h object.$(OBJEXT): $(top_srcdir)/internal/inits.h object.$(OBJEXT): $(top_srcdir)/internal/numeric.h object.$(OBJEXT): $(top_srcdir)/internal/object.h object.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -11873,6 +12102,7 @@ pack.$(OBJEXT): $(top_srcdir)/internal/bits.h pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h pack.$(OBJEXT): $(top_srcdir)/internal/gc.h pack.$(OBJEXT): $(top_srcdir)/internal/imemo.h pack.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h pack.$(OBJEXT): $(top_srcdir)/internal/serial.h pack.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -12090,6 +12320,7 @@ parse.$(OBJEXT): $(top_srcdir)/internal/gc.h parse.$(OBJEXT): $(top_srcdir)/internal/hash.h parse.$(OBJEXT): $(top_srcdir)/internal/imemo.h parse.$(OBJEXT): $(top_srcdir)/internal/io.h parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h parse.$(OBJEXT): $(top_srcdir)/internal/parse.h parse.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -13368,6 +13599,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/eval.h proc.$(OBJEXT): $(top_srcdir)/internal/gc.h proc.$(OBJEXT): $(top_srcdir)/internal/hash.h proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h proc.$(OBJEXT): $(top_srcdir)/internal/object.h proc.$(OBJEXT): $(top_srcdir)/internal/proc.h proc.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -13614,6 +13846,7 @@ process.$(OBJEXT): $(top_srcdir)/internal/gc.h process.$(OBJEXT): $(top_srcdir)/internal/hash.h process.$(OBJEXT): $(top_srcdir)/internal/imemo.h process.$(OBJEXT): $(top_srcdir)/internal/io.h process.$(OBJEXT): $(top_srcdir)/internal/numeric.h process.$(OBJEXT): $(top_srcdir)/internal/object.h process.$(OBJEXT): $(top_srcdir)/internal/process.h @@ -13839,6 +14072,7 @@ ractor.$(OBJEXT): $(top_srcdir)/internal/fixnum.h ractor.$(OBJEXT): $(top_srcdir)/internal/gc.h ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h ractor.$(OBJEXT): $(top_srcdir)/internal/object.h ractor.$(OBJEXT): $(top_srcdir)/internal/ractor.h @@ -14061,6 +14295,7 @@ random.$(OBJEXT): $(top_srcdir)/internal/compilers.h random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h random.$(OBJEXT): $(top_srcdir)/internal/gc.h random.$(OBJEXT): $(top_srcdir)/internal/imemo.h random.$(OBJEXT): $(top_srcdir)/internal/numeric.h random.$(OBJEXT): $(top_srcdir)/internal/random.h random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -14467,6 +14702,7 @@ rational.$(OBJEXT): $(top_srcdir)/internal/complex.h rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h rational.$(OBJEXT): $(top_srcdir)/internal/gc.h rational.$(OBJEXT): $(top_srcdir)/internal/imemo.h rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h rational.$(OBJEXT): $(top_srcdir)/internal/object.h rational.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -14676,6 +14912,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/encoding.h re.$(OBJEXT): $(top_srcdir)/internal/gc.h re.$(OBJEXT): $(top_srcdir)/internal/hash.h re.$(OBJEXT): $(top_srcdir)/internal/imemo.h re.$(OBJEXT): $(top_srcdir)/internal/object.h re.$(OBJEXT): $(top_srcdir)/internal/ractor.h re.$(OBJEXT): $(top_srcdir)/internal/re.h @@ -15890,6 +16127,7 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/io.h ruby.$(OBJEXT): $(top_srcdir)/internal/load.h ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h ruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h ruby.$(OBJEXT): $(top_srcdir)/internal/object.h ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h @@ -16321,6 +16559,7 @@ scheduler.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h scheduler.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h scheduler.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -16895,6 +17134,7 @@ shape.$(OBJEXT): $(top_srcdir)/internal/compilers.h shape.$(OBJEXT): $(top_srcdir)/internal/error.h shape.$(OBJEXT): $(top_srcdir)/internal/gc.h shape.$(OBJEXT): $(top_srcdir)/internal/imemo.h shape.$(OBJEXT): $(top_srcdir)/internal/object.h shape.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h shape.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -17107,6 +17347,7 @@ signal.$(OBJEXT): $(top_srcdir)/internal/error.h signal.$(OBJEXT): $(top_srcdir)/internal/eval.h signal.$(OBJEXT): $(top_srcdir)/internal/gc.h signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h signal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h signal.$(OBJEXT): $(top_srcdir)/internal/serial.h signal.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -17873,6 +18114,7 @@ string.$(OBJEXT): $(top_srcdir)/internal/fixnum.h string.$(OBJEXT): $(top_srcdir)/internal/gc.h string.$(OBJEXT): $(top_srcdir)/internal/hash.h string.$(OBJEXT): $(top_srcdir)/internal/imemo.h string.$(OBJEXT): $(top_srcdir)/internal/numeric.h string.$(OBJEXT): $(top_srcdir)/internal/object.h string.$(OBJEXT): $(top_srcdir)/internal/proc.h @@ -18126,6 +18368,7 @@ struct.$(OBJEXT): $(top_srcdir)/internal/error.h struct.$(OBJEXT): $(top_srcdir)/internal/gc.h struct.$(OBJEXT): $(top_srcdir)/internal/hash.h struct.$(OBJEXT): $(top_srcdir)/internal/imemo.h struct.$(OBJEXT): $(top_srcdir)/internal/object.h struct.$(OBJEXT): $(top_srcdir)/internal/proc.h struct.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -18340,6 +18583,7 @@ symbol.$(OBJEXT): $(top_srcdir)/internal/error.h symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h symbol.$(OBJEXT): $(top_srcdir)/internal/imemo.h symbol.$(OBJEXT): $(top_srcdir)/internal/object.h symbol.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -18564,6 +18808,7 @@ thread.$(OBJEXT): $(top_srcdir)/internal/gc.h thread.$(OBJEXT): $(top_srcdir)/internal/hash.h thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h thread.$(OBJEXT): $(top_srcdir)/internal/io.h thread.$(OBJEXT): $(top_srcdir)/internal/object.h thread.$(OBJEXT): $(top_srcdir)/internal/proc.h thread.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -18819,6 +19064,7 @@ time.$(OBJEXT): $(top_srcdir)/internal/fixnum.h time.$(OBJEXT): $(top_srcdir)/internal/gc.h time.$(OBJEXT): $(top_srcdir)/internal/hash.h time.$(OBJEXT): $(top_srcdir)/internal/imemo.h time.$(OBJEXT): $(top_srcdir)/internal/numeric.h time.$(OBJEXT): $(top_srcdir)/internal/rational.h time.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -19391,6 +19637,7 @@ variable.$(OBJEXT): $(top_srcdir)/internal/eval.h variable.$(OBJEXT): $(top_srcdir)/internal/gc.h variable.$(OBJEXT): $(top_srcdir)/internal/hash.h variable.$(OBJEXT): $(top_srcdir)/internal/imemo.h variable.$(OBJEXT): $(top_srcdir)/internal/object.h variable.$(OBJEXT): $(top_srcdir)/internal/re.h variable.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -19608,6 +19855,7 @@ version.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h version.$(OBJEXT): $(top_srcdir)/internal/compilers.h version.$(OBJEXT): $(top_srcdir)/internal/gc.h version.$(OBJEXT): $(top_srcdir)/internal/imemo.h version.$(OBJEXT): $(top_srcdir)/internal/parse.h version.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h version.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -19830,6 +20078,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/hash.h vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h vm.$(OBJEXT): $(top_srcdir)/internal/inits.h vm.$(OBJEXT): $(top_srcdir)/internal/missing.h vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h vm.$(OBJEXT): $(top_srcdir)/internal/object.h vm.$(OBJEXT): $(top_srcdir)/internal/parse.h @@ -20103,6 +20352,7 @@ vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -20335,6 +20585,7 @@ vm_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -20567,6 +20818,7 @@ vm_sync.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -20778,6 +21030,7 @@ vm_trace.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -21016,6 +21269,7 @@ weakmap.$(OBJEXT): $(top_srcdir)/internal/compilers.h weakmap.$(OBJEXT): $(top_srcdir)/internal/gc.h weakmap.$(OBJEXT): $(top_srcdir)/internal/hash.h weakmap.$(OBJEXT): $(top_srcdir)/internal/imemo.h weakmap.$(OBJEXT): $(top_srcdir)/internal/proc.h weakmap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h weakmap.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -21221,6 +21475,7 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h yjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h @@ -26,6 +26,7 @@ static void dln_loaderror(const char *format, ...); #include "dln.h" #include "internal.h" #include "internal/compilers.h" #ifdef HAVE_STDLIB_H # include <stdlib.h> @@ -383,9 +384,13 @@ dln_open(const char *file) # ifndef RTLD_GLOBAL # define RTLD_GLOBAL 0 # endif /* Load file */ - handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL); if (handle == NULL) { error = dln_strerror(); goto failed; @@ -497,8 +502,8 @@ abi_check_enabled_p(void) } #endif -void * -dln_load(const char *file) { #if defined(_WIN32) || defined(USE_DLN_DLOPEN) void *handle = dln_open(file); @@ -512,9 +517,6 @@ dln_load(const char *file) } #endif - char *init_fct_name; - init_funcname(&init_fct_name, file); - /* Call the init code */ dln_sym_callable(void, (void), handle, init_fct_name)(); @@ -524,6 +526,7 @@ dln_load(const char *file) { void (*init_fct)(void); init_fct = (void(*)(void))load((char*)file, 1, 0); if (init_fct == NULL) { aix_loaderror(file); @@ -540,3 +543,29 @@ dln_load(const char *file) return 0; /* dummy return */ } @@ -25,6 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); void *dln_load(const char*); void *dln_symbol(void*,const char*); RUBY_SYMBOL_EXPORT_END @@ -12,6 +12,15 @@ dln_load(const char *file) UNREACHABLE_RETURN(NULL); } NORETURN(void *dln_symbol(void*,const char*)); void* dln_symbol(void *handle, const char *symbol) @@ -1192,6 +1192,8 @@ rb_mod_append_features(VALUE module, VALUE include) return module; } /* * call-seq: * include(module, ...) -> self @@ -1345,9 +1347,9 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module) } superclass = refinement_superclass(superclass); c = iclass = rb_include_class_new(module, superclass); - RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass); - RCLASS_M_TBL(c) = RCLASS_M_TBL(module); rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass); } @@ -1402,6 +1404,12 @@ rb_using_module(const rb_cref_t *cref, VALUE module) rb_clear_all_refinement_method_cache(); } /* * call-seq: * target -> class_or_module @@ -1442,43 +1450,24 @@ add_activated_refinement(VALUE activated_refinements, } superclass = refinement_superclass(superclass); c = iclass = rb_include_class_new(refinement, superclass); - RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass); refinement = RCLASS_SUPER(refinement); while (refinement && refinement != klass) { - c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c))); - RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass); refinement = RCLASS_SUPER(refinement); } rb_hash_aset(activated_refinements, klass, iclass); } -/* - * call-seq: - * refine(mod) { block } -> module - * - * Refine <i>mod</i> in the receiver. - * - * Returns a module, where refined methods are defined. - */ - -static VALUE -rb_mod_refine(VALUE module, VALUE klass) { VALUE refinement; ID id_refinements, id_activated_refinements, id_refined_class, id_defined_at; VALUE refinements, activated_refinements; - rb_thread_t *th = GET_THREAD(); - VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp); - - if (block_handler == VM_BLOCK_HANDLER_NONE) { - rb_raise(rb_eArgError, "no block given"); - } - if (vm_block_handler_type(block_handler) != block_handler_type_iseq) { - rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine"); - } - ensure_class_or_module(klass); CONST_ID(id_refinements, "__refinements__"); refinements = rb_attr_get(module, id_refinements); if (NIL_P(refinements)) { @@ -1496,7 +1485,7 @@ rb_mod_refine(VALUE module, VALUE klass) if (NIL_P(refinement)) { VALUE superclass = refinement_superclass(klass); refinement = rb_refinement_new(); - RCLASS_SET_SUPER(refinement, superclass); RUBY_ASSERT(BUILTIN_TYPE(refinement) == T_MODULE); FL_SET(refinement, RMODULE_IS_REFINEMENT); CONST_ID(id_refined_class, "__refined_class__"); @@ -1506,8 +1495,41 @@ rb_mod_refine(VALUE module, VALUE klass) rb_hash_aset(refinements, klass, refinement); add_activated_refinement(activated_refinements, klass, refinement); } - rb_yield_refine_block(refinement, activated_refinements); - return refinement; } static void @@ -296,6 +296,7 @@ VALUE rb_vm_make_jump_tag_but_local_jump(enum ruby_tag_type state, VALUE val); rb_cref_t *rb_vm_cref(void); rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void); VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename); void rb_vm_set_progname(VALUE filename); VALUE rb_vm_cbase(void); @@ -0,0 +1 @@ @@ -0,0 +1,28 @@ @@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@ @@ -0,0 +1 @@ @@ -0,0 +1,28 @@ @@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@ @@ -186,6 +186,7 @@ coverage.o: $(top_srcdir)/internal/compilers.h coverage.o: $(top_srcdir)/internal/gc.h coverage.o: $(top_srcdir)/internal/hash.h coverage.o: $(top_srcdir)/internal/imemo.h coverage.o: $(top_srcdir)/internal/sanitizers.h coverage.o: $(top_srcdir)/internal/serial.h coverage.o: $(top_srcdir)/internal/set_table.h @@ -183,6 +183,7 @@ object_tracing.o: $(top_srcdir)/internal/basic_operators.h object_tracing.o: $(top_srcdir)/internal/compilers.h object_tracing.o: $(top_srcdir)/internal/gc.h object_tracing.o: $(top_srcdir)/internal/imemo.h object_tracing.o: $(top_srcdir)/internal/sanitizers.h object_tracing.o: $(top_srcdir)/internal/serial.h object_tracing.o: $(top_srcdir)/internal/set_table.h @@ -392,6 +393,7 @@ objspace.o: $(top_srcdir)/internal/compilers.h objspace.o: $(top_srcdir)/internal/gc.h objspace.o: $(top_srcdir)/internal/hash.h objspace.o: $(top_srcdir)/internal/imemo.h objspace.o: $(top_srcdir)/internal/sanitizers.h objspace.o: $(top_srcdir)/internal/serial.h objspace.o: $(top_srcdir)/internal/set_table.h @@ -605,6 +607,7 @@ objspace_dump.o: $(top_srcdir)/internal/gc.h objspace_dump.o: $(top_srcdir)/internal/hash.h objspace_dump.o: $(top_srcdir)/internal/imemo.h objspace_dump.o: $(top_srcdir)/internal/io.h objspace_dump.o: $(top_srcdir)/internal/sanitizers.h objspace_dump.o: $(top_srcdir)/internal/serial.h objspace_dump.o: $(top_srcdir)/internal/set_table.h @@ -792,7 +792,7 @@ objspace_internal_super_of(VALUE self, VALUE obj) case T_MODULE: case T_CLASS: case T_ICLASS: - super = RCLASS_SUPER(obj); break; default: rb_raise(rb_eArgError, "class or module is expected"); @@ -537,7 +537,7 @@ dump_object(VALUE obj, struct dump_config *dc) case T_CLASS: dump_append(dc, ", \"variation_count\":"); - dump_append_d(dc, RCLASS_EXT(obj)->variation_count); case T_MODULE: if (rb_class_get_superclass(obj)) { @@ -560,7 +560,7 @@ dump_object(VALUE obj, struct dump_config *dc) } } - if (RCLASS_SINGLETON_P(obj)) { dump_append(dc, ", \"singleton\":true"); } } @@ -591,6 +591,7 @@ ripper.o: $(top_srcdir)/internal/gc.h ripper.o: $(top_srcdir)/internal/hash.h ripper.o: $(top_srcdir)/internal/imemo.h ripper.o: $(top_srcdir)/internal/io.h ripper.o: $(top_srcdir)/internal/numeric.h ripper.o: $(top_srcdir)/internal/parse.h ripper.o: $(top_srcdir)/internal/rational.h @@ -200,6 +200,7 @@ ancdata.o: $(top_srcdir)/internal/error.h ancdata.o: $(top_srcdir)/internal/gc.h ancdata.o: $(top_srcdir)/internal/imemo.h ancdata.o: $(top_srcdir)/internal/io.h ancdata.o: $(top_srcdir)/internal/sanitizers.h ancdata.o: $(top_srcdir)/internal/serial.h ancdata.o: $(top_srcdir)/internal/set_table.h @@ -412,6 +413,7 @@ basicsocket.o: $(top_srcdir)/internal/error.h basicsocket.o: $(top_srcdir)/internal/gc.h basicsocket.o: $(top_srcdir)/internal/imemo.h basicsocket.o: $(top_srcdir)/internal/io.h basicsocket.o: $(top_srcdir)/internal/sanitizers.h basicsocket.o: $(top_srcdir)/internal/serial.h basicsocket.o: $(top_srcdir)/internal/set_table.h @@ -624,6 +626,7 @@ constants.o: $(top_srcdir)/internal/error.h constants.o: $(top_srcdir)/internal/gc.h constants.o: $(top_srcdir)/internal/imemo.h constants.o: $(top_srcdir)/internal/io.h constants.o: $(top_srcdir)/internal/sanitizers.h constants.o: $(top_srcdir)/internal/serial.h constants.o: $(top_srcdir)/internal/set_table.h @@ -837,6 +840,7 @@ ifaddr.o: $(top_srcdir)/internal/error.h ifaddr.o: $(top_srcdir)/internal/gc.h ifaddr.o: $(top_srcdir)/internal/imemo.h ifaddr.o: $(top_srcdir)/internal/io.h ifaddr.o: $(top_srcdir)/internal/sanitizers.h ifaddr.o: $(top_srcdir)/internal/serial.h ifaddr.o: $(top_srcdir)/internal/set_table.h @@ -1049,6 +1053,7 @@ init.o: $(top_srcdir)/internal/error.h init.o: $(top_srcdir)/internal/gc.h init.o: $(top_srcdir)/internal/imemo.h init.o: $(top_srcdir)/internal/io.h init.o: $(top_srcdir)/internal/sanitizers.h init.o: $(top_srcdir)/internal/serial.h init.o: $(top_srcdir)/internal/set_table.h @@ -1261,6 +1266,7 @@ ipsocket.o: $(top_srcdir)/internal/error.h ipsocket.o: $(top_srcdir)/internal/gc.h ipsocket.o: $(top_srcdir)/internal/imemo.h ipsocket.o: $(top_srcdir)/internal/io.h ipsocket.o: $(top_srcdir)/internal/sanitizers.h ipsocket.o: $(top_srcdir)/internal/serial.h ipsocket.o: $(top_srcdir)/internal/set_table.h @@ -1473,6 +1479,7 @@ option.o: $(top_srcdir)/internal/error.h option.o: $(top_srcdir)/internal/gc.h option.o: $(top_srcdir)/internal/imemo.h option.o: $(top_srcdir)/internal/io.h option.o: $(top_srcdir)/internal/sanitizers.h option.o: $(top_srcdir)/internal/serial.h option.o: $(top_srcdir)/internal/set_table.h @@ -1685,6 +1692,7 @@ raddrinfo.o: $(top_srcdir)/internal/error.h raddrinfo.o: $(top_srcdir)/internal/gc.h raddrinfo.o: $(top_srcdir)/internal/imemo.h raddrinfo.o: $(top_srcdir)/internal/io.h raddrinfo.o: $(top_srcdir)/internal/sanitizers.h raddrinfo.o: $(top_srcdir)/internal/serial.h raddrinfo.o: $(top_srcdir)/internal/set_table.h @@ -1897,6 +1905,7 @@ socket.o: $(top_srcdir)/internal/error.h socket.o: $(top_srcdir)/internal/gc.h socket.o: $(top_srcdir)/internal/imemo.h socket.o: $(top_srcdir)/internal/io.h socket.o: $(top_srcdir)/internal/sanitizers.h socket.o: $(top_srcdir)/internal/serial.h socket.o: $(top_srcdir)/internal/set_table.h @@ -2109,6 +2118,7 @@ sockssocket.o: $(top_srcdir)/internal/error.h sockssocket.o: $(top_srcdir)/internal/gc.h sockssocket.o: $(top_srcdir)/internal/imemo.h sockssocket.o: $(top_srcdir)/internal/io.h sockssocket.o: $(top_srcdir)/internal/sanitizers.h sockssocket.o: $(top_srcdir)/internal/serial.h sockssocket.o: $(top_srcdir)/internal/set_table.h @@ -2321,6 +2331,7 @@ tcpserver.o: $(top_srcdir)/internal/error.h tcpserver.o: $(top_srcdir)/internal/gc.h tcpserver.o: $(top_srcdir)/internal/imemo.h tcpserver.o: $(top_srcdir)/internal/io.h tcpserver.o: $(top_srcdir)/internal/sanitizers.h tcpserver.o: $(top_srcdir)/internal/serial.h tcpserver.o: $(top_srcdir)/internal/set_table.h @@ -2533,6 +2544,7 @@ tcpsocket.o: $(top_srcdir)/internal/error.h tcpsocket.o: $(top_srcdir)/internal/gc.h tcpsocket.o: $(top_srcdir)/internal/imemo.h tcpsocket.o: $(top_srcdir)/internal/io.h tcpsocket.o: $(top_srcdir)/internal/sanitizers.h tcpsocket.o: $(top_srcdir)/internal/serial.h tcpsocket.o: $(top_srcdir)/internal/set_table.h @@ -2745,6 +2757,7 @@ udpsocket.o: $(top_srcdir)/internal/error.h udpsocket.o: $(top_srcdir)/internal/gc.h udpsocket.o: $(top_srcdir)/internal/imemo.h udpsocket.o: $(top_srcdir)/internal/io.h udpsocket.o: $(top_srcdir)/internal/sanitizers.h udpsocket.o: $(top_srcdir)/internal/serial.h udpsocket.o: $(top_srcdir)/internal/set_table.h @@ -2957,6 +2970,7 @@ unixserver.o: $(top_srcdir)/internal/error.h unixserver.o: $(top_srcdir)/internal/gc.h unixserver.o: $(top_srcdir)/internal/imemo.h unixserver.o: $(top_srcdir)/internal/io.h unixserver.o: $(top_srcdir)/internal/sanitizers.h unixserver.o: $(top_srcdir)/internal/serial.h unixserver.o: $(top_srcdir)/internal/set_table.h @@ -3169,6 +3183,7 @@ unixsocket.o: $(top_srcdir)/internal/error.h unixsocket.o: $(top_srcdir)/internal/gc.h unixsocket.o: $(top_srcdir)/internal/imemo.h unixsocket.o: $(top_srcdir)/internal/io.h unixsocket.o: $(top_srcdir)/internal/sanitizers.h unixsocket.o: $(top_srcdir)/internal/serial.h unixsocket.o: $(top_srcdir)/internal/set_table.h @@ -1210,9 +1210,68 @@ rb_data_free(void *objspace, VALUE obj) return true; } bool rb_gc_obj_free(void *objspace, VALUE obj) { RB_DEBUG_COUNTER_INC(obj_free); switch (BUILTIN_TYPE(obj)) { @@ -1242,29 +1301,13 @@ rb_gc_obj_free(void *objspace, VALUE obj) break; case T_MODULE: case T_CLASS: - rb_id_table_free(RCLASS_M_TBL(obj)); - rb_cc_table_free(obj); - if (rb_shape_obj_too_complex_p(obj)) { - st_free_table((st_table *)RCLASS_FIELDS(obj)); - } - else { - xfree(RCLASS_FIELDS(obj)); - } - if (RCLASS_CONST_TBL(obj)) { - rb_free_const_table(RCLASS_CONST_TBL(obj)); - } - if (RCLASS_CVC_TBL(obj)) { - rb_id_table_foreach_values(RCLASS_CVC_TBL(obj), cvar_table_free_i, NULL); - rb_id_table_free(RCLASS_CVC_TBL(obj)); } - rb_class_remove_subclass_head(obj); - rb_class_remove_from_module_subclasses(obj); - rb_class_remove_from_super_subclasses(obj); - if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) { - xfree(RCLASS_SUPERCLASSES(obj)); - } - (void)RB_DEBUG_COUNTER_INC_IF(obj_module_ptr, BUILTIN_TYPE(obj) == T_MODULE); (void)RB_DEBUG_COUNTER_INC_IF(obj_class_ptr, BUILTIN_TYPE(obj) == T_CLASS); break; @@ -1363,18 +1406,12 @@ rb_gc_obj_free(void *objspace, VALUE obj) case T_MOVED: break; case T_ICLASS: - /* Basically , T_ICLASS shares table with the module */ - if (RICLASS_OWNS_M_TBL_P(obj)) { - /* Method table is not shared for origin iclasses of classes */ - rb_id_table_free(RCLASS_M_TBL(obj)); - } - if (RCLASS_CALLABLE_M_TBL(obj) != NULL) { - rb_id_table_free(RCLASS_CALLABLE_M_TBL(obj)); } - rb_class_remove_subclass_head(obj); - rb_cc_table_free(obj); - rb_class_remove_from_module_subclasses(obj); - rb_class_remove_from_super_subclasses(obj); RB_DEBUG_COUNTER_INC(obj_iclass_ptr); break; @@ -2124,6 +2161,60 @@ cc_table_memsize(struct rb_id_table *cc_table) return total; } size_t rb_obj_memsize_of(VALUE obj) { @@ -2148,23 +2239,16 @@ rb_obj_memsize_of(VALUE obj) break; case T_MODULE: case T_CLASS: - if (RCLASS_M_TBL(obj)) { - size += rb_id_table_memsize(RCLASS_M_TBL(obj)); - } - // class IV sizes are allocated as powers of two - size += SIZEOF_VALUE << bit_length(RCLASS_FIELDS_COUNT(obj)); - if (RCLASS_CVC_TBL(obj)) { - size += rb_id_table_memsize(RCLASS_CVC_TBL(obj)); - } - if (RCLASS_EXT(obj)->const_tbl) { - size += rb_id_table_memsize(RCLASS_EXT(obj)->const_tbl); - } - if (RCLASS_CC_TBL(obj)) { - size += cc_table_memsize(RCLASS_CC_TBL(obj)); - } - if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) { - size += (RCLASS_SUPERCLASS_DEPTH(obj) + 1) * sizeof(VALUE); } break; case T_ICLASS: if (RICLASS_OWNS_M_TBL_P(obj)) { @@ -2172,8 +2256,8 @@ rb_obj_memsize_of(VALUE obj) size += rb_id_table_memsize(RCLASS_M_TBL(obj)); } } - if (RCLASS_CC_TBL(obj)) { - size += cc_table_memsize(RCLASS_CC_TBL(obj)); } break; case T_STRING: @@ -2634,6 +2718,86 @@ mark_m_tbl(void *objspace, struct rb_id_table *tbl) } } #if STACK_GROW_DIRECTION < 0 #define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_END, (end) = STACK_START) #elif STACK_GROW_DIRECTION > 0 @@ -2796,45 +2960,12 @@ rb_mark_tbl_no_pin(st_table *tbl) gc_mark_tbl_no_pin(tbl); } -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(void *objspace, VALUE klass) -{ - struct rb_id_table *tbl = RCLASS_CVC_TBL(klass); - if (tbl) { - rb_id_table_foreach_values(tbl, mark_cvc_tbl_i, objspace); - } -} - static bool gc_declarative_marking_p(const rb_data_type_t *type) { return (type->flags & RUBY_TYPED_DECL_MARKING) != 0; } -static enum rb_id_table_iterator_result -mark_const_table_i(VALUE value, void *objspace) -{ - const rb_const_entry_t *ce = (const rb_const_entry_t *)value; - - gc_mark_internal(ce->value); - gc_mark_internal(ce->file); - - return ID_TABLE_CONTINUE; -} - void rb_gc_mark_roots(void *objspace, const char **categoryp) { @@ -2875,11 +3006,62 @@ rb_gc_mark_roots(void *objspace, const char **categoryp) #undef MARK_CHECKPOINT } #define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark void rb_gc_mark_children(void *objspace, VALUE obj) { if (FL_TEST_RAW(obj, FL_EXIVAR)) { rb_mark_generic_ivar(obj); } @@ -2920,42 +3102,21 @@ rb_gc_mark_children(void *objspace, VALUE obj) } // Continue to the shared T_CLASS/T_MODULE case T_MODULE: - if (RCLASS_SUPER(obj)) { - gc_mark_internal(RCLASS_SUPER(obj)); - } - mark_m_tbl(objspace, RCLASS_M_TBL(obj)); - mark_cvc_tbl(objspace, obj); - rb_cc_table_mark(obj); - if (rb_shape_obj_too_complex_p(obj)) { - gc_mark_tbl_no_pin((st_table *)RCLASS_FIELDS(obj)); - } - else { for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) { - gc_mark_internal(RCLASS_FIELDS(obj)[i]); } } - - if (RCLASS_CONST_TBL(obj)) { - rb_id_table_foreach_values(RCLASS_CONST_TBL(obj), mark_const_table_i, objspace); - } - - gc_mark_internal(RCLASS_EXT(obj)->classpath); break; case T_ICLASS: - if (RICLASS_OWNS_M_TBL_P(obj)) { - mark_m_tbl(objspace, RCLASS_M_TBL(obj)); - } - if (RCLASS_SUPER(obj)) { - gc_mark_internal(RCLASS_SUPER(obj)); - } - - if (RCLASS_INCLUDER(obj)) { - gc_mark_internal(RCLASS_INCLUDER(obj)); - } - mark_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj)); - rb_cc_table_mark(obj); break; case T_ARRAY: @@ -3031,8 +3192,8 @@ rb_gc_mark_children(void *objspace, VALUE obj) VALUE klass = RBASIC_CLASS(obj); // Increment max_iv_count if applicable, used to determine size pool allocation - if (RCLASS_EXT(klass)->max_iv_count < fields_count) { - RCLASS_EXT(klass)->max_iv_count = fields_count; } } @@ -3482,12 +3643,10 @@ update_cc_tbl_i(VALUE ccs_ptr, void *objspace) } static void -update_cc_tbl(void *objspace, VALUE klass) { - struct rb_id_table *tbl = RCLASS_CC_TBL(klass); - if (tbl) { - rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace); - } } static enum rb_id_table_iterator_result @@ -3507,16 +3666,14 @@ update_cvc_tbl_i(VALUE cvc_entry, void *objspace) } static void -update_cvc_tbl(void *objspace, VALUE klass) { - struct rb_id_table *tbl = RCLASS_CVC_TBL(klass); - if (tbl) { - rb_id_table_foreach_values(tbl, update_cvc_tbl_i, objspace); - } } static enum rb_id_table_iterator_result -update_const_table(VALUE value, void *objspace) { rb_const_entry_t *ce = (rb_const_entry_t *)value; @@ -3535,35 +3692,93 @@ static void update_const_tbl(void *objspace, struct rb_id_table *tbl) { if (!tbl) return; - rb_id_table_foreach_values(tbl, update_const_table, objspace); } static void -update_subclass_entries(void *objspace, rb_subclass_entry_t *entry) { while (entry) { - UPDATE_IF_MOVED(objspace, entry->klass); entry = entry->next; } } static void -update_class_ext(void *objspace, rb_classext_t *ext) { - UPDATE_IF_MOVED(objspace, ext->origin_); - UPDATE_IF_MOVED(objspace, ext->includer); - UPDATE_IF_MOVED(objspace, ext->refined_class); - update_subclass_entries(objspace, ext->subclasses); } static void -update_superclasses(void *objspace, VALUE obj) { - if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) { - for (size_t i = 0; i < RCLASS_SUPERCLASS_DEPTH(obj) + 1; i++) { - UPDATE_IF_MOVED(objspace, RCLASS_SUPERCLASSES(obj)[i]); } } } extern rb_symbols_t ruby_global_symbols; @@ -3884,6 +4099,8 @@ rb_gc_update_vm_references(void *objspace) void rb_gc_update_object_references(void *objspace, VALUE obj) { switch (BUILTIN_TYPE(obj)) { case T_CLASS: if (FL_TEST_RAW(obj, FL_SINGLETON)) { @@ -3891,39 +4108,15 @@ rb_gc_update_object_references(void *objspace, VALUE obj) } // Continue to the shared T_CLASS/T_MODULE case T_MODULE: - if (RCLASS_SUPER((VALUE)obj)) { - UPDATE_IF_MOVED(objspace, RCLASS(obj)->super); - } - update_m_tbl(objspace, RCLASS_M_TBL(obj)); - update_cc_tbl(objspace, obj); - update_cvc_tbl(objspace, obj); - update_superclasses(objspace, obj); - - if (rb_shape_obj_too_complex_p(obj)) { - gc_ref_update_table_values_only(RCLASS_FIELDS_HASH(obj)); - } - else { - for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) { - UPDATE_IF_MOVED(objspace, RCLASS_FIELDS(obj)[i]); - } - } - - update_class_ext(objspace, RCLASS_EXT(obj)); - update_const_tbl(objspace, RCLASS_CONST_TBL(obj)); - - UPDATE_IF_MOVED(objspace, RCLASS_EXT(obj)->classpath); break; case T_ICLASS: - if (RICLASS_OWNS_M_TBL_P(obj)) { - update_m_tbl(objspace, RCLASS_M_TBL(obj)); - } - if (RCLASS_SUPER((VALUE)obj)) { - UPDATE_IF_MOVED(objspace, RCLASS(obj)->super); - } - update_class_ext(objspace, RCLASS_EXT(obj)); - update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj)); - update_cc_tbl(objspace, obj); break; case T_IMEMO: @@ -170,13 +170,14 @@ rb_imemo_memsize(VALUE obj) static enum rb_id_table_iterator_result cc_table_mark_i(VALUE ccs_ptr, void *data) { struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr; VM_ASSERT(vm_ccs_p(ccs)); #if VM_CHECK_MODE > 0 VALUE klass = (VALUE)data; VALUE lookup_val; - VM_ASSERT(rb_id_table_lookup(RCLASS_CC_TBL(klass), ccs->cme->called_id, &lookup_val)); VM_ASSERT(lookup_val == ccs_ptr); #endif @@ -200,7 +201,8 @@ cc_table_mark_i(VALUE ccs_ptr, void *data) void rb_cc_table_mark(VALUE klass) { - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); if (cc_tbl) { rb_id_table_foreach_values(cc_tbl, cc_table_mark_i, (void *)klass); } @@ -492,7 +494,10 @@ cc_table_free_i(VALUE ccs_ptr, void *data) void rb_cc_table_free(VALUE klass) { - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); if (cc_tbl) { rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass); @@ -501,6 +506,14 @@ rb_cc_table_free(VALUE klass) } void rb_imemo_free(VALUE obj) { switch (imemo_type(obj)) { @@ -84,6 +84,8 @@ RUBY_EXTERN VALUE rb_cMethod; /**< `Method` class. */ RUBY_EXTERN VALUE rb_cModule; /**< `Module` class. */ RUBY_EXTERN VALUE rb_cRefinement; /**< `Refinement` class. */ RUBY_EXTERN VALUE rb_cNameErrorMesg; /**< `NameError::Message` class. */ RUBY_EXTERN VALUE rb_cNilClass; /**< `NilClass` class. */ RUBY_EXTERN VALUE rb_cNumeric; /**< `Numeric` class. */ RUBY_EXTERN VALUE rb_cProc; /**< `Proc` class. */ @@ -77,6 +77,7 @@ rb_call_inits(void) CALL(Prism); CALL(unicode_version); CALL(Set); // enable builtin loading CALL(builtin); @@ -10,6 +10,7 @@ */ #include "id.h" #include "id_table.h" /* for struct rb_id_table */ #include "internal/serial.h" /* for rb_serial_t */ #include "internal/static_assert.h" #include "internal/variable.h" /* for rb_class_ivar_set */ @@ -26,6 +27,41 @@ # undef RCLASS_SUPER #endif struct rb_subclass_entry { VALUE klass; struct rb_subclass_entry *next; @@ -41,21 +77,36 @@ struct rb_cvar_class_tbl_entry { }; struct rb_classext_struct { VALUE *fields; // Fields are either ivar or other internal properties stored inline struct rb_id_table *const_tbl; struct rb_id_table *callable_m_tbl; struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */ struct rb_id_table *cvc_tbl; size_t superclass_depth; VALUE *superclasses; - struct rb_subclass_entry *subclasses; - struct rb_subclass_entry *subclass_entry; /** - * In the case that this is an `ICLASS`, `module_subclasses` points to the link * in the module's `subclasses` list that indicates that the klass has been * included. Hopefully that makes sense. */ - struct rb_subclass_entry *module_subclass_entry; const VALUE origin_; const VALUE refined_class; union { @@ -71,6 +122,11 @@ struct rb_classext_struct { unsigned char variation_count; bool permanent_classpath : 1; bool cloned : 1; VALUE classpath; }; typedef struct rb_classext_struct rb_classext_t; @@ -79,92 +135,333 @@ STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_cl struct RClass { struct RBasic basic; - VALUE super; - struct rb_id_table *m_tbl; }; -// Assert that classes can be embedded in heaps[2] (which has 160B slot size) -STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE); struct RClass_and_rb_classext_t { struct RClass rclass; rb_classext_t classext; }; #define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext) -#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl) -#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl) -#define RCLASS_FIELDS(c) (RCLASS_EXT(c)->fields) -#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl) -#define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl) -#define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl) -#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_) #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class) -#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer) -#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry) -#define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry) -#define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses) -#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth) -#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses) #define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT(c)->as.singleton_class.attached_object) #define RCLASS_IS_ROOT FL_USER0 -#define RICLASS_IS_ORIGIN FL_USER0 -#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2 -#define RICLASS_ORIGIN_SHARED_MTBL FL_USER3 -static inline st_table * -RCLASS_FIELDS_HASH(VALUE obj) { - RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE)); - RUBY_ASSERT(rb_shape_obj_too_complex_p(obj)); - return (st_table *)RCLASS_FIELDS(obj); } static inline void -RCLASS_SET_FIELDS_HASH(VALUE obj, const st_table *tbl) { - RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE)); - RUBY_ASSERT(rb_shape_obj_too_complex_p(obj)); - RCLASS_FIELDS(obj) = (VALUE *)tbl; } -static inline uint32_t -RCLASS_FIELDS_COUNT(VALUE obj) { - RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE)); - if (rb_shape_obj_too_complex_p(obj)) { - uint32_t count; - // "Too complex" classes could have their IV hash mutated in - // parallel, so lets lock around getting the hash size. - RB_VM_LOCK_ENTER(); - { - count = (uint32_t)rb_st_table_size(RCLASS_FIELDS_HASH(obj)); } - RB_VM_LOCK_LEAVE(); - return count; } - else { - return RSHAPE(RCLASS_SHAPE_ID(obj))->next_field_index; } } static inline void -RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table) { - RUBY_ASSERT(!RB_OBJ_PROMOTED(klass)); - RCLASS_M_TBL(klass) = table; } /* class.c */ void rb_class_subclass_add(VALUE super, VALUE klass); void rb_class_remove_from_super_subclasses(VALUE); void rb_class_update_superclasses(VALUE); size_t rb_class_superclasses_memsize(VALUE); void rb_class_remove_subclass_head(VALUE); int rb_singleton_class_internal_p(VALUE sklass); VALUE rb_class_boot(VALUE); VALUE rb_class_s_alloc(VALUE klass); VALUE rb_module_s_alloc(VALUE klass); @@ -172,10 +469,6 @@ void rb_module_set_initialized(VALUE module); void rb_module_check_initializable(VALUE module); VALUE rb_make_metaclass(VALUE, VALUE); VALUE rb_include_class_new(VALUE, VALUE); -void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE); -void rb_class_detach_subclasses(VALUE); -void rb_class_detach_module_subclasses(VALUE); -void rb_class_remove_from_module_subclasses(VALUE); VALUE rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super); VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj); VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj); @@ -186,22 +479,152 @@ VALUE rb_special_singleton_class(VALUE); VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach); VALUE rb_singleton_class_get(VALUE obj); void rb_undef_methods_from(VALUE klass, VALUE super); - -static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin); -static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass); -static inline VALUE RCLASS_SUPER(VALUE klass); -static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super); -static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass); - VALUE rb_class_inherited(VALUE, VALUE); VALUE rb_keyword_error_new(const char *, VALUE); static inline bool RCLASS_SINGLETON_P(VALUE klass) { return RB_TYPE_P(klass, T_CLASS) && FL_TEST_RAW(klass, FL_SINGLETON); } static inline rb_alloc_func_t RCLASS_ALLOCATOR(VALUE klass) { @@ -215,26 +638,42 @@ static inline void RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator) { assert(!RCLASS_SINGLETON_P(klass)); - RCLASS_EXT(klass)->as.class.allocator = allocator; } static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin) { - RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin); - if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN); } static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass) { - FL_SET(iclass, RICLASS_ORIGIN_SHARED_MTBL); } static inline bool RICLASS_OWNS_M_TBL_P(VALUE iclass) { - return FL_TEST_RAW(iclass, RICLASS_IS_ORIGIN | RICLASS_ORIGIN_SHARED_MTBL) == RICLASS_IS_ORIGIN; } static inline void @@ -243,32 +682,61 @@ RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass) RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass); } -static inline VALUE -RCLASS_SUPER(VALUE klass) { - return RCLASS(klass)->super; } -static inline VALUE -RCLASS_SET_SUPER(VALUE klass, VALUE super) { - if (super) { - rb_class_remove_from_super_subclasses(klass); - rb_class_subclass_add(super, klass); - } - RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super); - rb_class_update_superclasses(klass); - return super; } static inline void RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent) { assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE); assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING); - RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath); - RCLASS_EXT(klass)->permanent_classpath = permanent; } static inline VALUE @@ -280,4 +748,22 @@ RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object) return attached_object; } #endif /* INTERNAL_CLASS_H */ @@ -16,11 +16,18 @@ #define id_status ruby_static_id_status /* eval.c */ extern ID ruby_static_id_signo; extern ID ruby_static_id_status; VALUE rb_refinement_module_get_refined_class(VALUE module); void rb_class_modify_check(VALUE); NORETURN(VALUE rb_f_raise(int argc, VALUE *argv)); VALUE rb_top_main_class(const char *method); /* eval_error.c */ @@ -10,6 +10,7 @@ */ #include "ruby/internal/config.h" #include <stddef.h> /* for size_t */ #include "internal/array.h" /* for rb_ary_hidden_new_fill */ #include "ruby/internal/stdbool.h" /* for bool */ #include "ruby/ruby.h" /* for rb_block_call_func_t */ @@ -24,6 +25,7 @@ #define IMEMO_FL_USER3 FL_USER7 #define IMEMO_FL_USER4 FL_USER8 #define IMEMO_FL_USER5 FL_USER9 enum imemo_type { imemo_env = 0, @@ -149,6 +151,7 @@ size_t rb_imemo_memsize(VALUE obj); void rb_cc_table_mark(VALUE klass); void rb_imemo_mark_and_move(VALUE obj, bool reference_updating); void rb_cc_table_free(VALUE klass); void rb_imemo_free(VALUE obj); RUBY_SYMBOL_EXPORT_BEGIN @@ -12,6 +12,8 @@ /* load.c */ VALUE rb_get_expanded_load_path(void); int rb_require_internal(VALUE fname); NORETURN(void rb_load_fail(VALUE, const char*)); @@ -0,0 +1,80 @@ @@ -23,11 +23,13 @@ VALUE rb_search_class_path(VALUE); VALUE rb_attr_delete(VALUE, ID); void rb_autoload_str(VALUE mod, ID id, VALUE file); VALUE rb_autoload_at_p(VALUE, ID, int); NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE)); rb_gvar_getter_t *rb_gvar_getter_function_of(ID); rb_gvar_setter_t *rb_gvar_setter_function_of(ID); void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_); void rb_gvar_ractor_local(const char *name); /** * Sets the name of a module. @@ -77,6 +77,7 @@ void rb_check_stack_overflow(void); #define RB_BLOCK_NO_USE_PACKED_ARGS 2 VALUE rb_block_call2(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2, long flags); struct vm_ifunc *rb_current_ifunc(void); #if USE_YJIT /* vm_exec.c */ @@ -2919,7 +2919,7 @@ rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq) attr_index_t count = (attr_index_t)rb_id_table_size(iv_names); VALUE superclass = rb_class_superclass(klass); - count += RCLASS_EXT(superclass)->max_iv_count; rb_id_table_free(iv_names); @@ -219,6 +219,7 @@ class Gem::Package # Adds a checksum for each entry in the gem to checksums.yaml.gz. def add_checksums(tar) Gem.load_yaml checksums_by_algorithm = Hash.new {|h, algorithm| h[algorithm] = {} } @@ -552,6 +553,7 @@ EOM # Reads and loads checksums.yaml.gz from the tar file +gem+ def read_checksums(gem) Gem.load_yaml @checksums = gem.seek "checksums.yaml.gz" do |entry| @@ -1,5 +1,7 @@ # frozen_string_literal: true module Gem ### # This module is used for safely loading YAML specs from a gem. The @@ -7,9 +7,11 @@ #include "internal.h" #include "internal/dir.h" #include "internal/error.h" #include "internal/file.h" #include "internal/hash.h" #include "internal/load.h" #include "internal/ruby_parser.h" #include "internal/thread.h" #include "internal/variable.h" @@ -19,6 +21,7 @@ #include "ruby/encoding.h" #include "ruby/util.h" #include "ractor_core.h" static VALUE ruby_dln_libmap; @@ -36,6 +39,38 @@ static VALUE ruby_dln_libmap; # error Need integer for VALUE #endif enum { loadable_ext_rb = (0+ /* .rb extension is the first in both tables */ 1) /* offset by rb_find_file_ext() */ @@ -64,10 +99,11 @@ enum expand_type { string objects in $LOAD_PATH are frozen. */ static void -rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_relative, int *has_non_cache) { - VALUE load_path = vm->load_path; - VALUE expanded_load_path = vm->expanded_load_path; VALUE ary; long i; @@ -106,108 +142,117 @@ rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_rel rb_ary_push(ary, rb_fstring(expanded_path)); } rb_ary_freeze(ary); - vm->expanded_load_path = ary; - rb_ary_replace(vm->load_path_snapshot, vm->load_path); } static VALUE -get_expanded_load_path(rb_vm_t *vm) { const VALUE non_cache = Qtrue; - if (!rb_ary_shared_with_p(vm->load_path_snapshot, vm->load_path)) { /* The load path was modified. Rebuild the expanded load path. */ int has_relative = 0, has_non_cache = 0; - rb_construct_expanded_load_path(vm, EXPAND_ALL, &has_relative, &has_non_cache); if (has_relative) { - vm->load_path_check_cache = rb_dir_getwd_ospath(); } else if (has_non_cache) { /* Non string object. */ - vm->load_path_check_cache = non_cache; } else { - vm->load_path_check_cache = 0; } } - else if (vm->load_path_check_cache == non_cache) { int has_relative = 1, has_non_cache = 1; /* Expand only non-cacheable objects. */ - rb_construct_expanded_load_path(vm, EXPAND_NON_CACHE, &has_relative, &has_non_cache); } - else if (vm->load_path_check_cache) { int has_relative = 1, has_non_cache = 1; VALUE cwd = rb_dir_getwd_ospath(); - if (!rb_str_equal(vm->load_path_check_cache, cwd)) { /* Current working directory or filesystem encoding was changed. Expand relative load path and non-cacheable objects again. */ - vm->load_path_check_cache = cwd; - rb_construct_expanded_load_path(vm, EXPAND_RELATIVE, &has_relative, &has_non_cache); } else { /* Expand only tilde (User HOME) and non-cacheable objects. */ - rb_construct_expanded_load_path(vm, EXPAND_HOME, &has_relative, &has_non_cache); } } - return vm->expanded_load_path; } VALUE rb_get_expanded_load_path(void) { - return get_expanded_load_path(GET_VM()); } static VALUE load_path_getter(ID id, VALUE * p) { - rb_vm_t *vm = (void *)p; - return vm->load_path; } static VALUE -get_loaded_features(rb_vm_t *vm) { - return vm->loaded_features; } static VALUE -get_loaded_features_realpaths(rb_vm_t *vm) { - return vm->loaded_features_realpaths; } static VALUE -get_loaded_features_realpath_map(rb_vm_t *vm) { - return vm->loaded_features_realpath_map; } static VALUE get_LOADED_FEATURES(ID _x, VALUE *_y) { - return get_loaded_features(GET_VM()); } static void -reset_loaded_features_snapshot(rb_vm_t *vm) { - rb_ary_replace(vm->loaded_features_snapshot, vm->loaded_features); } static struct st_table * -get_loaded_features_index_raw(rb_vm_t *vm) { - return vm->loaded_features_index; } static st_table * -get_loading_table(rb_vm_t *vm) { - return vm->loading_table; } static st_data_t @@ -228,7 +273,7 @@ is_rbext_path(VALUE feature_path) typedef rb_darray(long) feature_indexes_t; struct features_index_add_single_args { - rb_vm_t *vm; VALUE offset; bool rb; }; @@ -237,7 +282,7 @@ static int features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t raw_args, int existing) { struct features_index_add_single_args *args = (struct features_index_add_single_args *)raw_args; - rb_vm_t *vm = args->vm; VALUE offset = args->offset; bool rb = args->rb; @@ -245,7 +290,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r VALUE this_feature_index = *value; if (FIXNUM_P(this_feature_index)) { - VALUE loaded_features = get_loaded_features(vm); VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(this_feature_index)); feature_indexes_t feature_indexes; @@ -265,7 +310,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r long pos = -1; if (rb) { - VALUE loaded_features = get_loaded_features(vm); for (size_t i = 0; i < rb_darray_size(feature_indexes); ++i) { long idx = rb_darray_get(feature_indexes, i); VALUE this_feature_path = RARRAY_AREF(loaded_features, idx); @@ -297,7 +342,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r } static void -features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset, bool rb) { struct st_table *features_index; st_data_t short_feature_key; @@ -305,10 +350,10 @@ features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset Check_Type(offset, T_FIXNUM); short_feature_key = feature_key(str, len); - features_index = get_loaded_features_index_raw(vm); struct features_index_add_single_args args = { - .vm = vm, .offset = offset, .rb = rb, }; @@ -325,7 +370,7 @@ features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset relies on for its fast lookup. */ static void -features_index_add(rb_vm_t *vm, VALUE feature, VALUE offset) { const char *feature_str, *feature_end, *ext, *p; bool rb = false; @@ -351,14 +396,14 @@ features_index_add(rb_vm_t *vm, VALUE feature, VALUE offset) if (p < feature_str) break; /* Now *p == '/'. We reach this point for every '/' in `feature`. */ - features_index_add_single(vm, p + 1, feature_end - p - 1, offset, false); if (ext) { - features_index_add_single(vm, p + 1, ext - p - 1, offset, rb); } } - features_index_add_single(vm, feature_str, feature_end - feature_str, offset, false); if (ext) { - features_index_add_single(vm, feature_str, ext - feature_str, offset, rb); } } @@ -375,27 +420,31 @@ loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg) void rb_free_loaded_features_index(rb_vm_t *vm) { st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0); st_free_table(vm->loaded_features_index); } static st_table * -get_loaded_features_index(rb_vm_t *vm) { - VALUE features; int i; - if (!rb_ary_shared_with_p(vm->loaded_features_snapshot, vm->loaded_features)) { /* The sharing was broken; something (other than us in rb_provide_feature()) modified loaded_features. Rebuild the index. */ - st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0); - VALUE realpaths = vm->loaded_features_realpaths; - VALUE realpath_map = vm->loaded_features_realpath_map; VALUE previous_realpath_map = rb_hash_dup(realpath_map); rb_hash_clear(realpaths); rb_hash_clear(realpath_map); - features = vm->loaded_features; for (i = 0; i < RARRAY_LEN(features); i++) { VALUE entry, as_str; as_str = entry = rb_ary_entry(features, i); @@ -403,11 +452,11 @@ get_loaded_features_index(rb_vm_t *vm) as_str = rb_fstring(as_str); if (as_str != entry) rb_ary_store(features, i, as_str); - features_index_add(vm, as_str, INT2FIX(i)); } - reset_loaded_features_snapshot(vm); - features = rb_ary_dup(vm->loaded_features_snapshot); long j = RARRAY_LEN(features); for (i = 0; i < j; i++) { VALUE as_str = rb_ary_entry(features, i); @@ -421,7 +470,7 @@ get_loaded_features_index(rb_vm_t *vm) rb_hash_aset(realpath_map, as_str, realpath); } } - return vm->loaded_features_index; } /* This searches `load_path` for a value such that @@ -506,7 +555,7 @@ loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f) * 'u': unsuffixed */ static int -rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn) { VALUE features, this_feature_index = Qnil, v, p, load_path = 0; const char *f, *e; @@ -527,8 +576,8 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa elen = 0; type = 0; } - features = get_loaded_features(vm); - features_index = get_loaded_features_index(vm); key = feature_key(feature, strlen(feature)); /* We search `features` for an entry such that either @@ -575,7 +624,7 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa if ((n = RSTRING_LEN(v)) < len) continue; if (strncmp(f, feature, len) != 0) { if (expanded) continue; - if (!load_path) load_path = get_expanded_load_path(vm); if (!(p = loaded_feature_path(f, n, feature, len, type, load_path))) continue; expanded = 1; @@ -595,14 +644,14 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa } } - loading_tbl = get_loading_table(vm); f = 0; if (!expanded && !rb_is_absolute_path(feature)) { struct loaded_feature_searching fs; fs.name = feature; fs.len = len; fs.type = type; - fs.load_path = load_path ? load_path : get_expanded_load_path(vm); fs.result = 0; st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs); if ((f = fs.result) != 0) { @@ -657,7 +706,7 @@ rb_provided(const char *feature) } static int -feature_provided(rb_vm_t *vm, const char *feature, const char **loading) { const char *ext = strrchr(feature, '.'); VALUE fullpath = 0; @@ -669,15 +718,15 @@ feature_provided(rb_vm_t *vm, const char *feature, const char **loading) } if (ext && !strchr(ext, '/')) { if (IS_RBEXT(ext)) { - if (rb_feature_p(vm, feature, ext, TRUE, FALSE, loading)) return TRUE; return FALSE; } else if (IS_SOEXT(ext) || IS_DLEXT(ext)) { - if (rb_feature_p(vm, feature, ext, FALSE, FALSE, loading)) return TRUE; return FALSE; } } - if (rb_feature_p(vm, feature, 0, TRUE, FALSE, loading)) return TRUE; RB_GC_GUARD(fullpath); return FALSE; @@ -686,35 +735,41 @@ feature_provided(rb_vm_t *vm, const char *feature, const char **loading) int rb_feature_provided(const char *feature, const char **loading) { - return feature_provided(GET_VM(), feature, loading); } static void -rb_provide_feature(rb_vm_t *vm, VALUE feature) { VALUE features; - features = get_loaded_features(vm); if (OBJ_FROZEN(features)) { rb_raise(rb_eRuntimeError, "$LOADED_FEATURES is frozen; cannot append feature"); } feature = rb_fstring(feature); - get_loaded_features_index(vm); // If loaded_features and loaded_features_snapshot share the same backing // array, pushing into it would cause the whole array to be copied. // To avoid this we first clear loaded_features_snapshot. - rb_ary_clear(vm->loaded_features_snapshot); rb_ary_push(features, feature); - features_index_add(vm, feature, INT2FIX(RARRAY_LEN(features)-1)); - reset_loaded_features_snapshot(vm); } void rb_provide(const char *feature) { - rb_provide_feature(GET_VM(), rb_fstring_cstr(feature)); } NORETURN(static void load_failed(VALUE)); @@ -732,17 +787,34 @@ realpath_internal_cached(VALUE hash, VALUE path) return realpath; } static inline void load_iseq_eval(rb_execution_context_t *ec, VALUE fname) { const rb_iseq_t *iseq = rb_iseq_load_iseq(fname); if (!iseq) { rb_execution_context_t *ec = GET_EC(); VALUE v = rb_vm_push_frame_fname(ec, fname); - rb_thread_t *th = rb_ec_thread_ptr(ec); - VALUE realpath_map = get_loaded_features_realpath_map(th->vm); if (rb_ruby_prism_p()) { pm_parse_result_t result = { 0 }; @@ -786,13 +858,23 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname) RB_GC_GUARD(v); } rb_exec_event_hook_script_compiled(ec, iseq, Qnil); - rb_iseq_eval(iseq); } static inline enum ruby_tag_type load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper) { enum ruby_tag_type state; rb_thread_t *th = rb_ec_thread_ptr(ec); volatile VALUE wrapper = th->top_wrapper; volatile VALUE self = th->top_self; @@ -803,7 +885,15 @@ load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper) ec->errinfo = Qnil; /* ensure */ /* load in module as toplevel */ - th->top_self = rb_obj_clone(rb_vm_top_self()); th->top_wrapper = load_wrapper; rb_extend_object(th->top_self, th->top_wrapper); @@ -838,7 +928,9 @@ raise_load_if_failed(rb_execution_context_t *ec, enum ruby_tag_type state) static void rb_load_internal(VALUE fname, VALUE wrap) { rb_execution_context_t *ec = GET_EC(); enum ruby_tag_type state = TAG_NONE; if (RTEST(wrap)) { if (!RB_TYPE_P(wrap, T_MODULE)) { @@ -846,6 +938,10 @@ rb_load_internal(VALUE fname, VALUE wrap) } state = load_wrapping(ec, fname, wrap); } else { load_iseq_eval(ec, fname); } @@ -874,6 +970,40 @@ rb_load_protect(VALUE fname, int wrap, int *pstate) if (state != TAG_NONE) *pstate = state; } /* * call-seq: * load(filename, wrap=false) -> true @@ -907,32 +1037,16 @@ rb_load_protect(VALUE fname, int wrap, int *pstate) static VALUE rb_f_load(int argc, VALUE *argv, VALUE _) { - VALUE fname, wrap, path, orig_fname; - rb_scan_args(argc, argv, "11", &fname, &wrap); - - orig_fname = rb_get_path_check_to_string(fname); - fname = rb_str_encode_ospath(orig_fname); - RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname)); - - path = rb_find_file(fname); - if (!path) { - if (!rb_file_load_ok(RSTRING_PTR(fname))) - load_failed(orig_fname); - path = fname; - } - rb_load_internal(path, wrap); - - RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname)); - - return Qtrue; } static char * -load_lock(rb_vm_t *vm, const char *ftptr, bool warn) { st_data_t data; - st_table *loading_tbl = get_loading_table(vm); if (!st_lookup(loading_tbl, (st_data_t)ftptr, &data)) { /* partial state */ @@ -974,11 +1088,11 @@ release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int exis } static void -load_unlock(rb_vm_t *vm, const char *ftptr, int done) { if (ftptr) { st_data_t key = (st_data_t)ftptr; - st_table *loading_tbl = get_loading_table(vm); st_update(loading_tbl, key, release_thread_shield, done); } @@ -1026,9 +1140,22 @@ static VALUE rb_require_string_internal(VALUE fname, bool resurrect); VALUE rb_f_require(VALUE obj, VALUE fname) { return rb_require_string(fname); } /* * call-seq: * require_relative(string) -> true or false @@ -1041,18 +1168,13 @@ rb_f_require(VALUE obj, VALUE fname) VALUE rb_f_require_relative(VALUE obj, VALUE fname) { - VALUE base = rb_current_realfilepath(); - if (NIL_P(base)) { - rb_loaderror("cannot infer basepath"); - } - base = rb_file_dirname(base); - return rb_require_string_internal(rb_file_absolute_path(fname, base), false); } -typedef int (*feature_func)(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn); static int -search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_feature_p) { VALUE tmp; char *ext, *ftptr; @@ -1063,20 +1185,20 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_ ext = strrchr(ftptr = RSTRING_PTR(fname), '.'); if (ext && !strchr(ext, '/')) { if (IS_RBEXT(ext)) { - if (rb_feature_p(vm, ftptr, ext, TRUE, FALSE, &loading)) { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 'r'; } if ((tmp = rb_find_file(fname)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(vm, ftptr, ext, TRUE, TRUE, &loading) || loading) *path = tmp; return 'r'; } return 0; } else if (IS_SOEXT(ext)) { - if (rb_feature_p(vm, ftptr, ext, FALSE, FALSE, &loading)) { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 's'; } @@ -1085,25 +1207,25 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_ OBJ_FREEZE(tmp); if ((tmp = rb_find_file(tmp)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(vm, ftptr, ext, FALSE, TRUE, &loading) || loading) *path = tmp; return 's'; } } else if (IS_DLEXT(ext)) { - if (rb_feature_p(vm, ftptr, ext, FALSE, FALSE, &loading)) { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 's'; } if ((tmp = rb_find_file(fname)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (!rb_feature_p(vm, ftptr, ext, FALSE, TRUE, &loading) || loading) *path = tmp; return 's'; } } } - else if ((ft = rb_feature_p(vm, ftptr, 0, FALSE, FALSE, &loading)) == 'r') { if (loading) *path = rb_filesystem_str_new_cstr(loading); return 'r'; } @@ -1112,7 +1234,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_ // Check if it's a statically linked extension when // not already a feature and not found as a dynamic library. - if (!ft && type != loadable_ext_rb && vm->static_ext_inits) { VALUE lookup_name = tmp; // Append ".so" if not already present so for example "etc" can find "etc.so". // We always register statically linked extensions with a ".so" extension. @@ -1122,7 +1244,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_ rb_str_cat_cstr(lookup_name, ".so"); } ftptr = RSTRING_PTR(lookup_name); - if (st_lookup(vm->static_ext_inits, (st_data_t)ftptr, NULL)) { *path = rb_filesystem_str_new_cstr(ftptr); RB_GC_GUARD(lookup_name); return 's'; @@ -1134,7 +1256,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_ if (ft) goto feature_present; ftptr = RSTRING_PTR(tmp); - return rb_feature_p(vm, ftptr, 0, FALSE, TRUE, 0); default: if (ft) { @@ -1143,7 +1265,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_ /* fall through */ case loadable_ext_rb: ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); - if (rb_feature_p(vm, ftptr, ext, type == loadable_ext_rb, TRUE, &loading) && !loading) break; *path = tmp; } @@ -1161,10 +1283,15 @@ load_failed(VALUE fname) } static VALUE -load_ext(VALUE path) { rb_scope_visibility_set(METHOD_VISI_PUBLIC); - return (VALUE)dln_load(RSTRING_PTR(path)); } static bool @@ -1181,7 +1308,7 @@ run_static_ext_init(rb_vm_t *vm, const char *feature) } static int -no_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn) { return 0; } @@ -1193,10 +1320,11 @@ rb_resolve_feature_path(VALUE klass, VALUE fname) VALUE path; int found; VALUE sym; fname = rb_get_path(fname); path = rb_str_encode_ospath(fname); - found = search_required(GET_VM(), path, &path, no_feature_p); switch (found) { case 'r': @@ -1231,6 +1359,20 @@ rb_ext_ractor_safe(bool flag) GET_THREAD()->ext_config.ractor_safe = flag; } /* * returns * 0: if already loaded (false) @@ -1250,13 +1392,14 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa th->top_wrapper, th->top_self, ec->errinfo, ec, }; enum ruby_tag_type state; char *volatile ftptr = 0; VALUE path; volatile VALUE saved_path; volatile VALUE realpath = 0; - VALUE realpaths = get_loaded_features_realpaths(th->vm); - VALUE realpath_map = get_loaded_features_realpath_map(th->vm); volatile bool reset_ext_config = false; struct rb_ext_config prev_ext_config; @@ -1272,12 +1415,12 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa int found; RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname)); - found = search_required(th->vm, path, &saved_path, rb_feature_p); RUBY_DTRACE_HOOK(FIND_REQUIRE_RETURN, RSTRING_PTR(fname)); path = saved_path; if (found) { - if (!path || !(ftptr = load_lock(th->vm, RSTRING_PTR(path), warn))) { result = 0; } else if (!*ftptr) { @@ -1293,15 +1436,30 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa else { switch (found) { case 'r': - load_iseq_eval(saved.ec, path); break; case 's': reset_ext_config = true; ext_config_push(th, &prev_ext_config); - handle = rb_vm_call_cfunc(rb_vm_top_self(), load_ext, - path, VM_BLOCK_HANDLER_NONE, path); - rb_hash_aset(ruby_dln_libmap, path, SVALUE2NUM((SIGNED_VALUE)handle)); break; } result = TAG_RETURN; @@ -1317,7 +1475,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa if (reset_ext_config) ext_config_pop(th2, &prev_ext_config); path = saved_path; - if (ftptr) load_unlock(th2->vm, RSTRING_PTR(path), !state); if (state) { if (state == TAG_FATAL || state == TAG_THROW) { @@ -1343,7 +1501,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa } if (result == TAG_RETURN) { - rb_provide_feature(th2->vm, path); VALUE real = realpath; if (real) { real = rb_fstring(real); @@ -1442,15 +1600,15 @@ void ruby_init_ext(const char *name, void (*init)(void)) { st_table *inits_table; - rb_vm_t *vm = GET_VM(); - if (feature_provided(vm, name, 0)) return; - inits_table = vm->static_ext_inits; if (!inits_table) { inits_table = st_init_strtable(); - vm->static_ext_inits = inits_table; } st_update(inits_table, (st_data_t)name, register_init_ext, (st_data_t)init); } @@ -1595,6 +1753,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol) VALUE path; char *ext; VALUE fname_str = rb_str_new_cstr(fname); resolved = rb_resolve_feature_path((VALUE)NULL, fname_str); if (NIL_P(resolved)) { @@ -1602,7 +1761,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol) if (!ext || !IS_SOEXT(ext)) { rb_str_cat_cstr(fname_str, ".so"); } - if (rb_feature_p(GET_VM(), fname, 0, FALSE, FALSE, 0)) { return dln_symbol(NULL, symbol); } return NULL; @@ -1611,7 +1770,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol) return NULL; } path = rb_ary_entry(resolved, 1); - handle = rb_hash_lookup(ruby_dln_libmap, path); if (NIL_P(handle)) { return NULL; } @@ -1626,6 +1785,7 @@ Init_load(void) ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1); rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter); rb_alias_variable(rb_intern_const("$-I"), id_load_path); rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path); vm->load_path = rb_ary_new(); @@ -1635,7 +1795,9 @@ Init_load(void) rb_define_singleton_method(vm->load_path, "resolve_feature_path", rb_resolve_feature_path, 1); rb_define_virtual_variable("$\"", get_LOADED_FEATURES, 0); - rb_define_virtual_variable("$LOADED_FEATURES", get_LOADED_FEATURES, 0); vm->loaded_features = rb_ary_new(); vm->loaded_features_snapshot = rb_ary_hidden_new(0); vm->loaded_features_index = st_init_numtable(); @@ -531,7 +531,7 @@ w_extended(VALUE klass, struct dump_arg *arg, int check) klass = RCLASS_SUPER(klass); } while (BUILTIN_TYPE(klass) == T_ICLASS) { - if (!FL_TEST(klass, RICLASS_IS_ORIGIN) || BUILTIN_TYPE(RBASIC(klass)->klass) != T_MODULE) { VALUE path = rb_class_name(RBASIC(klass)->klass); w_byte(TYPE_EXTENDED, arg); @@ -197,6 +197,7 @@ struct rb_method_definition_struct { ID original_id; uintptr_t method_serial; }; struct rb_id_table; @@ -247,6 +248,7 @@ const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src); void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me); void rb_scope_visibility_set(rb_method_visibility_t); @@ -254,5 +256,6 @@ VALUE rb_unnamed_parameters(int arity); void rb_clear_method_cache(VALUE klass_or_module, ID mid); void rb_clear_all_refinement_method_cache(void); #endif /* RUBY_METHOD_H */ @@ -1,5 +1,6 @@ #include "internal.h" #include "internal/array.h" #include "iseq.h" #include "vm_core.h" #include "builtin.h" @@ -95,9 +96,23 @@ builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *ta return iseq; } void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table) { - const rb_iseq_t *iseq = builtin_iseq_load(feature_name, table); - rb_iseq_eval(iseq); } @@ -0,0 +1,1139 @@ @@ -121,7 +121,7 @@ rb_obj_reveal(VALUE obj, VALUE klass) VALUE rb_class_allocate_instance(VALUE klass) { - uint32_t index_tbl_num_entries = RCLASS_EXT(klass)->max_iv_count; size_t size = rb_obj_embedded_size(index_tbl_num_entries); if (!rb_gc_size_allocatable_p(size)) { @@ -2097,7 +2097,7 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass) rb_raise(rb_eTypeError, "can't inherit uninitialized class"); } } - RCLASS_SET_SUPER(klass, super); rb_make_metaclass(klass, RBASIC(super)->klass); rb_class_inherited(super, klass); rb_mod_initialize_exec(klass); @@ -2269,17 +2269,21 @@ rb_class_superclass(VALUE klass) RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS)); VALUE super = RCLASS_SUPER(klass); if (!super) { if (klass == rb_cBasicObject) return Qnil; rb_raise(rb_eTypeError, "uninitialized class"); } - if (!RCLASS_SUPERCLASS_DEPTH(klass)) { return Qnil; } else { - super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1]; RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS)); return super; } @@ -2288,7 +2292,7 @@ rb_class_superclass(VALUE klass) VALUE rb_class_get_superclass(VALUE klass) { - return RCLASS(klass)->super; } static const char bad_instance_name[] = "'%1$s' is not allowed as an instance variable name"; @@ -4599,6 +4603,13 @@ InitVM_Object(void) rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */ rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0); rb_define_method(rb_singleton_class(rb_cClass), "allocate", rb_class_alloc_m, 0); rb_define_method(rb_cClass, "allocate", rb_class_alloc_m, 0); rb_define_method(rb_cClass, "new", rb_class_new_instance_pass_kw, -1); @@ -678,6 +678,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc) { rb_proc_t *proc; cfunc_proc_t *sproc; VALUE procval = TypedData_Make_Struct(klass, cfunc_proc_t, &proc_data_type, sproc); VALUE *ep; @@ -692,6 +693,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc) /* self? */ RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc); proc->is_lambda = TRUE; return procval; } @@ -727,6 +729,7 @@ sym_proc_new(VALUE klass, VALUE sym) GetProcPtr(procval, proc); vm_block_type_set(&proc->block, block_type_symbol); proc->is_lambda = TRUE; RB_OBJ_WRITE(procval, &proc->block.as.symbol, sym); return procval; @@ -2006,6 +2009,21 @@ method_owner(VALUE obj) return data->owner; } void rb_method_name_error(VALUE klass, VALUE str) { @@ -4466,6 +4484,8 @@ Init_Proc(void) rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1); rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1); /* UnboundMethod */ rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject); rb_undef_alloc_func(rb_cUnboundMethod); @@ -1824,6 +1824,9 @@ ruby_opt_init(ruby_cmdline_options_t *opt) ruby_init_prelude(); // Initialize JITs after prelude because JITing prelude is typically not optimal. #if USE_YJIT rb_yjit_init(opt->yjit); @@ -656,7 +656,7 @@ rb_shape_transition_remove_ivar(VALUE obj, ID id, VALUE *removed) switch(BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: - fields = RCLASS_FIELDS(obj); break; case T_OBJECT: fields = ROBJECT_FIELDS(obj); @@ -803,7 +803,7 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings) if (BUILTIN_TYPE(obj) == T_OBJECT) { VALUE klass = rb_obj_class(obj); - allow_new_shape = RCLASS_EXT(klass)->variation_count < SHAPE_MAX_VARIATIONS; } bool variation_created = false; @@ -812,14 +812,14 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings) // Check if we should update max_iv_count on the object's class if (BUILTIN_TYPE(obj) == T_OBJECT) { VALUE klass = rb_obj_class(obj); - if (new_shape->next_field_index > RCLASS_EXT(klass)->max_iv_count) { - RCLASS_EXT(klass)->max_iv_count = new_shape->next_field_index; } if (variation_created) { - RCLASS_EXT(klass)->variation_count++; if (emit_warnings && rb_warning_category_enabled_p(RB_WARN_CATEGORY_PERFORMANCE)) { - if (RCLASS_EXT(klass)->variation_count >= SHAPE_MAX_VARIATIONS) { rb_category_warn( RB_WARN_CATEGORY_PERFORMANCE, "The class %"PRIsVALUE" reached %d shape variations, instance variables accesses will be slower and memory usage increased.\n" @@ -7,10 +7,17 @@ describe "Module#ancestors" do ModuleSpecs.ancestors.should == [ModuleSpecs] ModuleSpecs::Basic.ancestors.should == [ModuleSpecs::Basic] ModuleSpecs::Super.ancestors.should == [ModuleSpecs::Super, ModuleSpecs::Basic] - ModuleSpecs.without_test_modules(ModuleSpecs::Parent.ancestors).should == - [ModuleSpecs::Parent, Object, Kernel, BasicObject] - ModuleSpecs.without_test_modules(ModuleSpecs::Child.ancestors).should == - [ModuleSpecs::Child, ModuleSpecs::Super, ModuleSpecs::Basic, ModuleSpecs::Parent, Object, Kernel, BasicObject] end it "returns only modules and classes" do @@ -0,0 +1,97 @@ @@ -9,7 +9,11 @@ class TestABI < Test::Unit::TestCase assert_separately [], <<~RUBY err = assert_raise(LoadError) { require "-test-/abi" } assert_match(/incompatible ABI version/, err.message) - assert_include err.message, "/-test-/abi." RUBY end @@ -27,7 +31,11 @@ class TestABI < Test::Unit::TestCase assert_separately [{ "RUBY_ABI_CHECK" => "1" }], <<~RUBY err = assert_raise(LoadError) { require "-test-/abi" } assert_match(/incompatible ABI version/, err.message) - assert_include err.message, "/-test-/abi." RUBY end @@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@ @@ -0,0 +1,15 @@ @@ -0,0 +1,8 @@ @@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@ @@ -0,0 +1,5 @@ @@ -0,0 +1,8 @@ @@ -0,0 +1,147 @@ @@ -0,0 +1,13 @@ @@ -0,0 +1,5 @@ @@ -0,0 +1,37 @@ @@ -0,0 +1,9 @@ @@ -0,0 +1,26 @@ @@ -0,0 +1,10 @@ @@ -0,0 +1,31 @@ @@ -0,0 +1,14 @@ @@ -0,0 +1,5 @@ @@ -0,0 +1,64 @@ @@ -0,0 +1,3 @@ @@ -0,0 +1,12 @@ @@ -0,0 +1,65 @@ @@ -0,0 +1,13 @@ @@ -0,0 +1,5 @@ @@ -0,0 +1 @@ @@ -0,0 +1,12 @@ @@ -0,0 +1,33 @@ @@ -224,11 +224,18 @@ p Foo::Bar Kernel.module_eval do alias old_require require end called_with = [] Kernel.send :define_method, :require do |path| called_with << path old_require path end yield called_with ensure Kernel.module_eval do @@ -236,6 +243,11 @@ p Foo::Bar alias require old_require undef old_require end end def test_require_implemented_in_ruby_is_called @@ -249,7 +261,8 @@ p Foo::Bar ensure remove_autoload_constant end - assert_equal [file.path], called_with } end end @@ -267,7 +280,8 @@ p Foo::Bar ensure remove_autoload_constant end - assert_equal [a.path, b.path], called_with end end end @@ -0,0 +1,516 @@ @@ -260,6 +260,8 @@ class TestRubyOptions < Test::Unit::TestCase end def test_parser_flag assert_in_out_err(%w(--parser=prism -e) + ["puts :hi"], "", %w(hi), []) assert_in_out_err(%w(--parser=prism --dump=parsetree -e _=:hi), "", /"hi"/, []) @@ -25,6 +25,7 @@ #include "internal/error.h" #include "internal/eval.h" #include "internal/hash.h" #include "internal/object.h" #include "internal/gc.h" #include "internal/re.h" @@ -109,10 +110,10 @@ classname(VALUE klass, bool *permanent) { *permanent = false; - VALUE classpath = RCLASS_EXT(klass)->classpath; if (classpath == 0) return Qnil; - *permanent = RCLASS_EXT(klass)->permanent_classpath; return classpath; } @@ -210,7 +211,7 @@ static enum rb_id_table_iterator_result set_sub_temporary_name_i(ID id, VALUE val, void *data) { val = ((rb_const_entry_t *)val)->value; - if (rb_namespace_p(val) && !RCLASS_EXT(val)->permanent_classpath) { VALUE arg = (VALUE)data; struct sub_temporary_name_args *args = data; args->last = id; @@ -222,7 +223,7 @@ set_sub_temporary_name_i(ID id, VALUE val, void *data) static void set_sub_temporary_name_foreach(VALUE mod, struct sub_temporary_name_args *args, VALUE name) { - RCLASS_SET_CLASSPATH(mod, name, FALSE); struct rb_id_table *tbl = RCLASS_CONST_TBL(mod); if (!tbl) return; if (!name) { @@ -296,7 +297,7 @@ VALUE rb_mod_set_temporary_name(VALUE mod, VALUE name) { // We don't allow setting the name if the classpath is already permanent: - if (RCLASS_EXT(mod)->permanent_classpath) { rb_raise(rb_eRuntimeError, "can't change permanent name"); } @@ -529,6 +530,7 @@ struct rb_global_variable { rb_gvar_marker_t *marker; rb_gvar_compact_t *compactor; struct trace_var *trace; }; struct rb_global_entry { @@ -604,6 +606,13 @@ rb_gvar_ractor_local(const char *name) entry->ractor_local = true; } static void rb_gvar_undef_compactor(void *var) { @@ -629,6 +638,7 @@ rb_global_entry(ID id) var->block_trace = 0; var->trace = 0; rb_id_table_insert(rb_global_tbl, id, (VALUE)entry); } return entry; @@ -982,13 +992,27 @@ rb_gvar_set_entry(struct rb_global_entry *entry, VALUE val) return val; } VALUE rb_gvar_set(ID id, VALUE val) { struct rb_global_entry *entry; entry = rb_global_entry(id); - return rb_gvar_set_entry(entry, val); } VALUE @@ -1000,9 +1024,27 @@ rb_gv_set(const char *name, VALUE val) VALUE rb_gvar_get(ID id) { struct rb_global_entry *entry = rb_global_entry(id); struct rb_global_variable *var = entry->var; - return (*var->getter)(entry->id, var->data); } VALUE @@ -1056,6 +1098,7 @@ rb_f_global_variables(void) if (!rb_ractor_main_p()) { rb_raise(rb_eRactorIsolationError, "can not access global variables from non-main Ractors"); } rb_id_table_foreach(rb_global_tbl, gvar_i, (void *)ary); if (!NIL_P(backref)) { @@ -1335,7 +1378,7 @@ rb_obj_field_get(VALUE obj, rb_shape_t *target_shape) case T_CLASS: case T_MODULE: ASSERT_vm_locking(); - fields = RCLASS_FIELDS(obj); break; case T_OBJECT: fields = ROBJECT_FIELDS(obj); @@ -1392,7 +1435,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef) found = rb_shape_get_iv_index(shape, id, &index); if (found) { - ivar_list = RCLASS_FIELDS(obj); RUBY_ASSERT(ivar_list); val = ivar_list[index]; @@ -1501,7 +1544,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef) switch (BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: - table = RCLASS_FIELDS_HASH(obj); break; case T_OBJECT: @@ -1551,7 +1594,7 @@ obj_transition_too_complex(VALUE obj, st_table *table) break; case T_CLASS: case T_MODULE: - old_fields = RCLASS_FIELDS(obj); rb_shape_set_shape_id(obj, shape_id); RCLASS_SET_FIELDS_HASH(obj, table); break; @@ -2124,7 +2167,7 @@ rb_ivar_defined(VALUE obj, ID id) switch (BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: - table = (st_table *)RCLASS_FIELDS(obj); break; case T_OBJECT: @@ -2188,7 +2231,8 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu break; case T_CLASS: case T_MODULE: - iv_list = RCLASS_FIELDS(itr_data->obj); break; default: iv_list = itr_data->fields_tbl->as.shape.fields; @@ -2280,7 +2324,7 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, }; if (rb_shape_obj_too_complex_p(obj)) { - rb_st_foreach(RCLASS_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data); } else { iterate_over_shapes_with_callback(shape, func, &itr_data); @@ -2701,7 +2745,7 @@ autoload_data(VALUE mod, ID id) // If we are called with a non-origin ICLASS, fetch the autoload data from // the original module. if (RB_TYPE_P(mod, T_ICLASS)) { - if (FL_TEST_RAW(mod, RICLASS_IS_ORIGIN)) { return 0; } else { @@ -2729,6 +2773,10 @@ struct autoload_const { // The shared "autoload_data" if multiple constants are defined from the same feature. VALUE autoload_data_value; // The module we are loading a constant into. VALUE module; @@ -2866,6 +2914,70 @@ get_autoload_data(VALUE autoload_const_value, struct autoload_const **autoload_c return autoload_data; } void rb_autoload(VALUE module, ID name, const char *feature) { @@ -2883,6 +2995,7 @@ struct autoload_arguments { VALUE module; ID name; VALUE feature; }; static VALUE @@ -2952,6 +3065,7 @@ autoload_synchronized(VALUE _arguments) { struct autoload_const *autoload_const; VALUE autoload_const_value = TypedData_Make_Struct(0, struct autoload_const, &autoload_const_type, autoload_const); autoload_const->module = arguments->module; autoload_const->name = arguments->name; autoload_const->value = Qundef; @@ -2968,6 +3082,9 @@ autoload_synchronized(VALUE _arguments) void rb_autoload_str(VALUE module, ID name, VALUE feature) { if (!rb_is_const_id(name)) { rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"", QUOTE_ID(name)); } @@ -2981,6 +3098,7 @@ rb_autoload_str(VALUE module, ID name, VALUE feature) .module = module, .name = name, .feature = feature, }; VALUE result = rb_mutex_synchronize(autoload_mutex, autoload_synchronized, (VALUE)&arguments); @@ -3241,22 +3359,82 @@ autoload_apply_constants(VALUE _arguments) return Qtrue; } static VALUE autoload_feature_require(VALUE _arguments) { struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments; struct autoload_const *autoload_const = arguments->autoload_const; // We save this for later use in autoload_apply_constants: arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type); - VALUE result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments->autoload_data->feature); if (RTEST(result)) { return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments); } - return result; } @@ -3580,6 +3758,8 @@ rb_mod_remove_const(VALUE mod, VALUE name) return rb_const_remove(mod, id); } VALUE rb_const_remove(VALUE mod, ID id) { @@ -3589,7 +3769,7 @@ rb_const_remove(VALUE mod, ID id) rb_check_frozen(mod); ce = rb_const_lookup(mod, id); - if (!ce || !rb_id_table_delete(RCLASS_CONST_TBL(mod), id)) { if (rb_const_defined_at(mod, id)) { rb_name_err_raise("cannot remove %2$s::%1$s", mod, ID2SYM(id)); } @@ -3607,7 +3787,11 @@ rb_const_remove(VALUE mod, ID id) val = Qnil; } - ruby_xfree(ce); return val; } @@ -3829,8 +4013,8 @@ set_namespace_path_i(ID id, VALUE v, void *payload) } set_namespace_path(value, build_const_path(parental_path, id)); - if (!RCLASS_EXT(value)->permanent_classpath) { - RCLASS_SET_CLASSPATH(value, 0, false); } return ID_TABLE_CONTINUE; @@ -3848,7 +4032,7 @@ set_namespace_path(VALUE named_namespace, VALUE namespace_path) RB_VM_LOCK_ENTER(); { - RCLASS_SET_CLASSPATH(named_namespace, namespace_path, true); if (const_table) { rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path); @@ -3884,9 +4068,10 @@ const_set(VALUE klass, ID id, VALUE val) RB_VM_LOCK_ENTER(); { - struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); if (!tbl) { - RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0); rb_clear_constant_cache_for_id(id); ce = ZALLOC(rb_const_entry_t); rb_id_table_insert(tbl, id, (VALUE)ce); @@ -4010,6 +4195,7 @@ const_tbl_update(struct autoload_const *ac, int autoload_force) setup_const_entry(ce, klass, val, visibility); } else { rb_clear_constant_cache_for_id(id); ce = ZALLOC(rb_const_entry_t); @@ -4172,7 +4358,7 @@ static int cvar_lookup_at(VALUE klass, ID id, st_data_t *v) { if (RB_TYPE_P(klass, T_ICLASS)) { - if (FL_TEST_RAW(klass, RICLASS_IS_ORIGIN)) { return 0; } else { @@ -4277,10 +4463,11 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) int result = rb_class_ivar_set(target, id, val); - struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(target); if (!rb_cvc_tbl) { - rb_cvc_tbl = RCLASS_CVC_TBL(target) = rb_id_table_create(2); } struct rb_cvar_class_tbl_entry *ent; @@ -4304,7 +4491,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) // cvar in this lookup. if (result == 0) { if (RB_TYPE_P(target, T_CLASS)) { - if (RCLASS_SUBCLASSES(target)) { rb_class_foreach_subclass(target, check_for_cvar_table, id); } } @@ -4538,13 +4725,13 @@ class_ivar_set_shape_fields(VALUE obj, void *_data) { RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj)); - return RCLASS_FIELDS(obj); } static void class_ivar_set_shape_resize_fields(VALUE obj, attr_index_t _old_capa, attr_index_t new_capa, void *_data) { - REALLOC_N(RCLASS_FIELDS(obj), VALUE, new_capa); } static void @@ -4564,7 +4751,7 @@ class_ivar_set_too_complex_table(VALUE obj, void *_data) { RUBY_ASSERT(rb_shape_obj_too_complex_p(obj)); - return RCLASS_FIELDS_HASH(obj); } int @@ -4574,6 +4761,8 @@ rb_class_ivar_set(VALUE obj, ID id, VALUE val) bool existing = false; rb_check_frozen(obj); RB_VM_LOCK_ENTER(); { existing = general_ivar_set(obj, id, val, NULL, @@ -4620,11 +4809,9 @@ rb_fields_tbl_copy(VALUE dst, VALUE src) rb_ivar_foreach(src, tbl_copy_i, dst); } -rb_const_entry_t * -rb_const_lookup(VALUE klass, ID id) { - struct rb_id_table *tbl = RCLASS_CONST_TBL(klass); - if (tbl) { VALUE val; bool r; @@ -4638,3 +4825,9 @@ rb_const_lookup(VALUE klass, ID id) } return NULL; } @@ -21,6 +21,7 @@ #include "internal/gc.h" #include "internal/inits.h" #include "internal/missing.h" #include "internal/object.h" #include "internal/proc.h" #include "internal/re.h" @@ -1164,6 +1165,7 @@ vm_proc_create_from_captured(VALUE klass, { VALUE procval = rb_proc_alloc(klass); rb_proc_t *proc = RTYPEDDATA_DATA(procval); VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), captured->ep)); @@ -1173,6 +1175,7 @@ vm_proc_create_from_captured(VALUE klass, rb_vm_block_ep_update(procval, &proc->block, captured->ep); vm_block_type_set(&proc->block, block_type); proc->is_from_method = is_from_method; proc->is_lambda = is_lambda; @@ -1204,10 +1207,12 @@ proc_create(VALUE klass, const struct rb_block *block, int8_t is_from_method, in { VALUE procval = rb_proc_alloc(klass); rb_proc_t *proc = RTYPEDDATA_DATA(procval); VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), vm_block_ep(block))); rb_vm_block_copy(procval, &proc->block, block); vm_block_type_set(&proc->block, block->type); proc->is_from_method = is_from_method; proc->is_lambda = is_lambda; @@ -2182,7 +2187,7 @@ static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass) { st_data_t bop; - if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN) && RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) { klass = RBASIC_CLASS(klass); } @@ -2871,17 +2876,30 @@ rb_iseq_eval(const rb_iseq_t *iseq) rb_execution_context_t *ec = GET_EC(); VALUE val; vm_set_top_stack(ec, iseq); val = vm_exec(ec); return val; } VALUE -rb_iseq_eval_main(const rb_iseq_t *iseq) { rb_execution_context_t *ec = GET_EC(); VALUE val; vm_set_main_stack(ec, iseq); val = vm_exec(ec); return val; } @@ -2934,6 +2952,26 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, return val; } /* vm */ void @@ -2956,6 +2994,7 @@ rb_vm_update_references(void *ptr) vm->loaded_features_realpaths = rb_gc_location(vm->loaded_features_realpaths); vm->loaded_features_realpath_map = rb_gc_location(vm->loaded_features_realpath_map); vm->top_self = rb_gc_location(vm->top_self); vm->orig_progname = rb_gc_location(vm->orig_progname); rb_gc_update_values(RUBY_NSIG, vm->trap_list.cmd); @@ -3027,6 +3066,10 @@ rb_vm_mark(void *ptr) rb_gc_mark_maybe(*list->varptr); } rb_gc_mark_movable(vm->mark_object_ary); rb_gc_mark_movable(vm->load_path); rb_gc_mark_movable(vm->load_path_snapshot); @@ -3036,6 +3079,7 @@ rb_vm_mark(void *ptr) rb_gc_mark_movable(vm->loaded_features_snapshot); rb_gc_mark_movable(vm->loaded_features_realpaths); rb_gc_mark_movable(vm->loaded_features_realpath_map); rb_gc_mark_movable(vm->top_self); rb_gc_mark_movable(vm->orig_progname); rb_gc_mark_movable(vm->coverages); @@ -3113,7 +3157,8 @@ ruby_vm_destruct(rb_vm_t *vm) rb_id_table_free(vm->negative_cme_table); st_free_table(vm->overloaded_cme_table); - rb_id_table_free(RCLASS(rb_mRubyVMFrozenCore)->m_tbl); rb_shape_free_all(); @@ -3505,6 +3550,8 @@ thread_mark(void *ptr) rb_gc_mark(th->pending_interrupt_mask_stack); rb_gc_mark(th->top_self); rb_gc_mark(th->top_wrapper); if (th->root_fiber) rb_fiber_mark_self(th->root_fiber); RUBY_ASSERT(th->ec == rb_fiberptr_get_ec(th->ec->fiber_ptr)); @@ -3653,6 +3700,8 @@ th_init(rb_thread_t *th, VALUE self, rb_vm_t *vm) th->last_status = Qnil; th->top_wrapper = 0; th->top_self = vm->top_self; // 0 while self == 0 th->value = Qundef; th->ec->errinfo = Qnil; @@ -3682,10 +3731,16 @@ th_init(rb_thread_t *th, VALUE self, rb_vm_t *vm) VALUE rb_thread_alloc(VALUE klass) { VALUE self = thread_alloc(klass); rb_thread_t *target_th = rb_thread_ptr(self); target_th->ractor = GET_RACTOR(); th_init(target_th, self, target_th->vm = GET_VM()); return self; } @@ -4234,6 +4289,8 @@ Init_VM(void) th->vm = vm; th->top_wrapper = 0; th->top_self = rb_vm_top_self(); rb_vm_register_global_object((VALUE)iseq); th->ec->cfp->iseq = iseq; @@ -597,10 +597,13 @@ vm_cc_check_cme(const struct rb_callcache *cc, const rb_callable_method_entry_t #if 1 // debug print - fprintf(stderr, "iseq_overload:%d\n", (int)cme->def->iseq_overload); rp(cme); rp(vm_cc_cme(cc)); - rb_vm_lookup_overloaded_cme(cme); #endif return false; } @@ -118,6 +118,7 @@ extern int ruby_assert_critical_section_entered; #include "internal.h" #include "internal/array.h" #include "internal/basic_operators.h" #include "internal/sanitizers.h" #include "internal/serial.h" #include "internal/set_table.h" @@ -312,6 +313,7 @@ struct rb_calling_info { int argc; bool kw_splat; VALUE heap_argv; }; #ifndef VM_ARGC_STACK_MAX @@ -743,6 +745,9 @@ typedef struct rb_vm_struct { struct global_object_list *global_object_list; const VALUE special_exceptions[ruby_special_error_count]; /* load */ VALUE top_self; VALUE load_path; @@ -818,6 +823,8 @@ typedef struct rb_vm_struct { size_t fiber_machine_stack_size; } default_params; } rb_vm_t; /* default values */ @@ -1119,6 +1126,9 @@ typedef struct rb_thread_struct { /* for load(true) */ VALUE top_self; VALUE top_wrapper; /* thread control */ @@ -1258,6 +1268,7 @@ RUBY_SYMBOL_EXPORT_END typedef struct { const struct rb_block block; unsigned int is_from_method: 1; /* bool */ unsigned int is_lambda: 1; /* bool */ unsigned int is_isolated: 1; /* bool */ @@ -1349,11 +1360,11 @@ typedef rb_control_frame_t * enum vm_frame_env_flags { /* Frame/Environment flag bits: - * MMMM MMMM MMMM MMMM ____ FFFF FFFE EEEX (LSB) * * X : tag for GC marking (It seems as Fixnum) * EEE : 4 bits Env flags - * FF..: 7 bits Frame flags * MM..: 15 bits frame magic (to check frame corruption) */ @@ -1378,6 +1389,8 @@ enum vm_frame_env_flags { VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = 0x0200, VM_FRAME_FLAG_CFRAME_KW = 0x0400, VM_FRAME_FLAG_PASSED = 0x0800, /* env flag */ VM_ENV_FLAG_LOCAL = 0x0002, @@ -1476,6 +1489,12 @@ VM_FRAME_RUBYFRAME_P(const rb_control_frame_t *cfp) return !VM_FRAME_CFRAME_P(cfp); } #define RUBYVM_CFUNC_FRAME_P(cfp) \ (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC) @@ -1823,6 +1842,7 @@ NORETURN(void rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int /* functions about thread/vm execution */ RUBY_SYMBOL_EXPORT_BEGIN VALUE rb_iseq_eval(const rb_iseq_t *iseq); VALUE rb_iseq_eval_main(const rb_iseq_t *iseq); VALUE rb_iseq_path(const rb_iseq_t *iseq); VALUE rb_iseq_realpath(const rb_iseq_t *iseq); @@ -400,9 +400,9 @@ static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE rec static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self); static VALUE -gccct_hash(VALUE klass, ID mid) { - return (klass >> 3) ^ (VALUE)mid; } NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, unsigned int index, const struct rb_callinfo * ci)); @@ -447,7 +447,8 @@ scope_to_ci(call_type scope, ID mid, int argc, struct rb_callinfo *ci) static inline const struct rb_callcache * gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct rb_callinfo *ci) { - VALUE klass; if (!SPECIAL_CONST_P(recv)) { klass = RBASIC_CLASS(recv); @@ -457,8 +458,13 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct klass = CLASS_OF(recv); } // search global method cache - unsigned int index = (unsigned int)(gccct_hash(klass, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE); rb_vm_t *vm = rb_ec_vm_ptr(ec); const struct rb_callcache *cc = vm->global_cc_cache_table[index]; @@ -483,6 +489,17 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct return gccct_method_search_slowpath(vm, klass, index, ci); } /** * @internal * calls the specified method. @@ -1978,6 +1995,7 @@ eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int li cref = vm_cref_dup(orig_cref); } vm_set_eval_stack(ec, iseq, cref, &block); /* kick */ return vm_exec(ec); @@ -2000,6 +2018,8 @@ eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line) vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp)); } /* kick */ return vm_exec(ec); } @@ -2865,6 +2885,7 @@ Init_vm_eval(void) rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0); rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0); id_result = rb_intern_const("result"); id_tag = rb_intern_const("tag"); id_value = rb_intern_const("value"); @@ -134,7 +134,7 @@ callable_method_entry_p(const rb_callable_method_entry_t *cme) return TRUE; } else { - VM_ASSERT(IMEMO_TYPE_P((VALUE)cme, imemo_ment)); if (callable_class_p(cme->defined_class)) { return TRUE; @@ -418,7 +418,7 @@ vm_push_frame(rb_execution_context_t *ec, #if VM_DEBUG_BP_CHECK .bp_check = sp, #endif - .jit_return = NULL }; /* Ensure the initialization of `*cfp` above never gets reordered with the update of `ec->cfp` below. @@ -963,7 +963,7 @@ vm_get_const_key_cref(const VALUE *ep) while (cref) { if (RCLASS_SINGLETON_P(CREF_CLASS(cref)) || - RCLASS_EXT(CREF_CLASS(cref))->cloned) { return key_cref; } cref = CREF_NEXT(cref); @@ -1256,7 +1256,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call } } - ivar_list = RCLASS_FIELDS(obj); #if !SHAPE_IN_BASIC_FLAGS shape_id = RCLASS_SHAPE_ID(obj); @@ -1335,7 +1335,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call switch (BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: - table = (st_table *)RCLASS_FIELDS(obj); break; case T_OBJECT: @@ -2079,7 +2079,7 @@ static const struct rb_callcache * vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) { const ID mid = vm_ci_mid(ci); - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); struct rb_class_cc_entries *ccs = NULL; VALUE ccs_data; @@ -2125,7 +2125,8 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) } } else { - cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2); } RB_DEBUG_COUNTER_INC(cc_not_found_in_ccs); @@ -4123,7 +4124,7 @@ rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner) VALUE klass = current_class; /* for prepended Module, then start from cover class */ - if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN) && RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) { klass = RBASIC_CLASS(klass); } @@ -5109,6 +5110,20 @@ block_proc_is_lambda(const VALUE procval) } } static VALUE vm_yield_with_cfunc(rb_execution_context_t *ec, const struct rb_captured_block *captured, @@ -5259,11 +5274,16 @@ vm_invoke_iseq_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, VALUE * const rsp = GET_SP() - calling->argc; VALUE * const argv = rsp; int opt_pc = vm_callee_setup_block_arg(ec, calling, ci, iseq, argv, is_lambda ? arg_setup_method : arg_setup_block); SET_SP(rsp); vm_push_frame(ec, iseq, - VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0), captured->self, VM_GUARDED_PREV_EP(captured->ep), 0, ISEQ_BODY(iseq)->iseq_encoded + opt_pc, @@ -5362,6 +5382,9 @@ vm_invoke_proc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, { while (vm_block_handler_type(block_handler) == block_handler_type_proc) { VALUE proc = VM_BH_TO_PROC(block_handler); is_lambda = block_proc_is_lambda(proc); block_handler = vm_proc_to_block_handler(proc); } @@ -5812,6 +5835,7 @@ vm_define_class(ID id, rb_num_t flags, VALUE cbase, VALUE super) /* find klass */ rb_autoload_load(cbase, id); if ((klass = vm_const_get_under(id, flags, cbase)) != 0) { if (!vm_check_if_class(id, flags, super, klass)) unmatched_redefinition("class", cbase, id, klass); @@ -5913,8 +5937,7 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi); // Set max_iv_count on klasses based on number of ivar sets that are in the initialize method if (id == idInitialize && klass != rb_cObject && RB_TYPE_P(klass, T_CLASS) && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) { - - RCLASS_EXT(klass)->max_iv_count = rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval); } if (!is_singleton && vm_scope_module_func_check(ec)) { @@ -39,7 +39,7 @@ vm_ccs_dump_i(ID mid, VALUE val, void *data) static void vm_ccs_dump(VALUE klass, ID target_mid) { - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); if (cc_tbl) { VALUE ccs; if (target_mid) { @@ -87,18 +87,18 @@ vm_mtbl_dump(VALUE klass, ID target_mid) else { fprintf(stderr, " MTBL: NULL\n"); } - if (RCLASS_CALLABLE_M_TBL(klass)) { if (target_mid != 0) { - if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) { rp_m(" [CM**] ", me); } } else { fprintf(stderr, " ## RCLASS_CALLABLE_M_TBL\n"); - rb_id_table_foreach(RCLASS_CALLABLE_M_TBL(klass), vm_cme_dump_i, NULL); } } - if (RCLASS_CC_TBL(klass)) { vm_ccs_dump(klass, target_mid); } klass = RCLASS_SUPER(klass); @@ -166,6 +166,78 @@ const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me) static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id); static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme); static void clear_method_cache_by_id_in_class(VALUE klass, ID mid) @@ -174,33 +246,24 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) if (rb_objspace_garbage_object_p(klass)) return; RB_VM_LOCK_ENTER(); - if (LIKELY(RCLASS_SUBCLASSES(klass) == NULL)) { // no subclasses // check only current class - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); - VALUE ccs_data; - // invalidate CCs - if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { - struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; - rb_yjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme); - if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid); - rb_vm_ccs_free(ccs); - rb_id_table_delete(cc_tbl, mid); - RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs); } // remove from callable_m_tbl, if exists - struct rb_id_table *cm_tbl; - if ((cm_tbl = RCLASS_CALLABLE_M_TBL(klass)) != NULL) { - VALUE cme; - if (rb_yjit_enabled_p && rb_id_table_lookup(cm_tbl, mid, &cme)) { - rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme); - } - rb_id_table_delete(cm_tbl, mid); - RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable); } RB_DEBUG_COUNTER_INC(cc_invalidate_leaf); } else { @@ -223,10 +286,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) else { klass_housing_cme = RCLASS_ORIGIN(owner); } - // replace the cme that will be invalid - VM_ASSERT(lookup_method_table(klass_housing_cme, mid) == (const rb_method_entry_t *)cme); - const rb_method_entry_t *new_cme = rb_method_entry_clone((const rb_method_entry_t *)cme); - rb_method_table_insert(klass_housing_cme, RCLASS_M_TBL(klass_housing_cme), mid, new_cme); } vm_cme_invalidate((rb_callable_method_entry_t *)cme); @@ -234,7 +296,7 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) // In case of refinement ME, also invalidate the wrapped ME that // could be cached at some callsite and is unreachable from any - // RCLASS_CC_TBL. if (cme->def->type == VM_METHOD_TYPE_REFINED && cme->def->body.refined.orig_me) { vm_cme_invalidate((rb_callable_method_entry_t *)cme->def->body.refined.orig_me); } @@ -250,11 +312,12 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) // invalidate complement tbl if (METHOD_ENTRY_COMPLEMENTED(cme)) { VALUE defined_class = cme->defined_class; - struct rb_id_table *cm_tbl = RCLASS_CALLABLE_M_TBL(defined_class); - VM_ASSERT(cm_tbl != NULL); - int r = rb_id_table_delete(cm_tbl, mid); - VM_ASSERT(r == TRUE); (void)r; - RB_DEBUG_COUNTER_INC(cc_invalidate_tree_callable); } RB_DEBUG_COUNTER_INC(cc_invalidate_tree); @@ -263,6 +326,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) invalidate_negative_cache(mid); } } RB_VM_LOCK_LEAVE(); } @@ -302,6 +368,32 @@ rb_clear_method_cache(VALUE klass_or_module, ID mid) } } static int invalidate_all_refinement_cc(void *vstart, void *vend, size_t stride, void *data) { @@ -447,12 +539,17 @@ rb_clear_all_refinement_method_cache(void) void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me) { VALUE table_owner = klass; - if (RB_TYPE_P(klass, T_ICLASS) && !RICLASS_OWNS_M_TBL_P(klass)) { table_owner = RBASIC(table_owner)->klass; } VM_ASSERT_TYPE3(table_owner, T_CLASS, T_ICLASS, T_MODULE); - VM_ASSERT(table == RCLASS_M_TBL(table_owner)); rb_id_table_insert(table, method_id, (VALUE)me); RB_OBJ_WRITTEN(table_owner, Qundef, (VALUE)me); } @@ -760,6 +857,7 @@ rb_method_definition_create(rb_method_type_t type, ID mid) def->original_id = mid; static uintptr_t method_serial = 1; def->method_serial = method_serial++; return def; } @@ -1003,7 +1101,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil rb_clear_method_cache(orig_klass, mid); } } - mtbl = RCLASS_M_TBL(klass); /* check re-definition */ if (rb_id_table_lookup(mtbl, mid, &data)) { @@ -1331,7 +1429,11 @@ search_method0(VALUE klass, ID id, VALUE *defined_class_ptr, bool skip_refined) if (me == NULL) RB_DEBUG_COUNTER_INC(mc_search_notfound); - VM_ASSERT(me == NULL || !METHOD_ENTRY_INVALIDATED(me)); return me; } @@ -1366,23 +1468,27 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ struct rb_id_table *mtbl; const rb_callable_method_entry_t *cme; VALUE cme_data; if (me) { if (me->defined_class == 0) { RB_DEBUG_COUNTER_INC(mc_cme_complement); VM_ASSERT_TYPE2(defined_class, T_ICLASS, T_MODULE); - mtbl = RCLASS_CALLABLE_M_TBL(defined_class); - if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) { cme = (rb_callable_method_entry_t *)cme_data; RB_DEBUG_COUNTER_INC(mc_cme_complement_hit); VM_ASSERT(callable_method_entry_p(cme)); VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme)); } else if (create) { if (!mtbl) { - mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0); } cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class); rb_id_table_insert(mtbl, id, (VALUE)cme); @@ -1418,7 +1524,7 @@ cached_callable_method_entry(VALUE klass, ID mid) { ASSERT_vm_locking(); - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); VALUE ccs_data; if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { @@ -1446,11 +1552,12 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_ ASSERT_vm_locking(); VM_ASSERT(cme != NULL); - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); VALUE ccs_data; if (!cc_tbl) { - cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2); } if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { @@ -1694,7 +1801,7 @@ remove_method(VALUE klass, ID mid) rb_clear_method_cache(self, mid); } rb_clear_method_cache(klass, mid); - rb_id_table_delete(RCLASS_M_TBL(klass), mid); rb_vm_check_redefinition_opt_method(me, klass); |