Archive — history, not state. Kept for its reasoning and its evidence; its plan is closed.
Mach text-guard fusion and rejected local-fusion experiments
Date: 2026-07-13
Base: a2539cef
Branch: codex/perf-mach-guard-fusion
This is the second, separately measured increment on the Mach guard-fusion experiment. It changes no semantic mcode, serialized Mach word, language rule, or native lowering.
Retained experiment: is_text plus branch
The first guard experiment deliberately covered only the six predicates that were hot in its initial census. A fresh spectralnorm census exposed another residual pair executing 3.2 million times:
is_text result, value
jump_false result, fallback
The loader now applies the same target-preserving rewrite to is_text as to
the original guard family. Only the first word becomes a Mach-internal opcode.
The original branch word and relative offset remain untouched and independently
targetable. The handler writes the exact boolean result slot, consumes the
branch, and performs the normal pause/interruption check on a taken backward
edge. PIT_MACH_NO_TEXT_GUARD_FUSE=1 disables only this incremental member for
controlled A/B measurement.
Dispatch and timing
Both arms used the same executable, source, serialized Mach blob, and all other fusion families. Results matched exactly.
| benchmark | text fusion off | text fusion on | dispatch delta | off ms | on ms | time delta |
|---|---|---|---|---|---|---|
| spectralnorm | 227,632,186 | 224,432,185 | -3,200,001 (-1.41%) | 284.90 | 278.61 | -2.21% |
| record_field | 86,000,367 | 84,000,366 | -2,000,001 (-2.33%) | 104.05 | 102.76 | -1.24% |
| fannkuch | 232,394,870 | 232,394,869 | -1 | 276.44 | 286.20 | no coverage; timing noise |
| mandelbrot | 36,900,629 | 36,900,628 | -1 | 102.13 | 103.48 | no coverage; timing noise |
The spectralnorm timing is the median of three-run medians from three fresh processes. The complete pairs were 286.22 -> 281.84 ms, 284.45 -> 278.22 ms, and 284.90 -> 278.61 ms; every pair improved by 1.5%-2.2%. The record row is one three-run-median pair and is supporting rather than primary evidence. Fannkuch and mandelbrot demonstrate that programs with no reachable text pair retain the same instruction stream; their timing differences are noise.
Serialized Mach is unchanged: spectralnorm remains 88,760 bytes, record_field 40,296 bytes, fannkuch 30,760 bytes, and mandelbrot 5,160 bytes. There is no per-actor, per-frame, or per-loaded-code allocation.
An exact parent/current rebuild produced this shared-library delta:
- dylib file: 1,454,152 -> 1,454,232 bytes (+80 bytes);
__text: 1,030,876 -> 1,029,284 bytes (-1,592 bytes after compiler/layout reshaping, despite adding the handler);__cstring: +44 bytes; const table: +8 bytes;- aligned
__TEXT,__DATA_CONST, and total virtual segment sizes: unchanged.
The negative text-section delta is a compiler/layout artifact caused by adding an opcode/dispatch target, not a claim that the handler is intrinsically free. The meaningful constrained-console result is that no virtual segment grew and there is no actor-density or loaded-program cost.
Correctness coverage
- Extended cross-lane regression: Mach and native both return
674. - It exercises text true/false truthiness, immediate ASCII, dynamically built heap text, and a live heap text across 3 copying collections (3.9 MiB allocation in the measured run).
- A raw-mcode oracle places a label between the predicate and branch, then
jumps directly to the preserved branch word. It returns
7, proving loader fusion did not steal that legal target. - A second raw-mcode oracle takes a finite backward fused edge, repairs the
tested value, then falls through on its second pass. It returns
11and executes the backward-edge pause-check path. make: passed.- compiler tests: 66/66.
- full warmed suite: 1918/1918. (The first sandboxed run had six expected loopback-bind permission failures; the unrestricted rerun was green.)
./pit fuzz 500 --seed 20260713: 3733/3733.
mist_is_text and Pit_NewBool do not allocate. The new handler therefore
does not need a GC root under the C rooting rules.
Rejected experiment 1: fuse a backedge with its target
A backward jmp often targets an already fused compare/guard head. I tested
handlers that performed the normal pause check and then executed the target
predicate/branch directly while preserving both original target words.
The generic form reduced spectralnorm dispatch by 2.8% and fannkuch by about
5%, but regressed wall time by 2%-3%. Narrowing it to only the measured target
types (is_num, lt, neq) gave:
- spectralnorm: 227,632,186 -> 221,215,376 dispatches, but neutral/noisy time (some trials regressed 3.3%);
- fannkuch: 232,394,870 -> 221,433,783, about 1.2% faster in its favorable trial;
- record_field: 86,000,367 -> 84,000,359, roughly 1.1%-1.3% faster.
Three extra handlers for unstable ~1% gains are not compelling, especially when the generic version demonstrates that fewer dispatches are not sufficient. All implementation code was deleted.
Rejected experiment 2: adjacent loadi plus add
Spectralnorm executes 6.46 million loadi operations, so I tested a local
carrier fusion that retained the load result slot and consumed an immediately
following generic add. It had zero coverage and left dispatch at 227,632,186.
A temporary dynamic diagnostic explained why. In the first six million loads, 4,883,068 were followed by an add, but the load destination was not either add operand. These are interleaved initialization/reuse sequences, not a direct constant carrier. Correctly consuming them requires reaching-definition proof at the use, not adjacency. The diagnostic and handler were deleted.
This reinforces the structured value-fact direction: direct constant operands can be valuable, but only after exact definition/use provenance proves which constant reaches which operand. A local Mach peephole cannot safely infer it.
Recommendation
Keep the is_text member. It is an exact target-internal extension of a proven
mechanism, gives a repeatable 2.2% spectralnorm improvement, costs no dynamic
memory or program bytes, and is inert when the pair is absent. Do not revive
the two rejected local control/data-flow fusions without stronger evidence.
Source: plans/archive/perf-2026-07/perf-campaign-mach-text-guard.md