batch: land #8825, #8826, #8830, #8832 - #8835
Conversation
…8770) LLVM takes x19 as a frame base pointer for a function with a dynamic stack allocation (a VLA or a spread-argument area). Its GC roots are stack slots addressed via x19, and x19 is established as `mov x19, sp` immediately after the fixed prologue and before the dynamic `sub sp, sp, xN`, with no realignment — so x19 holds exactly the body SP the fp chain already reconstructs (`fp - fp_to_sp_offset`). Before this, any x19 root flipped the whole-image `chain_walkable` flag false (it required EVERY root to be fp/sp), which globally disabled the fast x29-chain root walk and forced every GC onto the platform unwinder. In cli.js just 63 of 72,812 functions use an x19 base, yet they disabled the correct fast walker for all of them; the unwinder then mis-resolved compiled-JS stack-slot roots and live young objects were swept (0xff-poison-receiver SIGSEGV / `(number).get is not a function`). Make `chain_walkable` accept x19 and resolve an x19 root like an SP root, gated per frame by `x19_is_body_sp` (confirms the `mov x19, sp` prologue shape); a frame that does not match still fails closed to the unwinder. Any other base register still disables the chain walk. Claude-Session: https://claude.ai/code/session_01TwxRkALrR9HKSF1zKLSTAF
|
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 (46)
📝 WalkthroughWalkthroughThis change adds exception-safe async-resource lifecycle handling, GC-safe callback and argument rooting, branded ChangesAsync lifecycle and GC safety
Branded collection dispatch
Socket write accounting
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant AsyncResource
participant ResourceScopes
participant LifecycleHooks
participant Callback
AsyncResource->>ResourceScopes: run_resource_scope_catching
ResourceScopes->>LifecycleHooks: before
ResourceScopes->>Callback: execute callback
ResourceScopes->>LifecycleHooks: after
ResourceScopes-->>AsyncResource: restore state and return result
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 |
Batch landing of four reviewed PRs, validated once as a single merged tree.
#8833 is deliberately excluded — see below.
Audit notes
#8832 is the GC-critical one. It accepts DWARF reg 19 as a frame base only when a per-frame
x19_is_body_sp()re-decodes the prologue and confirms the exactmov x19, spencoding (0x910003F3) after the frame pointer — the walker's anchor — is established. Every branch fails closed:return fp_setif the capture precedes the anchor,return falseon any unexpected sp write (realigningand sp, dynamicsub sp, sp, xN), and a defaultfalseif the bounded 24-instruction window finds nothing. A frame that fails the check falls back to the platform unwinder, i.e. today's behaviour.#8830 was gate-flagged by
local_binding_type_auditfor an unclassifiedlocal_type_hintread inis_declared_map_expr. Verified the whole chain before classifying itruntime-validatedrather than waiving it: codegen uses the declared type only to selectjs_declared_map_get, which brand-checks the live receiver (try_read_gc_header+obj_type == GC_TYPE_MAP) before the fast path, and on a brand miss roots both operands in a handle scope and refreshes them before falling back to ordinaryjs_native_call_methoddispatch. The declared type never becomes a layout proof in emitted code — the #7773 discipline holds.Validation (merged tree)
perry-runtime2694,perry-codegen1257,perry-stdlib120,perry-hir336 — all 0 failedPERRY_GC_FORCE_EVACUATE=1 PERRY_GC_VERIFY_EVACUATION=1), run specifically for runtime(gc): resolve x19 frame-base roots in the fast fp-chain walk (#8770) #8832: 2678 passed / 16 failed — identical failure count to cleanmain, so those 16 are pre-existing behaviour of those knobs and none is introduced heredfchecked before and after; no result produced under ENOSPCWhy #8833 is not in this batch
perf: complete ECS benchmark specializationsfails twoperry-codegentests. Attributed by A/B on clean trees from the same base:collectors::proven_args::tests::pshape_argument_symbol_reachability—$pshape_argssymbol fragments now appear incollectors/hir_facts.rsandcollectors/ptr_shape_report.rs, outside the direct-call allowlist.collectors::ptr_shape::opt_report_tests::escape_kinds_are_discriminated— the call-argument escape reason changed to "passed to a call that does not preserve whole-lifetime containment. A guarded$pshape_argsroute may still specialize field reads performed before the callee publishes the argument…", which no longer contains the substring the test asserts.The second is not obviously a stale-test problem: the new wording makes a substantive claim about what a guarded route may still specialize after a call, and updating the assertion to match would rubber-stamp that claim. That is the author's call, not mine.
Summary by CodeRabbit
New Features
Map.get,ReadonlyMap.get, andReadonlySet.hashandling, including custom objects, subclasses, and nullable values.Bug Fixes
Tests