lumbda/docs/asm-architecture.dot
russell@unturf.com 9b1a60226d whitepaper: diagrams + stats refresh for GC / meta-GC / hash primitives
Diagrams:
  - asm-architecture.dot: adds GC_NAIVE memory cluster (bump, free
    list, conservative stack scan) + meta-GC (with-arena) cluster
    showing the reset path; updates line count (4968 -> 6645),
    builtin count (91 -> 95+), mentions native hash-table-* /
    hash-set-* and the GC-build primitives (with-arena, gc-collect,
    gc-stats, arena-stats).
  - benchmark-binary-size.dot: adds second asm bar for the GC_NAIVE
    build (27 KB stripped vs 23 KB bump-only); updated asm bump
    size from 22 KB (stale) to actual 23 KB.
  - benchmark-gc.dot (new): side-by-side peak RSS for asm bump-only
    (134 MB), naive GC (1.1 MB), meta-GC arena (1.2 MB, 2000/2000
    resets); embedded in §6.6.
  - meta-gc-policy.dot (new): three-way decision tree at
    (with-arena) exit — implicit-GC-fired / mark-in-arena-range /
    no-mark-in-range -> skip / sweep / bulk-reset; embedded in
    §6.6.1.

Stats:
  - 975 verified assertions -> 980 (asm gained 5 via hash-table &
    hash-set tests; 571 Python + 137 asm + 83 C + 189 shared).
  - asm test count 132 -> 137 in the summary list, intro abstract,
    and §11 tier table. Notes that the optional GC build passes
    the same 137 independently (1,117 assertions total when both
    asm binaries are exercised).
  - Stale 4,968 LOC -> 6,645 already fixed in the prior commit;
    the new asm-architecture diagram now matches.

PDF rebuilt, 2.58 MB (was 2.40 MB). All test suites green.
2026-04-18 10:46:29 -04:00

80 lines
4.2 KiB
Text

// Assembly implementation architecture — 2026-04-18 refresh
// "A diagram is worth 10,000 words." — russell@unturf.com
digraph asm_arch {
rankdir=TB
node [shape=box, style=filled, fontname="Helvetica"]
edge [fontname="Helvetica", fontsize=10]
subgraph cluster_binary {
label="Binary: ~22 KB stripped (bump-only) / ~25 KB (GC_NAIVE), zero dependencies"
style=rounded
color="#333333"
fontcolor="#333333"
start [label="_start\nno libc\nno main()" fillcolor="#2d3436" fontcolor=white]
}
subgraph cluster_syscalls {
label="14 Linux Syscalls — no libc"
style=rounded
color="#666666"
fs_io [label="File I/O\nread(0) write(1)\nopen(2) close(3)\nlseek(8)" fillcolor="#dfe6e9"]
mem_io [label="Memory\nmmap(9) munmap(11)" fillcolor="#dfe6e9"]
net_io [label="Sockets\nsocket(41) connect(42)\naccept(43) bind(49)\nlisten(50) setsockopt(54)" fillcolor="#dfe6e9"]
misc [label="Misc\nclock_gettime(228)\nexit(60)" fillcolor="#dfe6e9"]
}
subgraph cluster_memory {
label="Memory Model — default bump; optional mark-sweep + meta-GC"
style=rounded
color="#666666"
bump [label="Bump Allocator\n%r15 = heap ptr\n%r13 = heap limit\nheap_grow mmaps 64 MB chunks\n(1 MB under GC_NAIVE)" fillcolor="#ffeaa7"]
snap [label="heap-snapshot / heap-restore\n(portable arena, bump-only)\nper-request loops = O(1)" fillcolor="#ffeaa7"]
tags [label="Tag-in-Low-3-Bits\n0=int 1=pair 2=sym\n3=closure 4=builtin\n5=special 6=string\n7=vector / hash-table / hash-set\n(disambiguated by negative sentinel)" fillcolor="#ffeaa7"]
gc [label="GC_NAIVE build (opt-in)\n• 8 B header per block\n• stop-the-world mark-sweep\n• first-fit free list\n• conservative stack scan" fillcolor="#fab1a0"]
meta [label="Meta-GC (with-arena thunk)\n1. snapshot %r15\n2. run thunk (free list off)\n3. mark phase (+ result root)\n4. NO mark in range → bulk reset O(1)\n5. otherwise → sweep fallback" fillcolor="#fd79a8"]
}
subgraph cluster_interp {
label="Interpreter — 6,645 lines of GNU assembler (GAS, AT&T syntax); as + ld from GNU binutils"
style=rounded
color="#666666"
tokenize [label="Tokenizer\nchar-by-char\n\\n \\r \\t \\0 escapes" fillcolor="#fff3cd"]
read_fn [label="Reader\nrecursive descent\n→ tagged cons cells\n(load), read-from-string" fillcolor="#fff3cd"]
eval_fn [label="Evaluator\nTCO via jmp .eval_top\nall special forms\n+ eval as builtin" fillcolor="#d4edda"]
print_fn [label="Printer\nitoa, list, vector\nhash-table / hash-set\ncustom output_fd" fillcolor="#81ecec"]
builtins [label="95+ Builtins\narith cons car cdr list ...\nload ports write-file\nportal-save/resume\ntcp-listen/accept/send/recv\nread-from-string eval\nnative hash-table-* / hash-set-*\n(GC build: with-arena, gc-collect,\n gc-stats, arena-stats)" fillcolor="#a29bfe"]
}
subgraph cluster_env {
label="Environment"
style=rounded
color="#666666"
env_chain [label="Linked List\n24 bytes per binding\n[sym | val | next]\n← allocation hot path" fillcolor="#e2d5f1"]
sym_intern [label="Symbol Table\ndjb2 hash, 1024 buckets\nO(1) intern\n(MOAD-0001 fixed)" fillcolor="#e2d5f1"]
}
start -> mem_io [label="allocate heap"]
start -> fs_io [label="read input"]
fs_io -> tokenize
tokenize -> read_fn
read_fn -> eval_fn
eval_fn -> eval_fn [label="TCO: jmp" style=bold color=red]
eval_fn -> builtins [label="apply"]
eval_fn -> env_chain [label="lookup/define"]
eval_fn -> print_fn [label="result"]
print_fn -> fs_io
builtins -> net_io [label="tcp-*"]
builtins -> fs_io [label="(load), file I/O"]
env_chain -> sym_intern
bump -> tags
bump -> snap [label="arena pattern" style=dashed]
bump -> gc [label="GC_NAIVE flag" style=dashed color="#fab1a0"]
gc -> meta [label="with-arena" color="#fd79a8"]
eval_fn -> bump [label="cons/closure alloc"]
meta -> bump [label="reset %r15" style=dashed]
{rank=same; fs_io; mem_io; net_io; misc}
{rank=same; tokenize; read_fn}
{rank=same; bump; tags}
{rank=same; gc; meta}
}