nx_arena.nx
buildroot/runtime/nx_arena.nx
about
nx_arena.nx -- bump-pointer arena allocator.
Today every "give me a buffer" inside the runtime calls sys_mmap.
On Linux that mmaps a fresh page (4 KiB) per allocation -- fine
for a handful of structs, terrible when, e.g., the parser allocs
thousands of small Token / IR-value records. Page fragmentation
+ syscall overhead silently dominate.
nx_arena solves the small-allocation problem the right way for a
bottom-up systems language: pre-mmap N pages, then hand out
aligned chunks via a bump pointer. Reset frees the whole arena
at once (perfect for "scope-bound" allocations like a parse pass).
This file is the CONVENIENCE layer: nx_arena_new() does the
sys_mmap so callers that don't care about syscall ABI portability
can just call it. Callers that need to compose nx_arena with a
DIFFERENT syscall layer (e.g., nx_syscalls_x86_64.nx for native
exec) import nx_arena_types.nx directly + provide their own
backing buffer via nx_arena_init. See cardinal user-owns-every-bit
+ four-pillar fix 2026-05-16.
Why now (decade-horizon framing):
* Determinism -- predictable allocation pattern means the F6
manifest stays stable across alloc-pattern changes upstream.
* Bug surface -- one allocator instead of N call sites means
one place to add poisoning, guard pages, alloc-tracing,
fuzz instrumentation.
* Migration target -- when MemCap (Phase B) lands, every
arena_alloc returns a MemCap with bounds prefilled. All
existing code transparently gains capability bounds-check.
Not yet (deferred):
* Multiple chunks (grow when full). v0.0.1 single chunk.
* Free-list or per-size pool. v0.0.1 bump only.
* Guard pages between large allocs. Add when first reproed
OOB hits arena.
* Threading. v0.0.1 single producer.
dependencies 3 imports · 0 importers
imports: nx_arena_types.nxnx_syscalls.nxnx_assert.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 48 | const K_MAGIC_1024: i64 = 1024 |
functions
| 56 | func nx_arena_new(cap: i64) -> *NxArena |
| 67 | func main() -> i64 |