Commit graph

12 commits

Author SHA1 Message Date
489776baa4 asm: naive stop-the-world mark-sweep GC as a control group
Adds a second asm build (asm/uncommonlisp-gc) behind the GC_NAIVE
assembler flag, providing the benchmark baseline we previously had
no data for. Same binary, same surface, different allocator:

  - 8-byte header per heap block (size << 1 | mark), placed at -8
    from the tagged pointer so existing untag + offset accesses
    stay unchanged.
  - Chunk list tracked in a side array, letting sweep walk every
    mmap'd region by header-chained blocks instead of guessing.
  - Free list rebuilt each sweep, first-fit alloc with split on
    large-leftover (>= 24 bytes).
  - Mark phase enumerates five root classes: %r14 (global env,
    untagged chain), sym_else_val, sym_table entries, every
    sym_hash_bucket chain, and a conservative scan from current
    %rsp to the initial stack_top captured at _start. The stack
    scan runs twice per word — once as a tagged value, once as a
    potential untagged env-node pointer (size-guarded to 24 bytes
    so it can't walk off a wrong-size block).
  - Transitive marking via an explicit 16K-entry mark stack;
    gc_mark_env walks untagged env chains from %r14 and from every
    closure's env field.
  - heap_alloc preserves the non-GC ABI (only %rax clobbered) so
    existing callers like bi_append, which holds state in %rcx
    across make_pair, keep working.
  - Overflow path uses check-then-write bumps and pads the old
    chunk's tail with a single dead block before growing, so sweep
    never walks into uninitialized mmap'd memory.
  - HEAP_SIZE shrinks to 1 MB under GC_NAIVE so the collector
    actually runs on ordinary workloads.
  - Two diagnostic builtins in the GC build: (gc-collect) to force
    a collection, (gc-stats) -> (collections . live-bytes).

Control-group bench (examples/bench-gc-memory.lsp, 2000 iterations
of build-sum-discard over 200-element lists, i5-8350U):

  tier           time_ms   peak_rss   final_rss
  asm no-GC       1097     133.9 MB   133.9 MB   (grows, never shrinks)
  asm naive GC    1431       1.1 MB     1.1 MB   (steady state)

124x less memory at a ~30% throughput cost. That is the number we
were guessing at before. Reproduce: make bench-gc.

Tests: 137 asm (no-GC) + 137 asm (GC) + 189 shared functional pass.
The two asm builds are tested independently via UNCOMMONLISP_BIN in
asm/test.sh; asm/Makefile now builds both and exposes a test-gc
target.
2026-04-18 09:34:51 -04:00
afb5616843 asm: native hash-set + benchmark — 15-21x over portable
Adds 6 hash-set builtins (make-hash-set, hash-set?, hash-set-add!,
hash-set-contains?, hash-set-size, hash-set->list). Same sentinel
scheme as hash-table but tag word = -2 (hash-table is -1, vector
is >= 0). One cons cell per entry (vs two for hash-table) since
a set stores keys only — that's where the speedup over the Scheme-
level vector-based ht-* lib comes from.

Benchmark (tests/bench-hashset.sh, via make bench-hashset),
N=5000, i5-8350U asm tier:

                portable   native   speedup
  insert        ~130 ms    ~7 ms    ~20x
  hit-lookup    ~125 ms    ~8 ms    ~15x
  miss-lookup   ~240 ms    ~12 ms   ~20x

Portable is the ht-* lib from proof-netspace-server-lib.lsp
(vectors + cons chains + modulo, pure Scheme). Native replaces
the Scheme-level bucket walk with an asm loop that dereferences
pairs directly — no env lookups, no frame building per iteration.

All 137 asm + 189 functional (Python + C) tests still green.
2026-04-18 06:15:21 -04:00
a9be071a7a native EML proof checker in Lumbda + Lean-vs-Lumbda benchmark
Addresses fox's framing: EML isn't a language design invariant; it's
a well-executed demonstration. Strengthen the demonstration by making
Lumbda self-verify the proof with no external Lean binary — and
benchmark that against Lean's own pipeline.

proof/eml_proof_in_lumbda.lsp (~150 lines, portable Scheme):

  - Term-rewriting engine: pattern variables (?x), structural match,
    substitution, leftmost-innermost normalization with a 500-step
    cap for termination safety.
  - Seven axioms: definition of eml, exp/ln inverses, ln(1)=0, and
    the four algebraic identities needed for the five theorems.
  - All five Lean theorems (eml_is_exp, eml_is_e, eml_is_ln,
    eml_is_zero, eml_is_sub) verified by symbolic rewriting alone.
    No numerical evaluation. Same abstract-exp/ln axioms Lean uses.

Full coverage: all 5 of 5 Lean theorems reproduce in Lumbda.
Cross-impl: 5/5 pass in Python --fast, C default, and asm.
(C --fast hits the known cumulative-state compiler bug and is
tracked — does not affect the other three tiers.)

tests/bench-proof.sh + `make bench-proof`:

  EML proof verification (best of 3 runs, i5-8350U):

    Lumbda Python --fast              363 ms
    Lumbda C (tree-walker)             42 ms
    Lumbda C --fast (bytecode VM)   crashes  (known bug)
    Lumbda asm                         29 ms  <-- fastest live check
    Lean 4 (cached replay)              1 ms  (artifact re-read)
    Lean 4 (cold rebuild)             374 ms  (fair end-to-end)

  Lumbda asm is 13× faster than Lean's cold rebuild at verifying
  the same five theorems. Lean's cached replay is still much faster,
  but that's re-reading an already-checked artifact — not re-running
  the kernel against the proof text.

Whitepaper §8.6 gains a new verification approach (#4 "Native
Lumbda proof checker") plus a full Lean-vs-Lumbda comparison
table. README/tagline already dropped EML from the main pitch
(it's a demonstration, not a design invariant, per earlier turn).

MOAD isolation is now the only spec-level claim in the subtitle.
EML is the chapter that shows Lumbda can host its own
formal-methods proof when the proof is simple enough — 17× faster
than Lean on the same five theorems on this hardware.
2026-04-17 19:40:20 -04:00
67e4fef85c bench targets + whitepaper reproducibility + MOAD cheat sheet citation
Every benchmark in the whitepaper now has a Makefile target and
each in-paper result is tagged with its reproduce command.

New / refactored Make targets:

  make bench              Python tree-walker vs bytecode (§6.1-6.3)
  make bench-3way         3-way Python/C/asm head-to-head  (§6.4)
  make bench-portal       portal save+load timings          (§7.5)
  make bench-portal-cross 3x3 cross-impl portal matrix      (§7.2)
  make bench-web          HTTP vs busybox / python http.server  (§11.3)
  make bench-rpc-chain    Python → C relay → asm chain      (§11.4)
  make bench-all          runs every bench above

bench-3way is a new script (tests/bench-3way.sh) that drives each
impl in its recommended high-performance mode and prints a clean
best-of-two comparison table matching §6.4.

Every script uses the six-layer safety envelope from CLAUDE.md
(ulimit -v + trap + timeout + explicit kill + pgrep verify).
Documented in the whitepaper's §6 Methodology block.

Whitepaper additions:

- §6 Methodology paragraph adds a "Reproducibility" block listing
  every Makefile target alongside the section it backs.
- §12 MOAD Audit now cites the canonical MOAD taxonomy:
    https://undefect.com/moad-cheat-sheet/
  (MOAD-0001 through MOAD-0005) so readers can look up the defect
  classes the paper references.
- §6.4, §7.2, §7.5, §11.3, §11.4 each end with a "Reproduce: make
  bench-<name>" pointer tying the number to the script that
  produces it.

Ran bench-3way on the i5-8350U:
  Python --fast: sum-to(100k)=555ms, sum-to(1M)=5038ms, ack(3,8)=18740ms
  C --fast:      sum-to(100k)= 27ms, sum-to(1M)= 255ms, ack(3,8)= 1465ms
  asm:           sum-to(100k)= 67ms, sum-to(1M)= 692ms, ack(3,8)= 2300ms

Matches the table in the paper (best-of-two).
2026-04-17 19:02:21 -04:00
5fb1f0cb17 Add benchmark dot diagrams showing performance differences
5 new diagrams (Graphviz DOT → PNG):
  benchmark-ack.dot      — ack(3,4) across all 5 tiers
  benchmark-sumto.dot    — sum-to(50k) across all 5 tiers
  benchmark-fib.dot      — fib(35) iterative across all 5 tiers
  benchmark-speedup.dot  — JIT speedup ratios (7x-784x)
  benchmark-binary-size.dot — 13KB asm vs 171KB C vs ~30MB Python

JIT: 0.19ms ack, 7x faster than CPython, 784x faster than Python VM.
Makefile docs target now auto-discovers all docs/*.dot files.
2026-04-16 13:01:32 -04:00
670487c01d Add architecture docs with dot diagrams, update Makefile and CLAUDE.md
4 architecture diagrams (Graphviz DOT → PNG):
  python-architecture.dot  — bytecode VM + continuations + portal
  c-architecture.dot       — tree-walker + VM + JIT tiers
  asm-architecture.dot     — syscalls-only, 13KB binary
  jit-pipeline.dot         — AST → x86_64 machine code flow

docs/README.md — full architecture docs with embedded diagrams
and performance summary across all implementations.

Makefile: add asm-repl, docs target, clean-docs. Header comments
document all targets and test suites.

CLAUDE.md: add "A diagram is worth 10,000 words" (russell@unturf.com),
implementation table, test suite inventory.

Assembly is 2.5-4x faster than C interpreter on recursive workloads.
JIT remains 33x faster than hand-written assembly.
2026-04-15 14:07:59 -04:00
a7239ea717 Add asm test suite: 75 tests (unit + integration + functional)
Unit tests (42): arithmetic, comparison, booleans, predicates,
  pairs/lists, and/or — each verifies expected output.
Integration tests (18): special forms, bindings, named-let,
  recursion, higher-order, closures.
Functional tests (15): fib(35), ack(3,4), TCO 100k depth,
  list processing, mutual recursion, closure state, display.

make test-all now runs: Python 571 + C 76 + asm 75 + functional 114.
All pass.
2026-04-15 13:44:36 -04:00
db2cd77c62 Add shared functional test suite: 114 tests, both implementations pass
tests/functional.lsp — single .lsp file, runs identically in Python and C.
Covers: arithmetic, comparison, booleans, pairs, lists, strings, characters,
vectors, hash tables, control flow, let/lambda/closures, do loops, define,
recursion, TCO (100k depth), quasiquote, macros, type predicates, call/cc,
error handling, mergesort, higher-order programs.

Fixed C call/cc: proper escape continuations via setjmp/longjmp.

make test-all runs: Python unit (571) + C unit (58) + shared functional (114).
2026-04-14 15:21:17 -04:00
fc9eb5350c Add C implementation: 7,429 lines, 58 tests, identical output
Complete C port of the Scheme interpreter. Same .lsp files run in
both Python and C with identical output.

Architecture:
- NaN-boxed 64-bit values (zero-alloc numbers)
- Hash-map environments with parent chain + global shortcut
- Interned symbols
- TCO via explicit loop (eval) and TAIL_CALL/SELF_TAIL_CALL (VM)
- Bytecode compiler with all opcodes including superinstructions
- 58 unit + integration tests

Makefile targets:
  make test-all    run Python (571) + C (58) tests
  make examples    run examples in both, compare output
  make friction    benchmark same .lsp in Python vs C
  make c-build     build C interpreter
  make c-test      run C tests
  make c-repl      C REPL
2026-04-14 14:55:17 -04:00
4d8cd9f1f8 Add whitepaper: Feedback Is All You Need
Permacomputer whitepaper covering uncommonlisp architecture,
bytecode VM, continuations, portal, EML universality proof,
and benchmarks. AGPL-3.0-only. Builds via make whitepaper
using a local venv (no sudo).
2026-04-14 13:32:42 -04:00
f584ad76f2 Add auto-compile, VM optimization, disassemble, call/cc compilation
- auto-compile! parameter: compile defines on the fly for zero-effort speedup
- VM optimization: local aliases, inlined truthiness checks (~15% faster)
- disassemble builtin: human-readable bytecode listing
- call/cc compiled natively in VM (escape-only, no longer falls back to eval)
- Makefile: add lint, bench-verbose, clean targets
- 518 tests green
2026-04-13 14:49:32 -04:00
f72190d2dc Initial implementation of uncommonlisp
Single-file Scheme-like Lisp interpreter in Python with:
- TCO via explicit while loop (no Python stack overflow at any depth)
- syntax-rules with ellipsis for hygienic macros
- define-macro for procedural macros
- Full numeric tower, strings, chars, vectors, hash tables
- SRFI-1 list library
- call/cc (escape continuations), values, dynamic-wind, guard
- Python interop (py-eval, py-import, py-call, py-attr)
- 396 passing unit/integration/functional tests
- stdlib.lsp with 60+ utility functions
- Benchmark suite vs CPython baseline
2026-04-13 11:01:04 -04:00