5.6 KiB

< Back | Summary | Next >

🧠 Memory Model

This chapter defines the memory architecture of the Prometeu Virtual Machine (PVM). It describes the stack, heap, handles, object layout, garbage collection, and interaction with host-owned memory such as asset banks.

The memory model is designed to be:

  • deterministic
  • safe
  • simple to verify
  • suitable for real-time 2D games

1 Overview

The PVM uses a split memory model:

  1. Stack memory

    • used for temporary values
    • function arguments
    • multi-return tuples
  2. Heap memory

    • used for all user-defined objects
    • accessed only through handles
  3. Host-owned memory

    • asset banks
    • audio buffers
    • framebuffers
    • not part of the VM heap

2 Stack Memory

The stack is used for:

  • primitive values
  • built-in value types
  • temporary results
  • function arguments
  • tuple returns

Stack value types

Type Description
int 64-bit integer
bool Boolean
float 64-bit float
vec2 2D vector
color Packed color
pixel Position + color
handle Reference to heap object

All stack values are:

  • fixed-size
  • copied by value
  • never directly reference raw memory

Stack properties

  • Stack is bounded and verified.
  • Stack depth must be consistent across all control paths.
  • Stack never stores raw pointers.

3 Tuples (Stack-Only Aggregates)

Tuples are used for multi-value returns.

Tuple rules

  • Tuples exist only on the stack.
  • Maximum tuple arity: 6 slots.
  • Tuples are not heap objects by default.
  • To persist a tuple, it must be explicitly boxed into a heap object.

Example

Function returning two values:

fn position(): (int, int)

At runtime:

stack top → [x, y]

4 Heap Memory

All user-defined objects live in the heap.

Heap characteristics

  • Linear slot-based storage.
  • Objects are fixed-layout blocks.
  • No raw pointer access.
  • No inheritance at memory level.

Heap objects include:

  • user structs/classes
  • arrays
  • strings
  • closures
  • boxed tuples (optional)

5 Handles and Gate Table

All heap objects are accessed via handles.

A handle is defined as:

handle = { index, generation }

The VM maintains a gate table:

GateEntry {
    alive: bool
    generation: u32
    base: usize
    slots: u32
    type_id: u32
}

Handle safety

When an object is freed:

  • alive becomes false
  • generation is incremented

When a handle is used:

  • index must exist
  • generation must match

Otherwise, the VM traps.

This prevents:

  • use-after-free
  • stale references

6 Object Layout

Heap objects have a simple, fixed layout:

Object {
    type_id
    field_0
    field_1
    ...
}

Properties:

  • Fields are stored in slot order.
  • No hidden base classes.
  • No pointer arithmetic.

Traits and method dispatch are resolved:

  • statically by the compiler, or
  • via vtable handles (if dynamic dispatch is used).

7 Closures

Closures are heap objects.

Layout:

Closure {
    func_id
    capture_count
    captures[]
}

Captures may be:

  • copied values
  • handles to heap objects

Closure environments are part of the GC root set.


8 Coroutine Memory

Each coroutine owns its own stacks:

Coroutine {
    call_stack
    operand_stack
    state
}

All coroutine stacks are included in the GC root set.

Coroutines do not share stacks or frames.


9 Garbage Collection

The PVM uses a mark-sweep collector.

GC properties

  • Non-moving (no compaction in v1).
  • Runs only at safepoints.
  • Primary safepoint: FRAME_SYNC.

GC triggers

GC may run when:

  • heap usage exceeds threshold
  • allocation pressure is high

Root set

The collector marks from:

  • operand stack
  • call stack frames
  • global variables
  • coroutine stacks
  • closure environments
  • host-held handles

10 Allocation and Deallocation

Allocation

Heap allocation:

  1. VM reserves a slot block.
  2. A gate entry is created.
  3. A handle is returned.

If allocation fails:

  • VM may trigger GC.
  • If still failing, a trap occurs.

Deallocation

Objects are freed only by the GC.

When freed:

  • gate is marked dead
  • generation is incremented
  • memory becomes available via free list

11 Host-Owned Memory (Asset Banks)

Asset memory is not part of the VM heap.

It is managed by the firmware.

Examples:

  • tilebanks
  • audio sample banks
  • sprite sheets

Properties

  • VM cannot access asset memory directly.
  • Access occurs only through syscalls.
  • Asset memory is not scanned by GC.

12 Save Memory (MEMCARD)

Save memory is a host-managed persistent storage area.

Properties:

  • fixed size
  • accessed only via syscalls
  • not part of the VM heap
  • not scanned by GC

13 Memory Safety Rules

The VM enforces:

  1. All heap access via handles.
  2. Generation checks on every handle use.
  3. Bounds checking on object fields.
  4. No raw pointer arithmetic.
  5. Verified stack discipline.

Any violation results in a trap.


14 Summary

The PVM memory model is based on:

  • stack-only primitive and tuple values
  • heap-only user objects
  • generation-based handles
  • deterministic GC at frame safepoints
  • strict separation between VM heap and host memory

This design ensures:

  • predictable performance
  • memory safety
  • simple verification
  • suitability for real-time game workloads.

< Back | Summary | Next >