Commit 81b81ea
committed
feat(gc): Phase C4 — non-moving tenuring (v0.5.228)
Objects that survive ≥2 minor GCs earn GC_FLAG_TENURED and get
treated identically to OLD_ARENA-allocated objects by
drain_trace_worklist_minor — their fields aren't recursively
visited.
crates/perry-runtime/src/gc.rs:
GC_FLAG_TENURED = 0x20 logically promoted
GC_FLAG_HAS_SURVIVED = 0x40 one mark phase observed; tenures next
Age-bump pass at the end of gc_collect_minor's mark phase:
walks arena_walk_objects, for each MARKED-or-PINNED nursery
object:
- already TENURED → skip
- HAS_SURVIVED set → set TENURED, clear HAS_SURVIVED
- otherwise → set HAS_SURVIVED
Two-bit aging gives PROMOTION_AGE=2 without a counter field.
drain_trace_worklist_minor skip predicate extended to fire on
`pointer_in_old_gen(addr) || (gc_flags & GC_FLAG_TENURED != 0)`.
Minor trace closure now bounded O(young live + RS roots).
Non-moving design: tenured objects stay PHYSICALLY in nursery.
No copying / forwarding pointers / reference rewrites. C4b adds
copying evacuation for the RSS win — this commit lands the
time-win half.
Measured (best-of-5, macOS ARM64):
bench_json_roundtrip:
default: 80 ms / 109 MB
PERRY_GEN_GC=1: 70 ms / 109 MB -12% time
PERRY_WRITE_BARRIERS=1: 80 ms / 109 MB
GEN_GC + WB: 70 ms / 109 MB
RSS unchanged (no compaction yet — C4b territory).
New unit test test_minor_gc_promotes_after_two_survivals:
pinned object flags transition {} → HAS_SURVIVED → TENURED
across 3 minor collections; TENURED idempotent thereafter.
Runtime tests 158 -> 159.
Regression:
20/20 test_json_*.ts under default + GEN_GC=1 WB=1
Gap tests 25/28 (baseline)
Phase C is now correctness + time-win complete. C4b (copying
evacuation → RSS ≤70 MB) and Phase D (flip default + drop
conservative scanner) remain. C4b is the architectural boss-
fight: cross-arena copying with full reference-update propagation,
significant correctness surface. With C4 landed, the bench
70 ms / 109 MB result is honest: time matches projection, RSS
bottlenecked by no-compaction.1 parent 783f1cf commit 81b81ea
4 files changed
Lines changed: 148 additions & 41 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
| 151 | + | |
151 | 152 | | |
152 | 153 | | |
153 | 154 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | | - | |
| 112 | + | |
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| |||
0 commit comments