Skip to content

refactor: split gc/layout.rs and codegen/artifacts.rs under the 2000-line cap (unblocks lint on main) - #8212

Merged
proggeramlug merged 3 commits into
mainfrom
fix/file-size-cap-8204
Aug 16, 2026
Merged

refactor: split gc/layout.rs and codegen/artifacts.rs under the 2000-line cap (unblocks lint on main)#8212
proggeramlug merged 3 commits into
mainfrom
fix/file-size-cap-8204

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

lint is red on main; this unblocks it

./scripts/check_file_size.sh exits 1 against the hard 2000-line cap:

2005  crates/perry-codegen/src/codegen/artifacts.rs
2110  crates/perry-runtime/src/gc/layout.rs

Bisected to #8204 (bf8fd868e, the 56 → 48 B header shrink): gc/layout.rs went 1975 → 2110, and codegen/artifacts.rs was sitting at exactly 2000 — right on the cap, so any addition at all broke it.

check_file_size.sh runs in lint, a required status context, so every open PR is currently blocked behind a failure that has nothing to do with it. That is the "required and red for a pre-existing reason" state — it trains everyone to bypass, and the next genuine failure arrives indistinguishable from the standing one.

The split

file before after
codegen/artifacts.rs 2005 1930
codegen/ctor_arity.rs (new) 83
gc/layout.rs 2110 1778
gc/layout/typed_shape.rs (new) 353

Both land with real headroom rather than scraping under at 1999 — artifacts.rs being at exactly 2000 is what made #8204 break it, and leaving it there would just re-arm the trap.

This is relocation-only, and here is the evidence

A file-size fix is the easiest place for an accidental semantic change to hide behind a large mechanical diff, so the claim is checked rather than asserted. Comparing the multiset of non-blank source lines before against (remainder + extracted) after:

pair code that vanished genuinely new
layout.rstyped_shape.rs 5 23
artifacts.rsctor_arity.rs 1 8

All six "vanished" lines reappear in adjusted form, and they are exactly the two categories a relocation produces:

  • Path shorteningsuper::shape_install::{words_contain_slot, words_intersect, hit, record} became shape_install::…, because the extracted module sits inside gc/layout/ and no longer needs the super:: hop.
  • One visibility wideningfn synthesized_ctor_param_count( became pub(super) fn, plus use super::ctor_arity::synthesized_ctor_param_count; at the call site.

The 23 + 8 new lines are module headers, use statements and doc comments. No logic edits, no renames visible outside the modules.

Seam choice

Both extractions are cohesive rather than "the last N lines": typed_shape.rs is the typed-shape layout family, ctor_arity.rs is the synthesized-constructor arity helper and its single caller.

Deliberately not touched, both near the cap and owned by in-flight work: gc/cycle.rs (1991) and gc/barrier/mod.rs (1995).

Note for anyone splitting in this area next: adding a matching pub use <new_mod>::*; is an unused-import warning — hence a -D warnings failure — when the extracted items are #[no_mangle] and reached by symbol rather than by path. The module needs mod <new_mod>; only, plus fixing any internal crate::…::<moved_fn> call sites.

No version bump.

Summary by CodeRabbit

  • Bug Fixes
    • Improved constructor argument handling for classes without explicit constructors, including inherited and imported classes.
    • Added safer fallback behavior when parent-class information is unavailable.
    • Strengthened typed object layout validation for slot counts and pointer/value masks.
    • Improved typed layout setup for newly allocated objects.
    • Added efficient reuse of previously validated typed layouts.

…line cap

#8204 pushed both files over scripts/check_file_size.sh's hard cap
(layout.rs 1975 -> 2110, artifacts.rs 2000 -> 2005), turning the required
lint context red on main for every PR. Pure code moves, no logic change:

- gc/layout.rs: the typed-shape layout installation protocol
  (TypedShapeProof, mask_words, init_typed_shape_layout,
  install_typed_shape_layout_slow, typed_shape_layout_entry,
  js_gc_init_typed_shape_layout, js_gc_declare_typed_shape_layout) moves
  to gc/layout/typed_shape.rs, next to the existing layout/slot_mask.rs.
  2110 -> 1778 lines. The two extern "C" entry points keep their
  crate::gc:: paths via an explicit named re-export.

- codegen/artifacts.rs: synthesized_ctor_param_count moves to a new
  sibling codegen/ctor_arity.rs. 2005 -> 1930 lines.

Claude-Session: https://claude.ai/code/session_01AHvBYz7E6wWKv8kmvLLGpj
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a735af77-09e5-4177-b357-28cc34d86ba3

📥 Commits

Reviewing files that changed from the base of the PR and between f8168ec and 42c94a2.

📒 Files selected for processing (2)
  • changelog.d/8212-file-size-cap-split.md
  • scripts/shape_descriptor_census_baseline.json

📝 Walkthrough

Walkthrough

The change extracts constructor arity calculation and typed-shape layout installation into dedicated modules. Existing codegen integration and typed-shape C ABI paths remain available through module wiring and re-exports.

Changes

Constructor and typed-shape layout modularization

Layer / File(s) Summary
Constructor arity extraction
crates/perry-codegen/src/codegen/ctor_arity.rs, crates/perry-codegen/src/codegen/artifacts.rs, crates/perry-codegen/src/codegen/mod.rs
Constructor arity calculation now resides in ctor_arity.rs. It handles explicit constructors, native and absent parents, local and imported ancestors, and unresolved parents. Artifact generation imports the helper.
Typed-shape layout module
crates/perry-runtime/src/gc/layout/typed_shape.rs, crates/perry-runtime/src/gc/layout.rs, scripts/shape_descriptor_census_baseline.json, changelog.d/8212-file-size-cap-split.md
Typed-shape validation, mask handling, memoized descriptor installation, per-object storage, and both C ABI entry points now reside in typed_shape.rs. layout.rs registers the module and re-exports the APIs. The census baseline and changelog record the relocation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • PerryTS/perry#6930: Adds related typed-shape initialization in standalone constructor paths.
  • PerryTS/perry#6939: Modifies related typed-shape initialization and descriptor installation logic.
  • PerryTS/perry#8182: Relocates related typed-shape layout logic from gc/layout.rs.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the motivation and file changes, but it omits the required related issue, test plan, and checklist sections. Add the template sections and document the verification commands and results, including the related issue or “n/a” and checklist confirmations.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes splitting the two oversized files to satisfy the 2,000-line cap and unblock lint.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/file-size-cap-8204

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.

Ralph Küpper added 2 commits August 16, 2026 16:45
…ray site

Pure path rename in the exact callsite multiset: the one keys_array access
inside the moved typed-shape install block now lives in
gc/layout/typed_shape.rs (raw_member_files 65 -> 66, total sites unchanged).

Claude-Session: https://claude.ai/code/session_01AHvBYz7E6wWKv8kmvLLGpj
@proggeramlug
proggeramlug merged commit 1be0880 into main Aug 16, 2026
5 of 18 checks passed
@proggeramlug
proggeramlug deleted the fix/file-size-cap-8204 branch August 16, 2026 14:47
proggeramlug pushed a commit that referenced this pull request Aug 16, 2026
Rebase moved the base to current main, so both arms were rebuilt there and the
whole measurement retaken. Counters are bit-identical (releases == allocs,
residue constant at 65,915) and peak RSS reproduces within 0.3 MB, so none of
#8204/#8196/#8211/#8212/#8162 moves this residue.

Also records, rather than rounds away, the fixed +80 KB per-process startup cost
the change adds: it is page-granular first touch, not code size (binary +80 B,
__TEXT unchanged) and not the pool data (144 B of empty Vec headers).

Claude-Session: https://claude.ai/code/session_01AHvBYz7E6wWKv8kmvLLGpj
proggeramlug pushed a commit that referenced this pull request Aug 16, 2026
Rebase moved the base to current main, so both arms were rebuilt there and the
whole measurement retaken. Counters are bit-identical (releases == allocs,
residue constant at 65,915) and peak RSS reproduces within 0.3 MB, so none of
#8204/#8196/#8211/#8212/#8162 moves this residue.

Also records, rather than rounds away, the fixed +80 KB per-process startup cost
the change adds: it is page-granular first touch, not code size (binary +80 B,
__TEXT unchanged) and not the pool data (144 B of empty Vec headers).

Claude-Session: https://claude.ai/code/session_01AHvBYz7E6wWKv8kmvLLGpj
proggeramlug pushed a commit that referenced this pull request Aug 16, 2026
Rebase moved the base to current main, so both arms were rebuilt there and the
whole measurement retaken. Counters are bit-identical (releases == allocs,
residue constant at 65,915) and peak RSS reproduces within 0.3 MB, so none of
#8204/#8196/#8211/#8212/#8162 moves this residue.

Also records, rather than rounds away, the fixed +80 KB per-process startup cost
the change adds: it is page-granular first touch, not code size (binary +80 B,
__TEXT unchanged) and not the pool data (144 B of empty Vec headers).

Claude-Session: https://claude.ai/code/session_01AHvBYz7E6wWKv8kmvLLGpj
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