/* Bench-only bump allocator stub. * * Used by `ail build --alloc=bump` (Bench iter) to A/B compare AILang * binaries against the default Boehm-GC build. The whole runtime is a * 256 MB statically-allocated arena and a single bump pointer; there * is no `free`, no scan, no anything. If the workload exceeds 256 MB * we abort — this is bench code, the right response to overflow is to * notice and pick a smaller workload. * * The signature mirrors `GC_malloc` from libgc: `void *bump_malloc(size_t)`. * The codegen replaces every `call ptr @GC_malloc` with * `call ptr @bump_malloc` when `--alloc=bump` is set, so the AILang IR * is otherwise byte-identical between the two strategies. */ #include #include #include #include #define ARENA_BYTES (256ul * 1024ul * 1024ul) static uint8_t arena[ARENA_BYTES]; static size_t cursor = 0; void *bump_malloc(size_t n) { /* Align bump pointer up to 8 bytes — AILang's allocations are all * 8-byte aligned (tag + 8-byte fields, env pointers, closure pairs * of two `ptr`s). Matches the alignment Boehm gives us. */ size_t aligned = (cursor + 7ul) & ~((size_t)7ul); if (aligned + n > ARENA_BYTES) { fprintf(stderr, "bump_malloc: arena exhausted (cursor=%zu, requested=%zu, arena=%zu)\n", aligned, n, (size_t)ARENA_BYTES); abort(); } void *p = (void *)(arena + aligned); cursor = aligned + n; return p; }