Skip to content

Guard typed-feedback dispatch specializations - #1762

Merged
proggeramlug merged 6 commits into
PerryTS:mainfrom
andrewtdiz:codex/guarded-dispatch-specializations
May 25, 2026
Merged

Guard typed-feedback dispatch specializations#1762
proggeramlug merged 6 commits into
PerryTS:mainfrom
andrewtdiz:codex/guarded-dispatch-specializations

Conversation

@andrewtdiz

Copy link
Copy Markdown
Contributor

Summary

  • adds typed-feedback guarded fast paths for array index access, direct object fields, direct closure calls, and direct class method calls
  • preserves fallback paths for dynamic/hazard cases such as object receivers, frozen/setter fields, replaced methods, prototype overrides, native receivers, bound closures, and megamorphic sites
  • keeps the runtime module under the file-size gate by splitting guard-heavy helpers into typed_feedback/guards.rs

Verification

  • cargo test -p perry-runtime typed_feedback -- --test-threads=1
  • cargo test -p perry-codegen --test typed_feedback -- --test-threads=1
  • cargo check -p perry-runtime -p perry-codegen
  • cargo fmt --all -- --check
  • ./scripts/check_file_size.sh
  • git diff --check origin/main..HEAD

Notes

This is the guarded-dispatch performance slice after #1752. It does not close #1096; the numeric-layout/raw-storage PR should follow separately.

@proggeramlug
proggeramlug merged commit ede4960 into PerryTS:main May 25, 2026
10 checks passed
proggeramlug added a commit that referenced this pull request May 25, 2026
…guard exports (#789, #788, #1423)

The async-context core landed earlier (#852 ALS propagation, #865 async_hooks
foundation). This finishes the remaining gaps and makes it usable in release:

#789 — async_hooks lifecycle on promise/await:
  - emit_init boxed the `type` string with POINTER_TAG, so the init hook's
    `type` argument read back as `[object Object]` instead of `"PROMISE"`.
    Box it with STRING_TAG (new box_string helper).
  - the await continuation (Task::AsyncStep) didn't fire before/after or set
    the execution id, so executionAsyncId() stayed 0 across `await` and the
    after hook never fired. Bracket the step call with
    async_hooks::before/after using the result promise's async_id (captured
    as a plain value before the callback per #1663; no-op when async_hooks
    are inactive), mirroring the Task::Promise arm.

#1764 follow-up — #1762 added class-field / direct-call guard helpers in
  typed_feedback/guards.rs with no #[used] anchors, so the auto-optimize
  thin-LTO + strip build dead-stripped them, failing the link for any
  class-field program (incl. the async harness). Add typed fn-pointer
  retention anchors for the four new guards.

Verified: executionAsyncId now survives await, init reports "PROMISE", and
before/after both fire (byte-for-byte vs node). All four async tests pass
under both PERRY_NO_AUTO_OPTIMIZE and auto-optimize; removed their stale
known_failures entries.

Closes #789, #788, #1423.
proggeramlug added a commit that referenced this pull request May 25, 2026
…guard exports (#789, #788, #1423) (#1769)

The async-context core landed earlier (#852 ALS propagation, #865 async_hooks
foundation). This finishes the remaining gaps and makes it usable in release:

#789 — async_hooks lifecycle on promise/await:
  - emit_init boxed the `type` string with POINTER_TAG, so the init hook's
    `type` argument read back as `[object Object]` instead of `"PROMISE"`.
    Box it with STRING_TAG (new box_string helper).
  - the await continuation (Task::AsyncStep) didn't fire before/after or set
    the execution id, so executionAsyncId() stayed 0 across `await` and the
    after hook never fired. Bracket the step call with
    async_hooks::before/after using the result promise's async_id (captured
    as a plain value before the callback per #1663; no-op when async_hooks
    are inactive), mirroring the Task::Promise arm.

#1764 follow-up — #1762 added class-field / direct-call guard helpers in
  typed_feedback/guards.rs with no #[used] anchors, so the auto-optimize
  thin-LTO + strip build dead-stripped them, failing the link for any
  class-field program (incl. the async harness). Add typed fn-pointer
  retention anchors for the four new guards.

Verified: executionAsyncId now survives await, init reports "PROMISE", and
before/after both fire (byte-for-byte vs node). All four async tests pass
under both PERRY_NO_AUTO_OPTIMIZE and auto-optimize; removed their stale
known_failures entries.

Closes #789, #788, #1423.
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.

GC scanning: add layout descriptors and pointer masks

2 participants