Skip to main content

47  mem standard library

The mem module provides unified, explicit memory management: low-level byte operations, regional bump arenas, and fixed-capacity object pools.

#use mem

47.1 Low-level memory utilities

Function Signature Description
mem::copy Addr, Addr, Int => () Copies bytes count from source to destination
mem::move Addr, Addr, Int => () Copies bytes count with support for overlap
mem::zero Addr, Int => () Fills memory range with zeros
mem::set Addr, Int, Int => () Fills memory range with specified byte value
mem::align_forward Addr, Int => Addr Advances address to meet alignment requirement
mem::is_aligned Addr, Int => <> Checks whether address satisfies alignment
mem::index_byte Addr, Int, Int => < Int | > memchr(3): offset of the first byte in [p, p + len), or <--> if absent

47.2 Regional bump arenas

Arenas provide allocation without per-object free overhead. All allocations within an arena are freed simultaneously when the arena is reset or destroyed.

#type Arena (raw: Addr, cap: Int)
#type ArenaStats (bytes_allocated: Int, num_chunks: Int, cap: Int)
Function Signature Description
mem::arena Int => Arena Creates an arena with initial chunk capacity (bytes)
mem::arena_default () => Arena Creates an arena with default 64 MB chunk capacity
mem::alloc Arena, Int => Addr Allocates uninitialized memory of given byte size
mem::reset Arena => () Rewinds arena offset to zero, retaining chunks
mem::destroy Arena => () Frees all backing chunks and arena descriptor
mem::stats Arena => ArenaStats Retrieves allocation metrics and chunk counts
mem::with Arena, (() => ()) => () Runs action with arena set as ambient allocator
#use mem

ar = mem::arena(1024)
buf = mem::alloc(ar, 256)
// ... use buf ...
mem::destroy(ar)

47.3 Fixed-capacity object pools

Pools manage uniform, fixed-size element allocations with \(O(1)\) allocation and deallocation.

#type Pool (buffer: Addr, free_stack: Addr, active: Addr, state: Addr,
   elem_size: Int, capacity: Int)
Function Signature Description
mem::pool Int, Int => Pool Creates pool: mem::pool(elem_size, capacity)
mem::pool_alloc Pool => < Addr | > Allocates slot: <+ Addr +> or <--> on full
mem::pool_free Pool, Addr => <> Frees slot: <+> on success, <-> on error
mem::pool_count Pool => Int Number of currently active allocated slots
mem::pool_capacity Pool => Int Maximum capacity of the pool
mem::pool_for_each Pool, (Addr => ()) => () Iterates over each active allocated slot
mem::pool_destroy Pool => () Releases pool memory buffer
#use mem
#use io

// Create pool with element size 16 bytes and capacity of 4 slots:
p = mem::pool(16, 4)

io::out $ mem::pool_capacity(p) // 4
io::out $ mem::pool_count(p)    // 0

slot = mem::pool_alloc(p)
slot
   | addr =>
      @[addr] = 42
      io::out $ @[addr Int]
      freed = mem::pool_free(p, addr)
      freed | io::out("freed") | io::out("invalid")
   | io::out("pool exhausted")

mem::pool_destroy(p)