Skip to content

fix(ci): point the thread-local ratchet at cycle_malloc_trim.rs (main is red, blocking all PRs) - #9268

Merged
proggeramlug merged 1 commit into
PerryTS:mainfrom
proggeramlug:fix/thread-local-ratchet-cycle-split
Aug 31, 2026
Merged

fix(ci): point the thread-local ratchet at cycle_malloc_trim.rs (main is red, blocking all PRs)#9268
proggeramlug merged 1 commit into
PerryTS:mainfrom
proggeramlug:fix/thread-local-ratchet-cycle-split

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

main is currently red on self-test-checkers, which fails that check on every open PR. Two-line allowlist fix.

Not any one PR's diff

Reproduced against a pristine origin/main worktree:

thread-local policy check FAILED:
  crates/perry-runtime/src/gc/cycle_malloc_trim.rs: 1 raw `thread_local!` block(s), none allowed.
  crates/perry-runtime/src/gc/cycle.rs: recorded as having 1 cold `thread_local!` block(s), but has none.

I found it because it was failing on my own #9258, whose diff touches only perry-codegen/src/stmt/loops.rs and therefore cannot affect perry-runtime thread-locals — "impossible for this diff" turned out to be the right first hypothesis.

Both halves are one event, and it traces to my #9245

#9245 added 20 lines to cycle.rs, pushing it past the 2000-line cap, so the merge split cycle_malloc_trim.rs out of it. The #[cfg(test)] malloc-trim counters moved with the split and the allowlist was not regenerated — leaving a stale entry for the old path and an unrecorded one for the new. My change is the proximate cause, so this is mine to clean up.

Recorded rather than converted

TEST_MALLOC_TRIM_CALLS and TEST_MALLOC_TRIM_EXECUTED are both #[cfg(test)]-gated counters, so they are cold by construction. crate::perry_thread_local! exists to keep a hot address out of _tlv_get_addr; these are never on a shipping path, so converting them would add indirection for no benefit and misrepresent them as hot.

One incidental change, flagged

--update also refreshes _hot_declarations 275 → 278. That is a recount of perry_thread_local! uses added since the file was last regenerated, not anything of mine. It moving up means more declarations sit on the hot macro, which is the direction the ratchet wants.

After: thread-local policy OK: 278 hot declarations, 125 raw blocks in 88 recorded cold files, capacity 768.

Summary by CodeRabbit

  • Chores
    • Updated internal tracking for hot declarations.
    • Refreshed the thread-local cold allowlist to reflect current runtime coverage.

`main` is red on `self-test-checkers`, which blocks the check on every open
PR. Reproduced against a pristine `origin/main` worktree, so it is not any
one PR's diff:

  crates/perry-runtime/src/gc/cycle_malloc_trim.rs: 1 raw `thread_local!`
    block(s), none allowed.
  crates/perry-runtime/src/gc/cycle.rs: recorded as having 1 cold
    `thread_local!` block(s), but has none.

Both halves are the same event. PerryTS#9245 (mine) added 20 lines to `cycle.rs`,
which pushed it past the 2000-line cap, so the merge split
`cycle_malloc_trim.rs` out of it. The `#[cfg(test)]` malloc-trim counters
moved with the split and the allowlist was not regenerated, leaving a stale
entry for the old path and an unrecorded one for the new.

Recorded rather than converted: `TEST_MALLOC_TRIM_CALLS` and
`TEST_MALLOC_TRIM_EXECUTED` are both `#[cfg(test)]` counters, so they are
cold by construction and `crate::perry_thread_local!` would buy nothing —
its point is keeping a hot address out of `_tlv_get_addr`, and these are
never on a shipping path.

`--update` also refreshes `_hot_declarations` 275 -> 278. That is a recount
of `perry_thread_local!` uses added since the file was last regenerated, not
a change of mine; the number moving up means more declarations are on the
hot macro, which is the direction the ratchet wants.

After: thread-local policy OK, 278 hot declarations, 125 raw blocks in 88
recorded cold files, capacity 768.
@proggeramlug

Copy link
Copy Markdown
Contributor Author

Merged immediately — this is my breakage and it was blocking every open PR.

I split cycle.rs in #9245 (it sat at exactly 2000 lines, so that PR's two calls broke check_file_size.sh) and extracted the malloc_trim block into cycle_malloc_trim.rs. That block contains a thread_local!, and thread_local_cold_allowlist.json pins cold declarations by file — so moving the file moved the declaration out from under its allowance and left a stale entry behind. Both halves of your reproduction are exactly right, and I confirmed it against a pristine origin/main worktree before merging.

Why my own validation missed it, which is the part worth recording. I ran scripts/run_lint_gates.sh on that branch and got 60/60 green. That script is generated from test.yml's lint job, and check_thread_locals.py runs in self-test-checkers — a different job. So my local gate suite has a blind spot exactly the width of "every checker that isn't in lint", and I had been treating 60/60 as "CI-equivalent". It isn't, and I'd stopped asking.

Your first hypothesis is the transferable bit: your #9258 touches only perry-codegen/src/stmt/loops.rs and therefore cannot affect perry-runtime thread-locals, so "impossible for this diff" was the right thing to trust rather than explain away. That is the same reasoning that catches a red gate belonging to someone else's merge, and it is cheap — a failure whose subject your diff does not touch is a pre-existing failure until proven otherwise.

Two-line allowlist change, check_thread_locals.py passes on the merged result. Sorry for the interruption to your PR.

@proggeramlug
proggeramlug merged commit d9bd897 into PerryTS:main Aug 31, 2026
19 of 20 checks passed
@coderabbitai

coderabbitai Bot commented Aug 31, 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: 3bdddb04-9528-4fb5-867d-baa212ab40c8

📥 Commits

Reviewing files that changed from the base of the PR and between 9ee9919 and 36ad7c6.

📒 Files selected for processing (1)
  • scripts/thread_local_cold_allowlist.json

📝 Walkthrough

Walkthrough

The thread-local cold allowlist increases the _hot_declarations ratchet count from 275 to 278 and replaces the cycle.rs entry with cycle_malloc_trim.rs.

Changes

Thread-local cold allowlist

Layer / File(s) Summary
Update allowlist ratchet and GC entry
scripts/thread_local_cold_allowlist.json
The _hot_declarations count increases from 275 to 278. The allowlist replaces crates/perry-runtime/src/gc/cycle.rs with crates/perry-runtime/src/gc/cycle_malloc_trim.rs.

Estimated code review effort: 1 (Trivial) | ~2 minutes

✨ 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
proggeramlug deleted the fix/thread-local-ratchet-cycle-split branch August 31, 2026 10:27
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