[pull] master from ruby:master - #1280
Merged
Merged
Conversation
…H-18108) `exit_recompile()` decides whether to invalidate a compiled unit by asking whether the interpreter has finished re-profiling the instruction that exited. It used to identify that instruction by reading `ec->cfp->iseq` and `ec->cfp->pc`. But, we already know those values at compile time, so there's no need to go through `ec`. Moreover, the indirection breaks for any exit that doesn't write its ISEQ and PC into the CFP, as is the case for virtual inline frames, where inlined callees have no physical control frame. There, `ec->cfp` is a perfectly valid CFP -- just not the one for the inlined ISEQ that exited -- so the check reads the profile counter of an unrelated instruction, which never reports as complete. The guard then asks for a recompile on every miss and never gets one.
Wiping the body of a hollowed-out object (556296c) is wrong for a string whose bytes another string reads in place: r = Ractor.new { Ractor.receive } str = "x" * 100 str.instance_variable_set(:@Iv, []) # unshareable, so it is moved str.freeze dup = str.dup # reads str's bytes in place r.send(str, move: true) dup #=> "\0\0\0..." (was "xxx...") str_replace_shared_without_enc() shares instead of copying whenever the target's embedded capacity is too small, and the shared bytes are the source's own slot when the source is embedded. The sharer keeps the root alive and reads that slot for as long as it lives, so the move must leave it as it is. Skip the wipe for an embedded shared root; every other case (a private heap buffer, a plain embedded string) keeps it. The default GC embeds strings up to a few hundred bytes and mmtk embeds any size, so this is reachable with an ordinary dup of a frozen string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
We should be able to see through the fields_obj but right now setivar/getivar disagree on what the return type is (RubyValue/BasicObject) so it doesn't get optimized. We will fix this in the next commit.
It's an imemo, so not a BasicObject. This way, also, the return types in setivar and getivar align and therefore we can optimize this better in load-store elimination.
Use this for extended fields.
gen_materialize_exit_trampoline clears cfp->jit_return and then calls
rb_zjit_materialize_frames. CFP_ZJIT_FRAME_P() is exactly
cfp->jit_return != NULL, so by then the exiting frame no longer looks like
a JIT frame and zjit_materialize_frames() skips its whole per-frame body,
including the branch that clears block_code:
if (jit_frame->materialize_block_code) {
cfp->block_code = NULL;
}
Nothing else clears it. compile_exit_save_state() does not write
block_code, and its comment in zjit/src/backend/lir.rs already states that
this trampoline clears both fields, which it never did. The exiting frame
therefore keeps the block_code ZJIT wrote for it, and
rb_execution_context_mark() marks cfp->block_code; once that iseq is
collected, marking it is "[BUG] try to mark T_NONE".
An instrumented build counts how often the exiting frame reaches
zjit_materialize_frames() with a non-NULL block_code: 5 times in the first
162 trampoline calls of a single btest process on master, 0 with this
change.
Clearing jit_return after materializing instead would be wrong: skipping
the exiting frame is deliberate, since compile_exit_save_state() has
already written its state and the stack-map restore would overwrite it.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The recent change to use `BasicObject.instance_method(:equal?)` broke the ability to share frozen ERB templates across Ractors because `UnboundMethod` isn't shareable. Freezing the `UnboundMethod` _may_ fix the issue (dependong on Ruby version), but replacing the constant with an inline call to the `singleton_class` is simpler (and still avoids calling `equal?` on `@init`). There have previously been many contributions to make ERB Ractor safe, but no tests added to ensure it continues to be Ractor safe, so this commit also adds some regression tests. ruby/erb@75f1ea059e
Ractor.make_shareable isn't needed if everything is plain `freeze`d ruby/erb@50f434e7e5
Each arm of a polymorphic dispatch takes a fresh Snapshot so that the receiver resolves from its refined type instead of the polymorphic profile. However, the fresh Snapshot had no ProfileOracle entries at all, so argument-profile-dependent specializations were disabled in every arm: e.g. Array#[] stayed a CCallVariadic because likely_a could not see the Fixnum profile of the index. Copy the profile entries from the original Snapshot to the per-arm Snapshot, excluding only the receiver's entry (chased through guards), since resolve_receiver_type prefers profiles over static types. On optcarrot, this lets the Array arm of the polymorphic `@fetch[addr]` callsites inline ArrayAref, removing ~3.9M frame-pushing Array#[] calls per iteration (53% of all not-inlined cfunc calls).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 : )