land #8783: deopt exact callbacks and captured updates - #8808
Merged
Conversation
added 6 commits
August 25, 2026 07:23
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (31)
📝 WalkthroughWalkthroughThe compiler now selects exact additive and update callbacks for versioned indexed loops. It emits private callback clones, resolves targets through runtime metadata, deoptimizes before unsupported operations, resumes at the next index, and marks specialized calls as GC-leaf call sites. ChangesVersioned loop callback specialization
Estimated code review effort: 5 (Critical) | ~120 minutes Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Lands #8783 (perf(codegen): deopt exact callbacks and captured updates).
Why this one needed more than the lint gates
#8783 adds a fourth early-return to
emit_gc_loop_safepoint(stmt/loops.rs), suppressing the GC loop poll whenever the newVersionedIndexedGuardMode::CallbackDeoptis active. Suppressing loop polls is the #7690 shape, and it is guarded bygc-root-dominance.yml— a separate workflow that thelintjob does not include, so a green lint run says nothing about it. The PR touches exactly the four files that gate exists for:gc_call_effects.rs,root_reload.rs,stmt/loops.rs,stmt/versioned_indexed_loop.rs(+152/-10).Root-dominance A/B
Same corpus, same binary profile, clean tree on each side:
#8783 introduces no root-dominance violation. The 7 are pre-existing on
main(see below).The PR's own change to
gc_call_effects.rsis test-side and tightens the invariant — it asserts that a guarded call-site marker must not make its containing function transitively leaf, i.e. the marker fails closed.Fix applied while landing
gc_runtime_root_holdersflagged the newCLOSURE_VERSIONED_LOOP_REGISTRY. Researched rather than pinned as debt: it maps a closure bodyfunc_ptr(a code pointer, never moved by the collector) toTrustedDirectTarget { func_ptr: *const u8, capture_count: u32, boxed_capture_mask: u64 }— every field is a code pointer or a plain integer, so no field can hold a heap pointer and the table cannot hold a GC root. Recorded as anot_a_gc_pointerverdict, not afrontierpin. Its siblingCLOSURE_ARROW_FUNCTION_REGISTRY, same value type in the samethread_local!block, is currently only frontier-pinned.Validation
perry-codegen1246,perry-runtime2687 — 0 failedversioned_indexed_loop_callback_deopt::cold_callback_arms_resume_once_at_the_next_index— passed (313 s)Two pre-existing findings on
main, filed separately from this PRBoth reproduce on clean
mainatdb821b5fd, so neither blocks this:gc_root_dominance_check.pyreports 7 violations / 4 fingerprints against an empty allowlist —js_closure_alloc -> js_object_set_field_by_nameintest_gap_array_iterator_manual_next,test_gap_gc_method_receiver_rooting,test_gap_object_create_method_this, andjs_object_alloc_class_inline_keys_stamped -> js_private_brand_addintest_gap_class_advanced.gc_root_dominance_corpus.shreports 2 of 152 sources "failed to compile" against a budget of 0 —test_gap_gc_http2_pending_event_callback_rootingandtest_gap_gc_net_once_flags_rekey. Both compile fine standalone (Wrote executable, IR emitted), so this is a corpus-harness discrepancy rather than a compiler regression.Measured with a
perry-devbinary; CI uses release, so the absolute numbers may differ there. The A/B is valid regardless — both arms used the identical profile and corpus.Summary by CodeRabbit
New Features
Bug Fixes