Skip to content

[pull] master from ruby:master#1197

Merged
pull[bot] merged 11 commits into
turkdevops:masterfrom
ruby:master
Jul 9, 2026
Merged

[pull] master from ruby:master#1197
pull[bot] merged 11 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull

@pull pull Bot commented Jul 9, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

ko1 and others added 11 commits July 9, 2026 22:05
Registering an exit handler with Kernel#at_exit or END{} in a non-main
Ractor behaved confusingly: the block ran in the main Ractor at process
exit even though it was registered from another Ractor. Raise
Ractor::IsolationError instead.

[Feature #22139]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Instead of special-casing it in the optimizer, expand the run-time type
check into HIR and let the optimizer fold it if/when it can. Leave
the `AnyToString` opcode as the fallback.
We can call `rb_any_to_s` directly now because the type check is in HIR.
It is just a call to `rb_any_to_s` which is a call to `rb_sprintf`.
We converted other LoadField constructors to use this method. Use this
method in cruby_methods too.
Don't try to infer it based on the type at codegen; it may be Empty and
that will give the wrong size (because it will match the first case).

See #17504
We have fixed the problem with `num_bits`.
…ransfer return value

The nt scheduling loop reclaimed a terminated coroutine thread's context using
the return value of coroutine_transfer() (through thread_sched_switch0),
assuming it was the resuming context (the dead coroutine). That holds for the
amd64 asm backend, but the ucontext backend returns the transfer *target*
instead, so the loop never recognized the terminal transfer: the reclaim always
saw a live thread, and the loop always unlocked the sched lock -- which the
dying thread had already released in coroutine_thread_terminated -- and
double-unlocked it. Benign on glibc, but FreeBSD's pthread_mutex_unlock returns
EPERM (crash), and it corrupts the scheduler (hang) elsewhere.

Have the terminating coroutine record its own context in nt->dead_co (per
native thread) right before its final transfer; the loop reads it after switch0
returns, independent of coroutine_transfer()'s backend-dependent return value.
It is set and read on the same native thread with nothing running in between,
so it cannot be overwritten before it is consumed.

coroutine_transfer0() and thread_sched_switch0() no longer need to return the
resuming context, so revert them to void (the ASan-only local remains).

Reproduced on Linux with --with-coroutine=ucontext (100% hang before, clean
after); amd64 and ucontext both pass bootstraptest thread/ractor/fiber.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Max Bernstein <ruby@bernsteinbear.com>
@pull pull Bot locked and limited conversation to collaborators Jul 9, 2026
@pull pull Bot added the ⤵️ pull label Jul 9, 2026
@pull pull Bot merged commit 9c3275a into turkdevops:master Jul 9, 2026
1 of 2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants