Skip to content

[pull] master from ruby:master#891

Merged
pull[bot] merged 22 commits intoturkdevops:masterfrom
ruby:master
Mar 27, 2026
Merged

[pull] master from ruby:master#891
pull[bot] merged 22 commits intoturkdevops:masterfrom
ruby:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull bot commented Mar 27, 2026

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 : )

Earlopain and others added 22 commits March 27, 2026 14:38
`tstring_beg` in particular is needed by `yard`.

Before:
> 1980 examples, 606 failures, 15 pending
After:
> 1980 examples, 582 failures, 15 pending

Thought it would be more, but oh well. It needs `on_sp` which I  guess is why there are not many new passes

ruby/prism@e1b18cb582
In `ripper`, both go through the same converion logic.
Needed for rspec, no other failures in their own tests

ruby/prism@510258aa2b
This checks that the value returned from the function registered with
rb_define_alloc_func is of the correct class. When this was first
introduced in 1fe40b7 (by Matz on 2001-10-03), allocation was done
via user-defined Object#allocate, so it made sense to have a runtime
check in release builds. Now that it's defined via rb_define_alloc_func
in the C extension API, I don't think it's necessary.

The check is surprisingly expensive. Removing it makes Object.new about
10% faster. It allows the C compiler to optimize the call to the
function pointer as a tail-call. Removing this also allows ZJIT/YJIT to
call the function directly (ZJIT already does this by having a list of
known safe allocation functions).

There's no way for users to ever have seen this check, other than by
writing a misbehaving C extension, which returns objects with the wrong
class.

[Feature #21966]
…6581)

For sends with ARGS_BLOCKARG (e.g. `foo(&block)`), the block arg sits
on the stack above the receiver and regular arguments. The profiling
(both interpreter and exit profiling) only records types for the
receiver and regular args (argc + 1 values), but profile_stack was
mapping those types onto stack positions starting from the top, which
incorrectly mapped them onto the block arg and the wrong operands.

Fix by detecting ARGS_BLOCKARG at the profile_stack call site and
passing a stack_offset of 1 to skip the block arg. This allows
resolve_receiver_type_from_profile to find the correct receiver type,
enabling method dispatch optimization for these sends after
recompilation via exit profiling.
* ZJIT: Check native stack before compiling ISEQ

When the native/machine stack is nearly exhausted, don't compile and
enter ZJIT code. JIT-compiled code uses more native stack per call
frame than the interpreter, so falling back to the interpreter avoids
SystemStackError in cases where the interpreter would still have room.

This matches what YJIT does in rb_yjit_iseq_gen_entry_point().

* ZJIT: Add skipped_native_stack_full counter
When an ISEQ has already reached MAX_ISEQ_VERSIONS, converting
no-profile sends to SideExits is counterproductive: the exit fires
every time but can never trigger recompilation. Keep them as Send
fallbacks so the interpreter handles them directly without the
overhead of a SideExit + no_profile_send_recompile call.
Instead of storing is_final_version as a field on Function, compute
it dynamically in convert_no_profile_sends by checking the payload's
version count against MAX_ISEQ_VERSIONS.
Keep the original SideExit recompile test alongside the new
final-version test since they cover different behaviors. Remove the
intermediate HIR snapshot since hir_string() now sees the auto-compiled
version as final.
…ler>

Introduce a BlockHandler enum to represent how a block is passed to a
send-like instruction. For now it has only the BlockIseq(IseqPtr)
variant, making this a pure mechanical rename with no behavior change.
Add a BlockArg variant to BlockHandler for sends that pass a block via
&proc (ARGS_BLOCKARG). Previously these were represented as
Some(BlockIseq(null)), requiring a normalization hack in
reduce_send_to_ccall. Now the three cases are explicit: None (no
block), Some(BlockIseq) (literal block), Some(BlockArg) (&proc).

This also fixes a latent bug: with specialized_instruction disabled
(as power_assert does), regular calls use `send` instead of
opt_send_without_block. A null blockiseq was misinterpreted as having
a block, causing gen_block_handler_specval to write a captured block
handler with a null code pointer.
Extend convert_no_profile_sends to handle SendNoProfiles (sends with
literal blocks), not just SendWithoutBlockNoProfiles. The match guards
against BlockArg sends since &proc forwarding can't be exit-profiled.
@pull pull bot locked and limited conversation to collaborators Mar 27, 2026
@pull pull bot added the ⤵️ pull label Mar 27, 2026
@pull pull bot merged commit ec2ff4f into turkdevops:master Mar 27, 2026
1 check failed
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.

4 participants