Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2b05785
Allow rb_thread_call_with_gvl() to work when thread already has GVL
kbrock Sep 26, 2024
834adc3
[ruby/prism] Avoid out-of-bounds reads
stevenjohnstone Dec 5, 2025
be12e19
[ruby/prism] Avoid undefined int overflow behaviour
stevenjohnstone Dec 5, 2025
786f673
[ruby/prism] Correct constant pool bucket type logic
kddnewton Dec 5, 2025
ee79232
ZJIT: Skip GC.auto_compact test when unsupported
XrXr Dec 3, 2025
3269ae1
ZJIT: Fix -Wpedantic warning in C99 mode when built with YJIT
XrXr Dec 3, 2025
7ecd369
ZJIT: Account for when YJIT is on by default in test_zjit_enable
XrXr Dec 3, 2025
02ca507
JITs: rb_iseq_opcode_at_pc(): Accommodate switch-case interpreter
XrXr Dec 3, 2025
f01fd2b
JITs: Update bindings to include interpreter zjit_ opcodes
XrXr Dec 3, 2025
8132b3d
YJIT: Fix including stats for ZJIT instructions when ZJIT not in build
XrXr Dec 4, 2025
109ddd2
ZJIT: Avoid binding to `rb_iseq_constant_body`
XrXr Dec 3, 2025
fb72ff7
CI: Avoid building ZJIT when LLVM is too old
XrXr Dec 3, 2025
2bc9b5a
tool/update-deps: Skip ZJIT and YJIT+ZJIT build objects
XrXr Dec 3, 2025
8296524
ZJIT: Fix duplicate make rule warning in combo build
XrXr Dec 3, 2025
addeafd
YJIT: Fix duplicate make rule warning in combo build
XrXr Dec 3, 2025
dce716e
ZJIT: Update `depend` for zjit.o
XrXr Dec 4, 2025
9a27100
YJIT: Fix unused_unsafe warning in `StatsAlloc`
XrXr Dec 4, 2025
ffe99a5
ZJIT: configure.ac logic to detect suitable build environment
XrXr Dec 2, 2025
f559a91
ZJIT: configure.ac: Look for GNU make when detecting build environment
XrXr Dec 3, 2025
d396a66
ZJIT: Build by default when build environment allows
XrXr Dec 5, 2025
c4c909b
ZJIT: Include local variable names in `Get|SetLocal` insn's print val…
st0012 Dec 5, 2025
65995c2
[ruby/timeout] Exclude constantly-failing test on x86_64-darwin
eregon Dec 5, 2025
791acc5
Revert "gc.c: Pass shape_id to `newobj_init`"
peterzhu2118 Dec 5, 2025
8f98384
Fix fields object in embedded struct
peterzhu2118 Dec 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/compilers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ jobs:
- { uses: './.github/actions/compilers', name: 'clang 12', with: { tag: 'clang-12' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 11', with: { tag: 'clang-11' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 10', with: { tag: 'clang-10' }, timeout-minutes: 5 }
# llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o.
- { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit' }, timeout-minutes: 5 }
# llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o and fail `make test-leaked-globals`.
- { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 }
- { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 }

compile5:
name: 'omnibus compilations, #5'
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/yjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ jobs:
include:
- test_task: 'yjit-bindgen'
hint: 'To fix: use patch in logs'
configure: '--with-gcc=clang-14 --enable-yjit=dev'
# Build with YJIT+ZJIT for output that works in the most number of configurations
configure: '--with-gcc=clang-14 --enable-yjit=dev --enable-zjit'
libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1'

- test_task: 'check'
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/zjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ jobs:

- test_task: 'zjit-bindgen'
hint: 'To fix: use patch in logs'
configure: '--enable-zjit=dev --with-gcc=clang-16'
# Build with YJIT+ZJIT for output that works in the most number of configurations
configure: '--enable-zjit=dev --enable-yjit --with-gcc=clang-16'
clang_path: '/usr/bin/clang-16'
runs-on: 'ubuntu-24.04' # for clang-16

Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,12 @@ The following bundled gems are updated.
`IO` objects share the same file descriptor, closing one does not affect
the other. [[Feature #18455]]

* GVL

* `rb_thread_call_with_gvl` now works with or without the GVL.
This allows gems to avoid checking `ruby_thread_has_gvl_p`.
Please still be diligent about the GVL. [[Feature #20750]]

* Set

* A C API for `Set` has been added. The following methods are supported:
Expand Down Expand Up @@ -402,6 +408,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[Feature #19908]: https://bugs.ruby-lang.org/issues/19908
[Feature #20610]: https://bugs.ruby-lang.org/issues/20610
[Feature #20724]: https://bugs.ruby-lang.org/issues/20724
[Feature #20750]: https://bugs.ruby-lang.org/issues/20750
[Feature #20884]: https://bugs.ruby-lang.org/issues/20884
[Feature #20925]: https://bugs.ruby-lang.org/issues/20925
[Feature #20971]: https://bugs.ruby-lang.org/issues/20971
Expand Down
96 changes: 57 additions & 39 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy], [:])
AC_CHECK_TOOLS([OBJDUMP], [gobjdump objdump])
AC_CHECK_TOOLS([STRIP], [gstrip strip], [:])

FIRSTMAKEFILE=""

# nm errors with Rust's LLVM bitcode when Rust uses a newer LLVM version than nm.
# In case we're working with llvm-nm, tell it to not worry about the bitcode.
AS_IF([${NM} --help 2>&1 | grep -q 'llvm-bc'], [NM="$NM --no-llvm-bc"])
Expand Down Expand Up @@ -470,6 +472,8 @@ AS_CASE(["$target_os"],
# so wrap clang to insert our fake wasm-opt, which does nothing, in PATH.
CC_WRAPPER=`cd -P "${tooldir}" && pwd`/wasm-clangw
CC="$CC_WRAPPER $CC"

FIRSTMAKEFILE=GNUmakefile:wasm/GNUmakefile.in
])

cc_version=
Expand Down Expand Up @@ -511,6 +515,8 @@ AS_CASE(["$target_os"],
target_cpu=`echo $target_cpu | sed s/i.86/i386/`
AS_CASE(["$target"], [-*], [ target="$target_cpu${target}"])
AS_CASE(["$target_alias"], [-*], [ target_alias="$target_cpu${target_alias}"])
# cygwin/GNUmakefile.in is not exclusively for cygwin.
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
AS_CASE(["$target_os"],
[mingw*], [
test "$rb_cv_msvcrt" = "" && unset rb_cv_msvcrt
Expand Down Expand Up @@ -613,6 +619,22 @@ AS_IF([test -f conf$$.dir/src/cdcmd], [
rm -fr conf$$.dir
AC_MSG_RESULT([$CHDIR])
AC_SUBST(CHDIR)

AS_CASE(["$FIRSTMAKEFILE"], [*GNUmakefile:*], [gnumake=yes], [
AC_MSG_CHECKING([if ${MAKE-make} is GNU make])
mkdir conftest.dir
echo "all:; @echo yes" > conftest.dir/GNUmakefile
echo "all:; @echo no" > conftest.dir/Makefile
gnumake=`(cd conftest.dir; ${MAKE-make})`
rm -fr conftest.dir
AS_CASE(["$gnumake"],
[*yes*], [
FIRSTMAKEFILE=GNUmakefile:template/GNUmakefile.in
gnumake=yes],
[
gnumake=no])
AC_MSG_RESULT($gnumake)
])
}

[begin]_group "compiler section" && {
Expand Down Expand Up @@ -3512,7 +3534,6 @@ AC_SUBST(RUNRUBY)
AC_SUBST(XRUBY)
AC_SUBST(EXTOUT, [${EXTOUT=.ext}])

FIRSTMAKEFILE=""
LIBRUBY_A='lib$(RUBY_SO_NAME)-static.a'
LIBRUBY='$(LIBRUBY_A)'
LIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static'
Expand Down Expand Up @@ -3875,12 +3896,13 @@ AC_SUBST(INSTALL_STATIC_LIBRARY)

[begin]_group "JIT section" && {
AC_CHECK_PROG(RUSTC, [rustc], [rustc], [no]) dnl no ac_tool_prefix
AC_CHECK_TOOL(CARGO, [cargo], [no])

dnl check if rustc is recent enough to build YJIT/ZJIT (rustc >= 1.58.0)
dnl check if rustc is recent enough to build YJIT (rustc >= 1.58.0)
JIT_RUSTC_OK=no
JIT_TARGET_ARCH=
AS_IF([test "$RUSTC" != "no"],
AC_MSG_CHECKING([whether ${RUSTC} works for YJIT/ZJIT])
JIT_TARGET_ARCH=
AC_MSG_CHECKING([whether ${RUSTC} works for YJIT])
AS_CASE(["$target_cpu"],
[arm64|aarch64], [JIT_TARGET_ARCH=aarch64],
[x86_64], [JIT_TARGET_ARCH=x86_64],
Expand Down Expand Up @@ -3914,33 +3936,47 @@ AS_IF([test "$cross_compiling" = no],
)
)

dnl build ZJIT in release mode if rustc >= 1.58.0 is present and we are on a supported platform
AC_ARG_ENABLE(zjit,
AS_HELP_STRING([--enable-zjit],
[enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]),
[ZJIT_SUPPORT=$enableval],
[AS_CASE(["$JIT_TARGET_OK:$JIT_RUSTC_OK:$YJIT_SUPPORT"],
[yes:yes:no], [
ZJIT_SUPPORT=yes
],
[ZJIT_SUPPORT=no]
)]
)

dnl build YJIT in release mode if rustc >= 1.58.0 is present and we are on a supported platform
AC_ARG_ENABLE(yjit,
AS_HELP_STRING([--enable-yjit],
[enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]),
[YJIT_SUPPORT=$enableval],
[AS_CASE(["$JIT_TARGET_OK:$JIT_RUSTC_OK:$ZJIT_SUPPORT"],
[yes:yes:no], [
[AS_CASE(["$JIT_TARGET_OK:$JIT_RUSTC_OK"],
[yes:yes], [
YJIT_SUPPORT=yes
],
[YJIT_SUPPORT=no]
)]
)

CARGO=
dnl build ZJIT in release mode if rustc >= 1.85.0 is present and we are on a supported platform
ZJIT_SUPPORT=no
AC_ARG_ENABLE(zjit,
AS_HELP_STRING([--enable-zjit],
[enable experimental JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.85.0+ is available]),
[ZJIT_SUPPORT=$enableval],
[AS_CASE(["$JIT_TARGET_OK"],
[yes], [
rb_zjit_build_possible=no
AC_MSG_CHECKING([possible to build ZJIT])dnl only checked when --enable-zjit is not specified
# Fails in case rustc target doesn't match ruby target. Can happen on Rosetta, for example.
# 1.85.0 is the first stable version that supports the 2024 edition.
AS_IF([test "$RUSTC" != "no" && echo "#[cfg(target_arch = \"$JIT_TARGET_ARCH\")] fn main() {}" |
$RUSTC - --edition=2024 --emit asm=/dev/null 2>/dev/null],
AS_IF([test "$gnumake" = "yes" -a \( "$YJIT_SUPPORT" = "no" -o "$CARGO" != "no" \)], [
# When only building ZJIT, we don't need cargo; it's required for YJIT+ZJIT build.
# Assume that if rustc is new enough, then cargo is also.
# TODO(alan): Get rid of dependency on cargo in YJIT+ZJIT build. Cargo's offline mode
# still too unreliable: https://github.com/rust-lang/cargo/issues/10352
rb_zjit_build_possible=yes
])
)
AC_MSG_RESULT($rb_zjit_build_possible)
ZJIT_SUPPORT=$rb_zjit_build_possible
]
)]
)

CARGO_BUILD_ARGS=
YJIT_LIBS=
JIT_CARGO_SUPPORT=no
Expand Down Expand Up @@ -4019,9 +4055,8 @@ AS_CASE(["${ZJIT_SUPPORT}"],

# if YJIT+ZJIT release build, or any build that requires Cargo
AS_IF([test x"$JIT_CARGO_SUPPORT" != "xno" -o \( x"$YJIT_SUPPORT" != "xno" -a x"$ZJIT_SUPPORT" != "xno" \)], [
AC_CHECK_TOOL(CARGO, [cargo], [no])
AS_IF([test x"$CARGO" = "xno"],
AC_MSG_ERROR([cargo is required. Installation instructions available at https://www.rust-lang.org/tools/install]))
AC_MSG_ERROR([this build configuration requires cargo. Installation instructions available at https://www.rust-lang.org/tools/install]))

YJIT_LIBS=
ZJIT_LIBS=
Expand Down Expand Up @@ -4187,7 +4222,6 @@ enum {
PLATFORM_DIR=win32
])
LIBRUBY_ALIASES=''
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
AS_IF([test x"$enable_shared" = xyes], [
LIBRUBY='lib$(RUBY_SO_NAME).dll.a'
], [
Expand All @@ -4197,7 +4231,6 @@ enum {
])
],
[wasi*], [
FIRSTMAKEFILE=GNUmakefile:wasm/GNUmakefile.in
AC_LIBOBJ([wasm/missing])
AC_LIBOBJ([wasm/runtime])
AC_LIBOBJ([wasm/fiber])
Expand All @@ -4214,21 +4247,6 @@ AC_ARG_ENABLE(debug-env,
AS_HELP_STRING([--enable-debug-env], [enable RUBY_DEBUG environment variable]),
[AC_SUBST(ENABLE_DEBUG_ENV, yes)])

AS_CASE(["$FIRSTMAKEFILE"], [*GNUmakefile:*], [gnumake=yes], [
AC_MSG_CHECKING([if ${MAKE-make} is GNU make])
mkdir conftest.dir
echo "all:; @echo yes" > conftest.dir/GNUmakefile
echo "all:; @echo no" > conftest.dir/Makefile
gnumake=`(cd conftest.dir; ${MAKE-make})`
rm -fr conftest.dir
AS_CASE(["$gnumake"],
[*yes*], [
FIRSTMAKEFILE=GNUmakefile:template/GNUmakefile.in
gnumake=yes],
[
gnumake=no])
AC_MSG_RESULT($gnumake)
])
AS_IF([test "$gnumake" = yes], [ NULLCMD=: ], [
AC_MSG_CHECKING([for safe null command for ${MAKE-make}])
mkdir conftest.dir
Expand Down
4 changes: 4 additions & 0 deletions depend
Original file line number Diff line number Diff line change
Expand Up @@ -20241,6 +20241,7 @@ zjit.$(OBJEXT): $(top_srcdir)/internal/array.h
zjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
zjit.$(OBJEXT): $(top_srcdir)/internal/bignum.h
zjit.$(OBJEXT): $(top_srcdir)/internal/bits.h
zjit.$(OBJEXT): $(top_srcdir)/internal/box.h
zjit.$(OBJEXT): $(top_srcdir)/internal/class.h
zjit.$(OBJEXT): $(top_srcdir)/internal/compile.h
zjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
Expand All @@ -20252,6 +20253,7 @@ zjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
zjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
zjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
zjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
zjit.$(OBJEXT): $(top_srcdir)/internal/set_table.h
zjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
zjit.$(OBJEXT): $(top_srcdir)/internal/string.h
zjit.$(OBJEXT): $(top_srcdir)/internal/variable.h
Expand Down Expand Up @@ -20428,6 +20430,7 @@ zjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/set.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
zjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h
Expand Down Expand Up @@ -20479,6 +20482,7 @@ zjit.$(OBJEXT): {$(VPATH)}vm_debug.h
zjit.$(OBJEXT): {$(VPATH)}vm_insnhelper.h
zjit.$(OBJEXT): {$(VPATH)}vm_opts.h
zjit.$(OBJEXT): {$(VPATH)}vm_sync.h
zjit.$(OBJEXT): {$(VPATH)}yjit.h
zjit.$(OBJEXT): {$(VPATH)}zjit.c
zjit.$(OBJEXT): {$(VPATH)}zjit.h
zjit.$(OBJEXT): {$(VPATH)}zjit.rbinc
Expand Down
11 changes: 4 additions & 7 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ typedef struct gc_function_map {
void (*stress_set)(void *objspace_ptr, VALUE flag);
VALUE (*stress_get)(void *objspace_ptr);
// Object allocation
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, shape_id_t shape_id, bool wb_protected, size_t alloc_size);
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size);
size_t (*obj_slot_size)(VALUE obj);
size_t (*heap_id_for_size)(void *objspace_ptr, size_t size);
bool (*size_allocatable_p)(size_t size);
Expand Down Expand Up @@ -993,7 +993,8 @@ gc_validate_pc(VALUE obj)
static inline VALUE
newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, shape_id_t shape_id, bool wb_protected, size_t size)
{
VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, shape_id, wb_protected, size);
VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, wb_protected, size);
RBASIC_SET_SHAPE_ID_NO_CHECKS(obj, shape_id);

gc_validate_pc(obj);

Expand Down Expand Up @@ -5063,11 +5064,7 @@ gc_raise(VALUE exc, const char *fmt, ...)
exc, fmt, &ap,
};

if (ruby_thread_has_gvl_p()) {
gc_vraise(&argv);
UNREACHABLE;
}
else if (ruby_native_thread_p()) {
if (ruby_native_thread_p()) {
rb_thread_call_with_gvl(gc_vraise, &argv);
UNREACHABLE;
}
Expand Down
Loading