Skip to content

perf(codegen): reuse receiver validation in ordinary counted loops - #9712

Closed
proggeramlug wants to merge 2 commits into
PerryTS:mainfrom
proggeramlug:fix/9254-receiver-descriptors
Closed

perf(codegen): reuse receiver validation in ordinary counted loops#9712
proggeramlug wants to merge 2 commits into
PerryTS:mainfrom
proggeramlug:fix/9254-receiver-descriptors

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Implement Design: safepoint-delimited receiver descriptors — one model to replace six ad-hoc guard-fact tables #9254 Phase 3 for ordinary strict i < array.length numeric-array loops without adding another specialized loop tier.
  • Materialize one loop-invariant receiver validation in the preheader, keep its box precisely rooted, and refresh the cached base handle after every fired back-edge GC poll.
  • Route exact bounded reads through an invariant fast/fallback diamond: validated receivers use a raw load, while validation misses preserve the existing guarded semantics.
  • Keep admission conservative: the descriptor is installed only when the shared receiver-region model finds no boundary other than covered loop polls; calls, allocation, coercion, suspension, and unwind all decline it.

This deliberately leaves Phase 4 (retiring the remaining fact tables one at a time) for follow-up work.

Refs #9254.

Validation

  • cargo build --release
  • cargo test -p perry-codegen --lib — 1,404 passed, 1 ignored
  • cargo test -p perry --test issue_9254_receiver_descriptor_counted_loop -- --test-threads=1 — 2 passed, including a rate-1 scheduled moving-GC run with from-space protection
  • ./run_parity_tests.sh --filter issue_9254_receiver_descriptor_counted_loop under the pinned Node 26.5.1 — 1 passed
  • ./scripts/pre-tag-check.sh --quick
  • python3 scripts/check_test_registration.py
  • cargo clippy -p perry-codegen --lib
  • cargo clippy -p perry --test issue_9254_receiver_descriptor_counted_loop

./scripts/test_affected_crates.sh --base origin/main ran 1,073 Perry bin tests successfully and found one unrelated failure: the existing build-cache inventory does not classify PERRY_CONCAT_SITE_CACHE. The same exact test fails unchanged on a clean detached worktree at base commit 75b886a381918e345f22b7f84dde7f4bb42e8a9a.

Summary by CodeRabbit

  • Performance

    • Improved counted loops over numeric arrays by validating array structure once and reusing the result during iteration.
    • Optimized eligible indexed array reads while preserving guarded fallback behavior when validation fails.
    • Maintained correct behavior during garbage collection and for loops containing allocation or other unsupported operations.
  • Tests

    • Added coverage for optimized loops, validation fallback, allocation-sensitive loops, and moving garbage collection scenarios.
  • Documentation

    • Documented the counted-loop optimization and its conservative eligibility rules.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 303cfd5c-29da-4aad-821c-f47f9943d240

📥 Commits

Reviewing files that changed from the base of the PR and between 0e3ce38 and 845139a.

📒 Files selected for processing (9)
  • changelog.d/9712-receiver-descriptor-counted-loops.md
  • crates/perry-codegen/src/collectors/mod.rs
  • crates/perry-codegen/src/collectors/receiver_regions.rs
  • crates/perry-codegen/src/collectors/receiver_regions_tests.rs
  • crates/perry-codegen/src/expr/index_get.rs
  • crates/perry-codegen/src/expr/index_get/guarded_array.rs
  • crates/perry-codegen/src/stmt/loops.rs
  • crates/perry/tests/issue_9254_receiver_descriptor_counted_loop.rs
  • test-files/test_issue_9254_receiver_descriptor_counted_loop.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

Ordinary counted loops now use one-time receiver validation for eligible numeric-array accesses. Codegen caches and refreshes the receiver handle at loop polls, emits trusted raw-load paths, preserves guarded fallbacks, and adds IR, runtime, moving-GC, and rejection tests.

Changes

Counted-loop receiver descriptor validation

Layer / File(s) Summary
Validation model and region analysis
crates/perry-codegen/src/collectors/receiver_regions.rs, crates/perry-codegen/src/collectors/receiver_regions_tests.rs, crates/perry-codegen/src/collectors/mod.rs
Receiver descriptors now store plain or numeric array validation. Region enders validate address and representation contracts. Trusted-operation traversal excludes only the trusted operation and still visits its children.
Counted-loop descriptor installation
crates/perry-codegen/src/stmt/loops.rs
Eligible i < arr.length loops create rooted receiver caches, install poll-refreshed numeric descriptors, reuse the cache for packed loops, and remove ordinary-loop descriptors at exit.
Validated array read lowering
crates/perry-codegen/src/expr/index_get.rs, crates/perry-codegen/src/expr/index_get/guarded_array.rs
Bounded reads query receiver descriptors. Valid branches use trusted plain or numeric raw loads. Invalid branches retain the existing guarded lowering.
Regression coverage and release record
crates/perry/tests/issue_9254_receiver_descriptor_counted_loop.rs, test-files/test_issue_9254_receiver_descriptor_counted_loop.ts, changelog.d/9712-receiver-descriptor-counted-loops.md
Tests verify preheader validation, refreshed handles at GC polls, moving-GC execution, allocating-region rejection, and invalid-receiver fallback. The changelog records the implementation.
Estimated code review effort: 4 (Complex) ~45 minutes

Merge Risk: ⚪ Minimal · up to 84513

No concrete merge-blocking issue remains, and the optimization preserves guarded fallback and moving-GC behavior.

Sequence Diagram(s)

sequenceDiagram
  participant CountedLoop
  participant ReceiverDescriptorTable
  participant IndexGet
  participant GuardedArray
  participant MovingGC
  CountedLoop->>ReceiverDescriptorTable: Analyze and install numeric array descriptor
  IndexGet->>ReceiverDescriptorTable: Query validated array access
  ReceiverDescriptorTable-->>IndexGet: Return valid_i1 and base handle slot
  IndexGet->>GuardedArray: Emit trusted raw load or checked fallback
  MovingGC->>ReceiverDescriptorTable: Refresh rooted receiver and derived handle at poll
  ReceiverDescriptorTable-->>IndexGet: Provide refreshed handle for later loads
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.53% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 38 functions across 8 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: reusing receiver validation in ordinary counted loops.
Description check ✅ Passed The description is mostly complete. It explains the implementation, references issue #9254, and lists detailed validation commands and results. It does not include the template's separate Changes, Tes…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 60.53% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 38 functions across 8 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug
proggeramlug marked this pull request as ready for review September 4, 2026 09:32
@proggeramlug
proggeramlug force-pushed the fix/9254-receiver-descriptors branch from 412f7aa to 845139a Compare September 4, 2026 09:33
@proggeramlug

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main via merge train #9734 (rebase-merged, so your commits keep their authorship). Gap suite ran clean — the only regressions were #9719's pre-existing http link failure and two macOS oracle artifacts, all attributed in the train PR. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant