comptime VM: memory = arena of stable host allocations; Addr = real host pointer (Phase 4D.0)
Replace the growable ArrayList(u8) flat buffer (reallocs/MOVES on growth) with a std.heap.ArenaAllocator. Each allocBytes is a separate arena allocation that never moves and is freed wholesale on deinit -- no per-object free, no cap, no fixed buffer. Addr is now the allocation's ABSOLUTE host pointer (@intFromPtr), not an offset, so a flat-memory pointer and an FFI-returned host pointer are the same kind of value -- the FFI bridge (4D.1) passes them to/from libc with zero translation and no per-call pinning (the moving-buffer hazard is gone by construction). readWord/writeWord/bytes deref the absolute pointer with a null-check bail (the malformed-IR / null-deref safety contract). Dropped the offset-based upper-bounds check (can't bound an absolute pointer; Frame.bad_ref still catches the dominant malformed-IR vector) and the test-only mark/reset (arena has no reset-to-mark; the VM never used them outside tests). 697/0 both gates + all unit tests (rewrote the two Machine tests). Pure refactor, no comptime behavior change.
This commit is contained in:
@@ -352,6 +352,23 @@ when reached (sentinels or accessor fns; see the design doc Risks).
|
||||
`List` growth; orthogonal, see `current/CHECKPOINT-METATYPE.md`.)
|
||||
|
||||
## Log
|
||||
- **Phase 4D.0 (VM plan) — comptime VM memory = an ARENA of stable host allocations; `Addr` = real host pointer (2026-06-18).**
|
||||
Replaced the growable `ArrayList(u8)` flat buffer (which reallocs/MOVES on growth) with a
|
||||
`std.heap.ArenaAllocator`: each `allocBytes` is a separate arena allocation that never moves and
|
||||
is freed wholesale on `deinit` (no per-object free, no cap, no fixed buffer). **`Addr` is now the
|
||||
allocation's absolute host pointer** (`@intFromPtr`), not an offset — so a flat-memory pointer and
|
||||
an FFI-returned host pointer are the SAME kind of value, and the FFI bridge (4D.1) can pass them
|
||||
to/from libc with ZERO translation and no per-call pinning (the original moving-buffer hazard is
|
||||
gone by construction). `Machine.readWord/writeWord/bytes` deref the absolute pointer directly,
|
||||
keeping the null-check bail (the malformed-IR / null-deref safety contract). Dropped the
|
||||
offset-based upper-bounds check (can't bound an absolute pointer; the `Frame.bad_ref` guard still
|
||||
catches the dominant malformed-IR vector) and the test-only `mark`/`reset` (the arena has no
|
||||
cheap reset-to-mark; the VM never used them outside tests). Decision rationale (user): use a
|
||||
GPA-like allocator, no artificial buffer limits. **697/0 BOTH gates + all unit tests** (rewrote
|
||||
the two Machine tests: null-deref bail + arena-stability-across-grows). Pure refactor, no
|
||||
comptime behavior change. **Next (4D.1):** extern-call dispatch in `Vm.invoke` — marshal args
|
||||
(scalars by value, pointers as the host pointer they already are), call via `host_ffi`
|
||||
trampolines, return scalars/pointers; a new `#run` libc example as the corpus guard.
|
||||
- **Phase 4A.1 (VM plan) — `box_any`/`unbox_any` on the VM + `.any` as a 16-byte aggregate (2026-06-18).**
|
||||
Ported the Any-boxing conversion pair: `box_any` allocates the 16-byte `{ type_tag@0, value@8 }`
|
||||
box (tag = source TypeId index, matching the legacy comptime interp), writing a word source's
|
||||
|
||||
Reference in New Issue
Block a user