-
-
Notifications
You must be signed in to change notification settings - Fork 161
perf(gc): one pass over the per-object layout tables per prune, and a filter that admits when it is outgrown #9807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
proggeramlug
wants to merge
1
commit into
PerryTS:main
from
proggeramlug:perf/layout-prune-single-pass
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| **The per-object layout death-prune walks its tables once instead of three | ||
| times, and no longer allocates a `Vec` of every live key** — 50.6 MB of a | ||
| compiled claude-code turn's 304 MB in the layout tables (#9792). | ||
|
|
||
| `prune_dead_per_object_layout_owners` visited every surviving key three times | ||
| per collection: `retain` to drop the dead owners, then | ||
| `layout_addr_filter_rebuild` — which first collected all of them into a | ||
| `Vec<usize>` — and then `recount_young_layout_records` to re-derive the | ||
| nursery-key count. The last two want exactly the survivor set `retain` is | ||
| already walking, so both fold into its closure. The `Vec` is gone from the | ||
| rebuild's other caller too. | ||
|
|
||
| The measurement that prompted it also found the accelerator these tables sit | ||
| behind unable to do its job. `layout_addr_filter_may_hold` is a 4,096-bit | ||
| one-hash sketch documented for "one or two entries, ~0.05 % false positives"; | ||
| a new `PERRY_LAYOUT_DIAG` instrument reports **162,258 live keys and 4,096 of | ||
| 4,096 bits set** on one 400-character claude-code reply. Every probe answers | ||
| "may hold", so the early returns in `transfer_per_object_descriptor` and | ||
| `transfer_per_object_slot_mask` never fire, and each rebuild was an O(live | ||
| keys) walk restoring the all-ones state it started from. Past four times the | ||
| bit count — 16,384 keys, where the false-positive rate is already 98.2 % — the | ||
| rebuild now sets all ones directly, the same conservative answer reached in | ||
| O(1); below that the filter keeps exactly the selectivity it has today. The | ||
| instrument says so out loud rather than leaving it to be inferred. Widening the sketch is not available | ||
| from the runtime: its geometry and hash are mirrored in `perry-codegen`'s | ||
| `emit_gated_forget_object_layout`, and discriminating at 162k keys would take | ||
| ~190 KB of inline thread-local storage per thread. | ||
|
|
||
| `transfer_per_object_descriptor` also gained the emptiness test its shared | ||
| flag cannot express: the flag and the filter are common to both per-object | ||
| tables, so a full slot-mask table drags every relocation into the typed-layout | ||
| map as well — which on cc is permanently empty (typed=0, masks=162,258). One | ||
| `len` load replaces two hashes per evacuated object. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Pass pre-prune state to the layout diagnostic.
The diagnostic receives only survivor counts. If 10,000 entries prune to one, it reports one key walked. If more than 16,384 entries prune to one, the filter is saturated but the report says the table is “within it.”
crates/perry-runtime/src/gc/layout_tables.rs#L278-L285: pass pre-prune occupancy and an explicit saturation result with the post-prune snapshot.crates/perry-runtime/src/hot_diag.rs#L414-L416: count pre-prune entries as the entries examined by a rebuilding prune.crates/perry-runtime/src/hot_diag.rs#L460-L464: report saturation from the recorded branch result, not post-prune occupancy.📍 Affects 2 files
crates/perry-runtime/src/gc/layout_tables.rs#L278-L285(this comment)crates/perry-runtime/src/hot_diag.rs#L414-L416crates/perry-runtime/src/hot_diag.rs#L460-L464🤖 Prompt for AI Agents