From ed9d6df52b5bc09ae334aa1ccf3f25b073d7b0a2 Mon Sep 17 00:00:00 2001 From: Brummel Date: Fri, 8 May 2026 15:22:32 +0200 Subject: [PATCH] JOURNAL: 18g tidy follow-ups (stat-of-N + let-alias propagation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes two of the three queued debts from the 18g tidy in the same session. Tag-conditional partial-drop helper stays queued — substantial, no observable fixture, all current fallback paths cleanly use shallow ailang_rc_dec. The 18-arc + 18g sub-arc + 18g tidy + post-tidy follow-ups are all closed. Decision 9 has been re-framed to match the orchestrator's dual-allocator stance (commit f10a77e). Next iter is queue-driven; nothing load-bearing is open. --- docs/JOURNAL.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/docs/JOURNAL.md b/docs/JOURNAL.md index 832d6c6..cb7c19b 100644 --- a/docs/JOURNAL.md +++ b/docs/JOURNAL.md @@ -8279,3 +8279,75 @@ The three known debts from the 18g tidy (tag-conditional partial-drop, let-alias-aware mode propagation, bench-number stat-of-N) remain queued. They are RC-side improvements; none of them block the dual-allocator stance. + +## 2026-05-08 — 18g tidy follow-ups: stat-of-N + let-alias propagation + +Picked off the two smaller queued debts from the 18g tidy in +the same session. The third (tag-conditional partial-drop +helper) stays queued — substantively larger, no observable +fixture, and the carve-outs it would close all fall back to +`ailang_rc_dec` cleanly (potential leak, not crash). + +### Stat-of-N in the latency harness (commit `c2af5ad`) + +`bench/latency_harness.py` now accepts `--runs N`. Single-run +output is byte-identical for back-compat. With N≥2 the report +prints median + min..max per cell across runs; with N≥4 the +slowest run is dropped before aggregation, matching +`bench/run.sh`'s drop-slowest convention. `bench/run.sh` +invokes the harness with `--runs 5` for each of the three +latency arms. + +A 5-run smoke on the explicit-rc arm: + +``` +arm | median | p99(med) p99(range) | p99/median(med) +explicit @ rc (5-run) | 226.1 | 296.4 [288.7, 311.3] | 1.31× +``` + +The qualitative claim ("RC tail latency is 23× better than +Boehm; RC RSS is lower than Boehm") holds at this confidence +level — variance is well below the signal. The exact JOURNAL +2026-05-08 18g.2 numbers are now reproducible. + +### Let-alias-aware mode propagation (commit `2e00060`) + +Closes the carve-out shared by 18d.4 Iter A and 18g.1's +pre-tail-call seam: `(let a t (match a ...))` where `t` is a +non-Own fn-param defeated `scrutinee_is_owned`, because +`current_param_modes` only registered fn-params and the +let-binder `a` looked up as missing → default "owned" → arm- +close drop fired on pattern-binders whose underlying memory +the caller still owned. + +Fix shape: `Term::Let` lowering inspects `value`. If `value` +is `Term::Var { name: src }` and `src` is in +`current_param_modes`, the let-binder inherits that mode for +the duration of the body. Push/pop, symmetric with `locals`. +The Borrow-aliasing case is already prevented by the +typechecker's `consume-while-borrowed` rule; the Implicit-mode +case (default for unannotated params) is what the codegen +carve-out actually surfaces, and it's what the new fixture +`rc_let_alias_implicit_param.ailx` pins. + +Pre-fix on the new fixture: SIGSEGV / RC underflow on the +second iteration of `loop`. Post-fix: matches `alloc=gc` +(`0`). Kept as regression coverage. e2e count: 65 → 66. + +### Remaining queued debt + +- **Tag-conditional partial-drop helper.** Closes the two + dynamic-tag carve-outs (18d.4 match-arm shallow fallback + and 18g.2 App-binder partial-drop fallback). Substantial: + a per-type runtime helper that dispatches on the runtime + ctor tag and dec's non-moved ptr fields. No canonical + fixture currently hits the leak path; both fall back to + `ailang_rc_dec` (shallow) cleanly. Stays queued; will close + with the next iter that surfaces the leak in a benchmark or + a real workload. + +The 18-arc + the 18g sub-arc + the 18g tidy + the +post-18g-tidy follow-ups: all closed. Decision 9 has been +re-framed (commit `f10a77e`) to match the orchestrator's +dual-allocator stance. Next iter is queue-driven; nothing +load-bearing is open.