diff --git a/changelog.d/7289-clarify-static-checker-scope.md b/changelog.d/7289-clarify-static-checker-scope.md new file mode 100644 index 0000000000..f8bfbfd9f1 --- /dev/null +++ b/changelog.d/7289-clarify-static-checker-scope.md @@ -0,0 +1,10 @@ +`gc-rooting-invariant.md` said the static checker was "structurally blind to this +class" and, eight lines later, "the only instrument that sees this class before +it crashes". Both sentences were about different classes and read as a +contradiction. + +The checker's scope is now stated as emitted-LLVM rooting hazards, with its three +known blind spots named and attributed: runtime tables/interning caches (#7231), +unrooted locals in runtime Rust (#7249), and anything its exact-emitted-symbol +sets fail to name (#7284, where property GETs were unread because the set carried +a symbol codegen never emits). diff --git a/docs/src/internals/gc-rooting-invariant.md b/docs/src/internals/gc-rooting-invariant.md index 9c794f52ea..148d3c01c9 100644 --- a/docs/src/internals/gc-rooting-invariant.md +++ b/docs/src/internals/gc-rooting-invariant.md @@ -122,7 +122,28 @@ on a real workload. When adding a cache of a heap pointer, register it in ### 1. The static checker — run this one -It is the only instrument that sees this class before it crashes. +**Scope: emitted-LLVM rooting hazards only** — a stale register or an unrooted +alloca in generated code. Within that scope it is the only instrument that sees +a defect before it crashes, which is why it runs first. + +**It is blind to three classes, all found the hard way. A clean report is not +evidence for any of them:** + +- **Runtime tables and interning caches** (#7231) — it reads emitted IR and + cannot see a runtime cell. Tell: fails 10/10 rather than intermittently. +- **Unrooted locals in runtime Rust** (#7249) — same reason. It read + `0 violations` on both sides of a real bug whose fix was a one-line + `GcSuppressScope` in the `globalThis` bootstrap. +- **Anything its symbol sets do not name** (#7284) — `POLL_CAPABLE_RUNTIME` is + an *exact emitted-symbol* set. It carried `js_object_get_field_by_name`, which + codegen never emits, next to `js_object_set_field_by_name`, which it emits + verbatim. Property sets classified `MOVING: YES`, property gets `MOVING: no`, + and 31 stale uses were dropped by `--moving-only`. **Audit these sets against + what codegen actually emits, the way #7227 audits `ALLOC_RE`.** + +For the classes above, the instruments that catch them are the zeal/quarantine +arms below and a *dependency-scale* workload — #7280 records 25 curated corpus +files passing while 20 lines of stock zod fail. ```bash cargo build --release -p perry -p perry-runtime-static -p perry-stdlib-static