fix(gc): clear the raw-handle debt regression and ratchet 1006 → 1003 (Layer 3) - #7455
Merged
Conversation
added 2 commits
August 5, 2026 16:51
The Layer 3 debt ratchet has been RED on main since #7424, which added two get_raw_mut_ptr reads to the proxy splice path: 1006 -> 1008, and the baseline may only move DOWN, so the gate could not be satisfied by re-pinning. Both #7424 sites are correct — they re-derive the receiver after a trap that can move it. The ratchet counts them because they spell that as a manual call/re-read pair rather than the combinator the RFC prescribes. One converts exactly; the other is a terminal read with no allocating call to wrap. Converted five call/re-read pairs to across_{mut,const}: array/push_pop.rs proxy splice: trap then re-derive promise/then.rs (x2) js_promise_new_with_parent then re-read object/async_generator_queue.rs js_promise_new then re-read string/append.rs js_string_from_bytes_with_capacity then re-read Each is semantically identical — across_* runs the call and returns the post-collection address — but the ordering becomes structural instead of conventional, which is the whole point of #7341: every fix in that family was an ordering bug, not a missing root. 1008 -> 1003; baseline locked at 1003. 1705 lib tests pass.
|
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 (6)
📝 WalkthroughWalkthroughFive runtime raw-handle sites now use ChangesGC-safe runtime handle reacquisition
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: 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.
Layer 3 of the engine plan (#7294) — "#7389 supplies the first half … and the count is the worklist."
The gate was red
scripts/raw_handle_debt.pyexits 1 onmain:It was at exactly 1006 as of 2026-08-04 and rose today. Per-file diff against yesterday's tip attributes all of it to
array/push_pop.rs(3 → 5), added by #7424. Thefield_set_by_name14 → 0 alongsidefast_paths.rs0 → 3 andtail.rs0 → 11 is #7444's file split, correctly net-zero.The baseline may only be moved down (
--updaterefuses a rise), so this could not be resolved by re-pinning — which is the ratchet working as designed.Both #7424 sites are correct
They re-derive the receiver after a proxy trap that can move it — the comment there says so. The ratchet counts them because they spell that as a manual call/re-read pair rather than the combinator. One converts exactly; the other is a terminal read with no allocating call to wrap, so
across_*cannot express it.Five conversions
array/push_pop.rsremovedpromise/then.rs(×2)js_promise_new_with_parent→ re-readpromiseobject/async_generator_queue.rsjs_promise_new→ re-readoriginalstring/append.rsjs_string_from_bytes_with_capacity→ re-readsrcEach is semantically identical —
across_mut(f)is literallylet r = f(); (r, self.get_raw_mut_ptr()). What changes is that the ordering becomes structural rather than conventional, which is the entire point of #7341: every fix in that family was an ordering bug, not a missing root. A future edit cannot drift the re-read above the call without deleting the combinator.1008 → 1003, baseline locked at 1003 (3 below where it started the day).
Verification
cargo test -p perry-runtime --lib: 1705 passed / 0 failedcargo checkclean,cargo fmt --checkclean--self-test(which guards against the matcher silently ceasing to match) passesNote for the next person
The ratchet penalises correct rooting when it is written as a manual pair. That is deliberate — the pair is what drifts — but it means any PR adding a
get_raw_*_ptrhas to offset it, and #7424 merged without doing so. Worth knowing that this gate cannot be satisfied by re-pinning the way most baselines can.Summary by CodeRabbit