Problem
scripts/gc_runtime_root_holders.py enumerates static / thread_local! /
lazy_static! declarations. It does not know about Perry's own TLS macro,
perry_thread_local! (crates/perry-runtime/src/tls_hot.rs), so every holder
declared through it is invisible to the gate.
Measured on 7c22189aa (main):
|
count |
| declarations the gate scans |
633 |
declarations inside perry_thread_local! blocks, in the two core crates |
248 (75 files) |
gate script mentions of perry_thread_local |
0 |
So the gate sees roughly 72% of the population it is written to guard.
Spot-checked, none of these is enumerated (--list has no row for any):
EXCEPTION_STATE: UnsafeCell<ExceptionState> (exception.rs)
TYPED_ARRAY_OWN_PROPS: RefCell<PtrHashMap<usize, Vec<TypedArrayOwnProp>>> (typedarray_props.rs)
YOGA_NODES: RefCell<Option<HashMap<u32, YogaNode>>> (yoga.rs)
PENDING_REQUIRE_PARENT, MODULE_PATH_REGISTRY, PATH_MODULE_INIT_ADDRS (module_require*)
A plain thread_local!/static in the same crates is enumerated, so this is
specifically the macro, not the file set.
Why it matters
The failure direction is toward green. A narrower match means fewer hits and
a passing gate, and nothing ever prompts the check. Concretely, today:
MODULE_PATH_REGISTRY holds NaN-boxed heap pointers and is correctly scanned
(scan_module_path_roots_mut, registered in gc/mod.rs). But because the gate
cannot see the declaration, deleting that reg_scanner! line would not turn
the gate red — the exact scenario the gate exists to prevent.
This is the same class as #8207 and the #8163 hunt: a too-narrow symbol/declaration
regex silently removing holders from consideration.
Fix
Teach the enumerator to parse perry_thread_local! { ... } (and the
crate::perry_thread_local! spelling) the way it already parses thread_local!
blocks — the inner syntax is the same static NAME: TYPE = init;.
Budget for the unmasking. Making the gate see 248 more declarations will
surface holders that currently have no verdict, and the gate fails on an
unclassified holder by design. Expect it to go red until they are triaged; that
redness is the fix working, not a regression. Worth landing the enumerator change
and the triage together, or behind a temporary allowlist that can only shrink.
Please also report the population delta (633 -> N) in the PR: a scanner fix
without a stated blast radius is indistinguishable from one nobody measured.
Problem
scripts/gc_runtime_root_holders.pyenumeratesstatic/thread_local!/lazy_static!declarations. It does not know about Perry's own TLS macro,perry_thread_local!(crates/perry-runtime/src/tls_hot.rs), so every holderdeclared through it is invisible to the gate.
Measured on
7c22189aa(main):perry_thread_local!blocks, in the two core cratesperry_thread_localSo the gate sees roughly 72% of the population it is written to guard.
Spot-checked, none of these is enumerated (
--listhas no row for any):EXCEPTION_STATE: UnsafeCell<ExceptionState>(exception.rs)TYPED_ARRAY_OWN_PROPS: RefCell<PtrHashMap<usize, Vec<TypedArrayOwnProp>>>(typedarray_props.rs)YOGA_NODES: RefCell<Option<HashMap<u32, YogaNode>>>(yoga.rs)PENDING_REQUIRE_PARENT,MODULE_PATH_REGISTRY,PATH_MODULE_INIT_ADDRS(module_require*)A plain
thread_local!/staticin the same crates is enumerated, so this isspecifically the macro, not the file set.
Why it matters
The failure direction is toward green. A narrower match means fewer hits and
a passing gate, and nothing ever prompts the check. Concretely, today:
MODULE_PATH_REGISTRYholds NaN-boxed heap pointers and is correctly scanned(
scan_module_path_roots_mut, registered ingc/mod.rs). But because the gatecannot see the declaration, deleting that
reg_scanner!line would not turnthe gate red — the exact scenario the gate exists to prevent.
This is the same class as #8207 and the #8163 hunt: a too-narrow symbol/declaration
regex silently removing holders from consideration.
Fix
Teach the enumerator to parse
perry_thread_local! { ... }(and thecrate::perry_thread_local!spelling) the way it already parsesthread_local!blocks — the inner syntax is the same
static NAME: TYPE = init;.Budget for the unmasking. Making the gate see 248 more declarations will
surface holders that currently have no verdict, and the gate fails on an
unclassified holder by design. Expect it to go red until they are triaged; that
redness is the fix working, not a regression. Worth landing the enumerator change
and the triage together, or behind a temporary allowlist that can only shrink.
Please also report the population delta (633 -> N) in the PR: a scanner fix
without a stated blast radius is indistinguishable from one nobody measured.