353 lines
5.6 KiB
Markdown

< [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >
# 🧠 **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](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >