Skip to content

runtime: fresh class templates memoize shapes in their own cell (no side tables); node key order after edits - #11823

Merged
proggeramlug merged 5 commits into
mainfrom
fix/fresh-class-followups
Oct 3, 2026
Merged

proggeramlug merged 5 commits into
mainfrom
fix/fresh-class-followups

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #11780 (fresh classes).

What changed

  • The TEMPLATES and PROTOTYPES side tables are gone. A fresh class template memoizes its final class-object and prototype shapes in its own cell (js_register_class_template_cell). The two entries are removed from scripts/registry_lifetime_allowlist.json (12 lines, nothing else).
  • A fresh class converts (ToPrimitive) and lists its keys like node after edits.
  • GC call-effects tables regenerated from release archives for linux, macos and windows (template cell row, plus 5 rows of existing drift on main); wasm ABI row updated (runtime_abi_check.py --check-wasm-abi passes).

Gates, rebased head 1bea17f vs main f9a65b4, both built and run the same way on perrymaster

  • gc_call_effects linux: identical to archives. registry_lifetime: OK (88 allowlisted, main 90).
  • one_shape fixtures: same set fails on both (class_read_worker, class_relink_methods, setter_site).
  • perry integration (88 targets, class/static/heritage/proto/relink/super): 212 passed / 8 failed on both, the same 8 tests.
  • hir+codegen units: 3331/0 on both. perry-runtime serial: 4846/0 (main 4845/0).
  • run_lint_gates.sh: identical FAIL set on both arms (environment: xwin, file size, inventories); no new failures.

Cost (instructions, paired, vs main)

  • per static method 138 vs 138; call 76 vs 76; new 10978 vs 10977; eval+new+call (enc_f) 55290 vs 55105 (1.003x); eval-only e0/e2/e4/e16 0.994-1.003x.
  • tsc +0.073% instr, same 82 full collections, RSS +1.5%; Zod +0.007%, same output as node.

proggeramlug and others added 5 commits October 3, 2026 14:13
…not in a table

#11780 kept each per-evaluation class template's final class-object and
prototype ShapeIds, slot fills and internal-key transitions in two
thread-local maps keyed by template class id (TEMPLATES, PROTOTYPES), both
allowlisted in the registry lifetime check. They now live in the template's
own record: an image static codegen emits once per template
(@perry_ctpl.<cid>), passed to js_class_evaluation_object and
js_class_object_set_ctor_caps at the evaluation site and registered on the
template's vtable entry for the paths that start from a class object.

ShapeIds name one agent's shape records, so the cell answers only the
thread that recorded it; any other thread takes the ordinary path. Codegen
writes only the cell's length; every record is checked against it.

The two allowlist entries are removed: registry_lifetime_check is red on
#11780's head without them and green here.
Three gaps in #11780's fresh class objects, each shown by a new
fresh_class_object_semantics line that main (a739f6c) gets wrong:

- str-own-undefined: an own toString holding undefined was treated as
  absent, so String(C) returned the class source instead of throwing a
  TypeError (main before #11780 threw). Presence now decides, whatever the
  property holds.
- str-deleted-static: a static toString the template declares still kept the
  source text out after delete C.toString removed it from this evaluation,
  so String(C) gave [object Function]. The class object's own state decides
  (class_object_registry_serves_static), not the template's declaration.
- own-index: getOwnPropertyNames put prototype before integer keys such as a
  static method named 0.
@coderabbitai

coderabbitai Bot commented Oct 3, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: eebdde32-13e8-4c79-b77d-dfcaa130d41f
📥 Commits

Reviewing files that changed from the base of the PR and between a25ac0d and 1bea17f.

⛔ Files ignored due to path filters (4)
  • crates/perry-codegen/src/gc_effects/linux-x86_64.tsv is excluded by !**/*.tsv
  • crates/perry-codegen/src/gc_effects/macos-aarch64.tsv is excluded by !**/*.tsv
  • crates/perry-codegen/src/gc_effects/windows-x86_64.tsv is excluded by !**/*.tsv
  • crates/perry-codegen/src/wasm32/runtime_abi.tsv is excluded by !**/*.tsv
📒 Files selected for processing (17)
  • changelog.d/PLACEHOLDER-fresh-class-followups.md
  • crates/perry-codegen/src/codegen/fresh_class_templates.rs
  • crates/perry-codegen/src/codegen/mod.rs
  • crates/perry-codegen/src/codegen/string_pool.rs
  • crates/perry-codegen/src/expr/static_field_meta.rs
  • crates/perry-codegen/src/runtime_decls/objects.rs
  • crates/perry-codegen/src/runtime_decls/stdlib_ffi/language_core.rs
  • crates/perry-runtime/src/object/class_registry.rs
  • crates/perry-runtime/src/object/class_registry/parent_static.rs
  • crates/perry-runtime/src/object/class_registry/state.rs
  • crates/perry-runtime/src/object/descriptors.rs
  • crates/perry-runtime/src/object/field_get_set/class_object_props.rs
  • crates/perry-runtime/src/object/field_get_set/class_object_template.rs
  • crates/perry-runtime/src/object/field_get_set/class_object_template_tests.rs
  • scripts/registry_lifetime_allowlist.json
  • tests/fixtures/fresh_class_object_semantics/expected.txt
  • tests/fixtures/fresh_class_object_semantics/main.ts
 _____________________________________________________________
< Today's code review brought to you by yesterday's caffeine. >
 -------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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 merged commit 4e6e68e into main Oct 3, 2026
24 checks passed
@proggeramlug
proggeramlug deleted the fix/fresh-class-followups branch October 3, 2026 17:29
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