lumbda/asm
russell@unturf.com a606b6087e asm-gc: movb-not-orq type patch (kills residual "unbound variable")
Root-cause fix for the residual crashes I had documented as known
issues in §6.6.4. Every heap_alloc call site was setting its type
byte with `orq $(HT_X << 8), -8(%rax)` — but OR merges with the
stale type byte from a free-list-reused block. A pair previously
used as a vector (type 5 = 0b101) re-allocated as pair (type 1 =
0b001) ends up with merged type 0b101 = still vector. Walker then
treats the pair as a vector, reads the pair's car as a "length",
and walks off the block end — hence the hash-set bench's "unbound
variable: t", memory bench's "unbound variable: lst", arena bench's
"unbound variable: k".

Fix: overwrite the byte instead of OR-ing. 18 sites converted from
`orq $(HT_X << 8), -8(%rax)` to `movb $HT_X, -7(%rax)`. Every
previously-residual crash gone on first rerun.

Refreshed benchmark numbers throughout §6.6:

§6.6 Memory table: 122× less memory at 26% slowdown (was 124×,
30%). Range shifted because the fix also accelerated the common
paths; ratio stable.

§6.6.4 HTTP soak at 50,000 requests × 16 concurrent × 4 cells:
  no-GC + snapshot       630 req/s   peak 100 KB     growth 4 KB
  GC    + snapshot       633 req/s   peak 120 KB     growth 4 KB
  no-GC + no snapshot    625 req/s   peak 458 MB     OOM at cap
  GC    + no snapshot    610 req/s   peak 1,092 KB   growth 852 KB

Cell 4 now sustains 50K requests with steady-state 1-chunk memory.
Previous residual edge at 50K (cell 4 failing to start) was a
manifestation of the same type-byte bug, now gone.

§6.6.3 Adaptive numbers collapsed to within ~1% across all three
workloads (was 6% / 7% / 17% deltas). Paper updated to honestly
report adaptive as a null experiment on these shapes — neutral
cost, same stats surface, default on.

§6.6 diagram: bench-gc.png refreshed to match new numbers.

137 asm no-GC + 137 asm GC + 189 shared functional all pass.
Hash-set / memory / arena / adaptive / HTTP benches all clean.
2026-04-18 20:28:31 -04:00
..
Makefile asm: naive stop-the-world mark-sweep GC as a control group 2026-04-18 09:34:51 -04:00
test.sh asm: naive stop-the-world mark-sweep GC as a control group 2026-04-18 09:34:51 -04:00
uncommonlisp asm-gc Fix 2: S-expression portal for the GC build 2026-04-18 19:41:52 -04:00
uncommonlisp-gc asm-gc: movb-not-orq type patch (kills residual "unbound variable") 2026-04-18 20:28:31 -04:00
uncommonlisp-gc.o asm-gc: movb-not-orq type patch (kills residual "unbound variable") 2026-04-18 20:28:31 -04:00
uncommonlisp.o asm-gc Fix 2: S-expression portal for the GC build 2026-04-18 19:41:52 -04:00
uncommonlisp.s asm-gc: movb-not-orq type patch (kills residual "unbound variable") 2026-04-18 20:28:31 -04:00