diff --git a/.github/workflows/check_sast.yml b/.github/workflows/check_sast.yml index dbe2f43bb475c8..3b4eb17646bb66 100644 --- a/.github/workflows/check_sast.yml +++ b/.github/workflows/check_sast.yml @@ -45,7 +45,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7 + uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0 continue-on-error: true analyze: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ce81e15ed8a164..c8e32674832359 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -96,6 +96,17 @@ jobs: sudo sysctl -w kern.coredump=1 sudo chmod -R +rwx /cores/ + - name: Disable ReportCrash + # We don't want this service running on every crash signal. When it's running, processes must wait for + # the service to gather process info before they can finish. We have tests that test our crash signal + # handling and this service can take a while to run which can time our tests out. + run: | + launchctl bootout gui/"$(id -u)"/com.apple.ReportCrash 2>/dev/null || true + launchctl disable gui/"$(id -u)"/com.apple.ReportCrash 2>/dev/null || true + sudo launchctl bootout system/com.apple.ReportCrash.Root 2>/dev/null || true + sudo launchctl disable system/com.apple.ReportCrash.Root 2>/dev/null || true + continue-on-error: true + - name: Delete unused SDKs # To free up disk space to not run out during the run run: | diff --git a/.github/workflows/tarball-windows.yml b/.github/workflows/tarball-windows.yml index 24bfe8dde1bd00..7e32faa3b9395e 100644 --- a/.github/workflows/tarball-windows.yml +++ b/.github/workflows/tarball-windows.yml @@ -97,7 +97,7 @@ jobs: - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: - path: snapshot-*/.downloaded-cache + path: ${{ inputs.archname }}/.downloaded-cache key: downloaded-cache - name: setup env diff --git a/class.c b/class.c index 4e35285c610581..f591eb9a2e6deb 100644 --- a/class.c +++ b/class.c @@ -1047,6 +1047,13 @@ rb_mod_init_copy(VALUE clone, VALUE orig) rb_class_update_superclasses(clone); } + if (RB_TYPE_P(clone, T_CLASS)) { + VALUE super = RCLASS_SUPER(clone); + if (super && RB_TYPE_P(super, T_ICLASS)) { + class_switch_superclass(rb_class_superclass(clone), clone); + } + } + return clone; } diff --git a/compile.c b/compile.c index 3888134c7c8402..41aee58f75570d 100644 --- a/compile.c +++ b/compile.c @@ -1003,10 +1003,10 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq) VALUE * rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */ { - VALUE *original_code; + VALUE *original_code = RUBY_ATOMIC_PTR_LOAD(ISEQ_BODY(iseq)->variable.original_iseq); - if (ISEQ_ORIGINAL_ISEQ(iseq)) return ISEQ_ORIGINAL_ISEQ(iseq); - original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, ISEQ_BODY(iseq)->iseq_size); + if (original_code) return original_code; + original_code = ALLOC_N(VALUE, ISEQ_BODY(iseq)->iseq_size); MEMCPY(original_code, ISEQ_BODY(iseq)->iseq_encoded, VALUE, ISEQ_BODY(iseq)->iseq_size); #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE @@ -1022,6 +1022,15 @@ rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */ } } #endif + + /* Concurrent callers can each build a copy; publish only fully + * translated code and keep the first one. */ + VALUE *prev = ATOMIC_PTR_CAS(ISEQ_BODY(iseq)->variable.original_iseq, + NULL, original_code); + if (prev) { + SIZED_FREE_N(original_code, ISEQ_BODY(iseq)->iseq_size); + return prev; + } return original_code; } diff --git a/configure.ac b/configure.ac index a461adc697cc80..9ae8acee9b6b95 100644 --- a/configure.ac +++ b/configure.ac @@ -3149,7 +3149,6 @@ STATIC= ], [ AS_CASE(["$target_os"], [solaris*|irix*], [CCDLFLAGS="$CCDLFLAGS -KPIC"], - [sunos*], [CCDLFLAGS="$CCDLFLAGS -PIC"], [esix*|uxpds*], [CCDLFLAGS="$CCDLFLAGS -KPIC"], [: ${CCDLFLAGS=""}]) ]) @@ -3190,8 +3189,6 @@ AC_SUBST(EXTOBJS) : ${PRELOADENV=LD_PRELOAD_32} ]) rb_cv_dlopen=yes], - [sunos*], [ : ${LDSHARED='$(LD) -assert nodefinitions'} - rb_cv_dlopen=yes], [irix*], [ : ${LDSHARED='$(LD) -shared'} rb_cv_dlopen=yes], [sysv4*], [ : ${LDSHARED='$(LD) -G'} @@ -3662,9 +3659,6 @@ AS_CASE("$enable_shared", [yes], [ relative_libprefix="/../${multiarch+../}${libdir_basename}" AS_CASE(["$target_os"], - [sunos4*], [ - LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' - ], [linux* | gnu* | k*bsd*-gnu | atheos* | kopensolaris*-gnu | haiku*], [ RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"]) LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' diff --git a/iseq.h b/iseq.h index df74ec86e3fdf4..b346ad0da013e6 100644 --- a/iseq.h +++ b/iseq.h @@ -75,13 +75,6 @@ ISEQ_ORIGINAL_ISEQ_CLEAR(const rb_iseq_t *iseq) } } -static inline VALUE * -ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size) -{ - return ISEQ_BODY(iseq)->variable.original_iseq = - ALLOC_N(VALUE, size); -} - #define ISEQ_TRACE_EVENTS (RUBY_EVENT_LINE | \ RUBY_EVENT_CLASS | \ RUBY_EVENT_END | \ diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb index 82199876ecf35f..39968f2741675c 100644 --- a/test/ruby/test_class.rb +++ b/test/ruby/test_class.rb @@ -846,6 +846,20 @@ def test_subclasses end end + def test_subclasses_includes_clone + c = Class.new + with_include = Class.new(c) { include Module.new } + with_prepend = Class.new(c) { prepend Module.new } + plain = Class.new(c) + + bug22190 = '[ruby-core:126038] [Bug #22190]' + clones = [with_include, with_prepend, plain].flat_map {|k| [k.clone, k.dup]} + subclasses = c.subclasses + clones.each do |k| + assert_equal(1, subclasses.count(k), "#{bug22190} expected #{k.inspect} to appear in subclasses exactly once") + end + end + def test_attached_object c = Class.new sc = c.singleton_class