193 lines
4.6 KiB
Markdown
193 lines
4.6 KiB
Markdown
# Memory Model
|
|
|
|
Domain: VM memory model
|
|
Function: normative
|
|
|
|
This chapter defines the VM memory architecture: stack, heap, handles, object layout, allocation, and garbage collection.
|
|
|
|
It intentionally focuses on VM-managed memory.
|
|
|
|
Host-owned memory surfaces such as asset banks and persistent save storage are covered by their own domain specs and by the host ABI docs.
|
|
|
|
## 1 Overview
|
|
|
|
The PVM memory model is based on:
|
|
|
|
- stack-resident execution values;
|
|
- heap-resident objects;
|
|
- validated handles for indirect heap access;
|
|
- GC-managed object lifetime.
|
|
|
|
## 2 Stack Memory
|
|
|
|
The stack stores transient execution values and frame-scoped data.
|
|
|
|
### Stack value types
|
|
|
|
The stack may contain:
|
|
|
|
- primitive values;
|
|
- built-in fixed-layout values;
|
|
- heap handles;
|
|
- tuple-shaped multi-return values.
|
|
|
|
See [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) for the slot/value model.
|
|
|
|
### Stack properties
|
|
|
|
- stack values are local to execution state;
|
|
- stack discipline is verifier-sensitive;
|
|
- stack underflow and invalid access are traps.
|
|
|
|
## 3 Heap Memory
|
|
|
|
The heap stores runtime objects that require identity and reachability tracking.
|
|
|
|
### Heap characteristics
|
|
|
|
- user objects live in the heap;
|
|
- arrays and closures live in the heap;
|
|
- heap access is indirect through handles;
|
|
- the collector is non-moving in the baseline model.
|
|
|
|
## 4 Handles and Gate Table
|
|
|
|
All heap objects are accessed via handles.
|
|
|
|
A conceptual handle:
|
|
|
|
```
|
|
handle = { index, generation }
|
|
```
|
|
|
|
Conceptual gate entry:
|
|
|
|
```
|
|
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:
|
|
|
|
- the index must exist;
|
|
- the generation must match;
|
|
- invalid or stale handles trap.
|
|
|
|
This prevents:
|
|
|
|
- use-after-free;
|
|
- stale references;
|
|
- hidden raw memory access.
|
|
|
|
## 5 Object Layout
|
|
|
|
Heap objects use explicit, implementation-visible layout rules.
|
|
|
|
Conceptual form:
|
|
|
|
```
|
|
Object {
|
|
type_id
|
|
field_0
|
|
field_1
|
|
...
|
|
}
|
|
```
|
|
|
|
Properties:
|
|
|
|
- fields are stored in slot order;
|
|
- there is no raw pointer arithmetic in the VM model;
|
|
- layout rules are explicit and verifier/runtime-friendly.
|
|
|
|
Closures and coroutine-owned state may build on top of this memory model, but their behavioral rules are documented separately:
|
|
|
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md)
|
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md)
|
|
|
|
## 6 Garbage Collection
|
|
|
|
The PVM uses a **mark-sweep collector**.
|
|
|
|
### GC properties
|
|
|
|
- non-moving in the baseline model;
|
|
- 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-owned execution state;
|
|
- closure environments;
|
|
- host-held roots where the host legally retains VM heap references.
|
|
|
|
## 7 Allocation and Deallocation
|
|
|
|
### Allocation
|
|
|
|
Heap allocation conceptually performs:
|
|
|
|
1. reserve object storage;
|
|
2. create or reuse gate entry;
|
|
3. return validated handle.
|
|
|
|
If allocation fails:
|
|
|
|
- the VM may trigger GC;
|
|
- if pressure remains unresolved, allocation may trap or fail according to the runtime contract.
|
|
|
|
### Deallocation
|
|
|
|
Objects are reclaimed by GC.
|
|
|
|
When reclaimed:
|
|
|
|
- the gate is marked dead;
|
|
- the generation is incremented;
|
|
- storage becomes reusable.
|
|
|
|
## 8 Memory Safety Rules
|
|
|
|
The VM enforces:
|
|
|
|
1. all heap access goes through handles;
|
|
2. generation checks validate handle freshness;
|
|
3. object and field access is bounds-checked;
|
|
4. there is no guest-visible raw pointer arithmetic;
|
|
5. stack discipline remains verifier-constrained.
|
|
|
|
Any violation results in a trap or rejected program image.
|
|
|
|
## 9 Relationship to Other Specs
|
|
|
|
- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) defines stack values and tuple/call-slot semantics.
|
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md) defines closure function values.
|
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine state and scheduling behavior.
|
|
- [`15-asset-management.md`](15-asset-management.md) defines asset-bank surfaces outside VM heap ownership.
|
|
- [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md) defines save storage outside VM heap ownership.
|
|
- [`16a-syscall-policies.md`](16a-syscall-policies.md) defines host-root rules and host/heap interaction policy.
|