code wiki / (root) / nx_arena.nx

nx_arena.nx

buildroot/runtime/nx_arena.nx

5171 B125 linesdepth 3pulls 4 transitivereach 0 importersview sourcekind tooltopic arena
docsdependenciesstructsconstsfunctions

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

nx_arena_types.nx nx_syscalls.nx nx_assert.nx nx_arena.nx

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

main nx_arena_new nx_assert sys_write nx_puts_err sys_write ↻ sys_mmap nx_arena_init nx_arena_used nx_arena_alloc nx_arena_align_up nx_arena_alloc_zero nx_arena_alloc ↻ nx_arena_oom_count nx_arena_reset nx_arena_alloc_count

structs

none

consts

48const K_MAGIC_1024: i64 = 1024

functions

56func nx_arena_new(cap: i64) -> *NxArena
called by 1: main calls 3: nx_assertsys_mmapnx_arena_init
67func main() -> i64