Skip to content
CryoCryo home
Stdliballoc

arena

import std::alloc::arena; · source

Types

Arena

type struct Arena {
    head:       Chunk*;
    current:    Chunk*;
    chunk_size: u64;

    static new() -> Arena;
    static with_chunk_size(chunk_size: u64) -> Arena;
    reset(mut &this) -> void;
    capacity(&this) -> u64;
    used(&this) -> u64;
    bump(mut &this, size: u64, align: u64) -> void*;
    owns(&this, ptr: void*) -> boolean;
    grow(mut &this, ptr: void*, old_size: u64, new_size: u64, align: u64) -> void*;
    release(mut &this) -> void;
}

Bump allocation, bulk release. An arena hands out memory by bumping an offset into a chunk. Allocation is O(1), individual deallocation is unsupported, and everything comes back at once through reset (keep the chunks, reuse the space) or drop (return the chunks to the OS).

The shape it fits is "allocate a pile of things with related lifetimes, then throw them away together" — compiler passes, per-request handlers, parse trees. Long-lived caches are not that shape.

import std::alloc::arena;

mut a: Arena = Arena::new();
mut nodes: Array<Node, Arena> = Array::<Node, Arena>::new_in(a);
// ... build the tree ...
a.reset();      // everything above is invalid now; capacity is reused

Repeated reset is where an arena earns its keep — the same memory gets reused instead of round-tripping through the platform allocator.

Each chunk's data buffer is mapped straight from the OS, so releasing it returns the pages immediately and RSS drops at the call, with none of the main-heap retention you get from freeing many small malloc blocks. The mapping is demand-paged, so untouched pages cost nothing and a small arena stays cheap despite the 1 MiB nominal chunk.

Properties

PropertyType
headChunk*
currentChunk*
chunk_sizeu64

Constructors

static new() -> Arena;

Create an arena whose chunks are DEFAULT_CHUNK_SIZE bytes each.

static with_chunk_size(chunk_size: u64) -> Arena;

Create an arena with a custom chunk size. Requests larger than chunk_size get their own chunk sized to fit, so the choice is a hint about typical allocation size, not a hard cap.

Methods

reset(mut &this) -> void;

Reset every chunk's high-water mark to zero, making the arena's full capacity available for re-allocation without releasing the underlying chunks back to the system allocator. This is the amortizing power of an arena: repeated reset reuses the same memory instead of round-tripping through malloc/free.

capacity(&this) -> u64;

Total bytes currently held in chunks (including unused tail).

used(&this) -> u64;

Bytes handed out so far; this is the high-water mark for the arena.

bump(mut &this, size: u64, align: u64) -> void*;

Hand out size bytes aligned to align from the arena. Returns null on out-of-memory or a zero-sized request. Marches through the chunk list (reusing chunks emptied by reset) before growing.

owns(&this, ptr: void*) -> boolean;

True when ptr lies inside any chunk this arena owns. Used by GlobalAlloc's free/realloc routing to recognise arena-backed pointers so they are never handed to libc free. Range-scan of the chunk list (mirrors capacity); a pointer one-past-the-end of a chunk is intentionally excluded.

grow(mut &this, ptr: void*, old_size: u64, new_size: u64, align: u64) -> void*;

Grow (or shrink) a block previously handed out by bump. If ptr is the most-recent allocation in the frontier chunk and that chunk has room for the delta, the block is extended in place and the same pointer returned - this kills realloc-stranding for monotonic single-growers (e.g. a TypeArena.types vector that only ever grows). Otherwise a fresh block is allocated and the old contents copied; the old block is stranded until reset. Returns null on out-of-memory.

release(mut &this) -> void;

Release every chunk back to the platform allocator. Invoked by the Drop impl in alloc::arena_alloc; exposed as an inherent method so the drop logic lives next to the allocation logic.

Trait implementations

implement trait Allocator for struct Arena
std::alloc::arena_alloc
implement trait Drop for struct Arena
std::alloc::arena_alloc

Arena implements Allocator, so it drops into any allocator-generic type. Its deallocate is a no-op by design; reallocate tries grow first.

Constants

const DEFAULT_CHUNK_SIZE: u64 = 1048576;