Memory Model¶
BearVM exposes two heap allocation strategies directly in the IR: manual allocation and arena allocation.
Manual Allocation¶
alloc allocates memory on the heap. The argument is either a byte size
or a struct type name:
%buf = alloc 16
%p = alloc Person
Allocated memory is zero-initialised. The caller is responsible for freeing
it with free:
free %buf
free %p
Failing to call free leaks the memory. Using a pointer after freeing it
is undefined behaviour.
Working with Heap-Allocated Structs¶
To write to a heap-allocated struct, get a reference to the field with
get_field_ref, then use store:
struct Person {
age: int
score: int
}
@main {
%p = alloc Person
%age_ref = get_field_ref %p, age
store %age_ref, 42
%age_val = load %age_ref
call puts(%age_val)
free %p
ret 0
}
A struct can also be initialised in one step using a struct literal with
store:
%p_ptr = alloc Person
store %p_ptr, { name: "Alice", age: 25 }
Working with Arrays¶
Arrays are allocated with alloc_array. Elements are accessed by index
using get_index_ref:
%arr = alloc_array int, 5
%i = const 0
; write: store each index with its own value
%elem_ptr = get_index_ref %arr, %i
store %elem_ptr, %i
; read
%val = load %elem_ptr
free %arr
Accessing an index outside the allocated length raises IndexOutOfBounds.
Arena Allocation¶
An arena groups allocations together so they can all be freed in one operation. This is useful when a set of allocations share the same lifetime.
Create an arena with arena_create, allocate from it with
arena_alloc, and release everything at once with arena_destroy:
@test_arena {
%arena = arena_create
%a = arena_alloc %arena, 64
%b = arena_alloc %arena, 128
%c = arena_alloc %arena, 32
arena_destroy %arena
ret 0
}
Individual arena allocations cannot be freed. All memory belonging to an
arena is released when arena_destroy is called.
Using an invalid arena ID raises InvalidArena.
Choosing Between Manual and Arena Allocation¶
Use manual allocation when individual objects have independent lifetimes and need to be freed separately.
Use arena allocation when a group of objects all become unreachable at the
same point. A single arena_destroy is cheaper and less error-prone than
calling free on each individual allocation.