Skip to content

fix(codegen): retain typed arrays across specialized calls - #9812

Closed
proggeramlug wants to merge 1 commit into
PerryTS:mainfrom
proggeramlug:fix/9782-full-gc-repsel
Closed

fix(codegen): retain typed arrays across specialized calls#9812
proggeramlug wants to merge 1 commit into
PerryTS:mainfrom
proggeramlug:fix/9782-full-gc-repsel

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

A specialized typed-array call passes a raw header pointer and relies on the caller to retain the array. At a binding's last use, native GC liveness could end while preparing that raw argument. A full collection inside the callee then reclaimed its array storage; taMix in the representation stress fixture returned a corrupted checksum.

Keep the boxed typed-array owner live until the specialized call returns, including the guarded fast-call path. This preserves the raw calling convention and hoisted element access. The regression covers both module and function-local last uses. The native-root harness also recognizes LLVM's quoted specialized function names so it can verify these calls directly.

Closes #9782.

Validation:

  • The canonical GC representation matrix passes all five previously failing full-collection arms plus default and forced/verified moving controls: 7 PASS, 0 UNVER, 0 FAIL. Every arm's collection liveness check passes.
  • The original stress fixture and the new last-use regression both match Node 26.5.1 under full-GC pressure; the new fixture also passes canonical parity with the default timeout and no skips.
  • All 16 native-root coverage tests pass. The new test checks the post-RS4GC live set for macOS arm64 and Linux x86_64; moving the lifetime use before the call makes the owner disappear from that set.
  • Specialized-ABI codegen tests: 17 passed.
  • Coherent perry-dev compiler/runtime/stdlib build, Node-version consistency, Rust file-size, and diff checks pass.

No collector policy change or version bump.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where typed-array storage could be garbage-collected too early during specialized calls.
    • Prevented incorrect results and checksum errors when typed arrays are used as the final operation before a call.
    • Improved handling of specialized call names to ensure native memory remains tracked correctly.
  • Tests

    • Added regression coverage for typed-array lifetime and garbage-collection scenarios, including repeated allocation churn and full-collection stress cases.

@coderabbitai

coderabbitai Bot commented Sep 5, 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: 6180658a-2c10-4be7-941e-432fcd4b8b38

📥 Commits

Reviewing files that changed from the base of the PR and between c7361c8 and 9b11dbf.

📒 Files selected for processing (6)
  • changelog.d/9782-specialized-typedarray-lifetime.md
  • crates/perry-codegen/src/lower_call/func_ref.rs
  • crates/perry-codegen/src/native_root_coverage/harness_self_tests.rs
  • crates/perry-codegen/src/native_root_coverage/mod.rs
  • crates/perry-codegen/src/native_root_coverage/specialized_calls.rs
  • test-files/test_gap_9782_specialized_typedarray_last_use.ts

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


📝 Walkthrough

Walkthrough

Specialized typed-array calls now keep boxed owners alive through the call. Native root coverage parses quoted specialized callees and verifies statepoint liveness. A GC-stress regression test covers module-level and local typed arrays.

Changes

Typed-array lifetime retention

Layer / File(s) Summary
Root typed-array owners across specialized calls
crates/perry-codegen/src/lower_call/func_ref.rs, crates/perry-codegen/src/native_root_coverage/specialized_calls.rs
Specialized call lowering emits lifetime barriers for TaPtr owners in guarded and guard-free paths. Native tests verify the owner remains live across the specialized call.
Parse quoted specialized callees
crates/perry-codegen/src/native_root_coverage/mod.rs, crates/perry-codegen/src/native_root_coverage/harness_self_tests.rs
The statepoint parser accepts quoted specialized callee names. A self-test verifies the parsed callee and live values.
Exercise typed-array lifetime under GC stress
test-files/test_gap_9782_specialized_typedarray_last_use.ts, changelog.d/9782-specialized-typedarray-lifetime.md
The regression fixture exercises module-level and local typed arrays during allocation churn. The changelog documents the lifetime behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 9b11d

Specialized typed-array calls now retain their boxed owners until return, preventing storage reclamation during full GC while preserving the raw-pointer calling convention. The implementation is covered by native-root and GC-stress regressions, with no remaining concrete merge-blocking risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 5 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #9782 by retaining boxed typed-array owners across specialized calls, including guarded paths, and by adding regression coverage for the reported full-collection last-use fai…
Out of Scope Changes check ✅ Passed The code, parser, harness, changelog, and regression-test changes all support the typed-array lifetime fix and its validation. No unrelated changes are evident.
Title check ✅ Passed The title clearly and concisely describes the main change: retaining typed arrays across specialized code-generation calls.
Description check ✅ Passed The description explains the problem, implementation, regression coverage, linked issue, validation results, and explicitly notes that no collector policy change or version bump is included. It does n…
Full details: Docstring Coverage

Explanation

Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 5 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

Copy link
Copy Markdown
Contributor Author

Landed on main via merge train #9817 (rebase-merged, so your commits keep their authorship). 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

1 participant