examples: lisp — chunked bump arena for value/env cells
Replaces rt_alloc-per-cell (one 4 KiB mmap each) with arena_alloc over 64 KiB chunks. test_huge peak under massif --pages-as-heap=yes drops from ~525 MB to ~253 MB. Same lifetime semantics; remaining bulk is per-call append() in eval's arg slice (rt_ensure still mmaps page-per-call).
This commit is contained in:
@@ -115,14 +115,17 @@ env where `od?` is unbound; the tie-back only adds the self-binding.
|
||||
|
||||
## Interpreter limitations (design, not bug)
|
||||
|
||||
- **No GC.** Every cons / value / env frame is `mmap`'d via
|
||||
`rt_alloc` and never reclaimed. A long REPL session leaks until
|
||||
the process exits. The test_huge demo peaks at ~595 MB under
|
||||
`--pages-as-heap=yes`. Per-top-level-form arena reset would cut
|
||||
this by ~100× — see the closing note in `repl()` for the hook
|
||||
point. Note: `rt_alloc` is one mmap syscall per call returning a
|
||||
whole 4KB page, so even tail-recursive loops are bottlenecked on
|
||||
allocation, not on Lisp work — `(spin 100000 0)` runs in ~4s.
|
||||
- **No GC.** Cons / value / env cells come from a single bump-
|
||||
pointer arena (`arena_alloc`, 64 KiB chunks chained via `os.alloc`).
|
||||
The arena never reclaims — long REPL sessions still leak — but
|
||||
cells pack tightly instead of one cell per 4 KiB mmap. test_huge
|
||||
peaks at ~253 MB under `--pages-as-heap=yes`, down from ~525 MB
|
||||
pre-arena. The remaining bulk is `append(xs, av)` in eval's arg
|
||||
loop: every apply allocates a fresh `[]*value` through `rt_ensure`,
|
||||
which still hits `rt_alloc` page-per-call. Per-top-level-form
|
||||
arena reset (perm/trans split + Cheney promote on define/set!) is
|
||||
the next step — see the closing note in `repl()` for the hook
|
||||
point.
|
||||
- **No bigints.** `i64` wraps silently on overflow. `(fact 21)`
|
||||
rolls over.
|
||||
- **Float printing is fixed `%.6f`.** `1.0` prints as `1.000000`.
|
||||
|
||||
Reference in New Issue
Block a user