An allocation registry answers what is at an address, without tagging a struct
This commit is contained in:
parent
324d1c6c60
commit
fc6b0f5aba
36
NEXT.md
36
NEXT.md
@ -20,6 +20,42 @@ This matters more here than in most Lisps because the intended use is a **game l
|
||||
skip a frame and carry on rather than die — exactly the case where a non-idempotent mutation bites. Write it into
|
||||
`conditions.org` and `spec-conditions.md`'s prose, and into `web/index.html` beside the restart documentation.
|
||||
|
||||
## Queued: a dev-build allocation registry — address to type
|
||||
|
||||
Raised in conversation and wanted. **What it is:** in a dev build only, every allocation records what type it was
|
||||
made for. Address → type becomes a lookup.
|
||||
|
||||
**Why it is possible without tagging anything.** A Flan struct is exactly its C layout with no header and no tag word
|
||||
— deliberately, and it is what makes structs free and the FFI work. So "what is at this address" is normally
|
||||
unanswerable at run time, and a tag cannot be added without breaking raylib. The registry sidesteps that: the
|
||||
*allocator* knows the type at the moment it hands out memory, so nothing about the value's layout has to change.
|
||||
Costs nothing in a release build.
|
||||
|
||||
**What it buys, in rough order of value:**
|
||||
|
||||
- **Following a pointer.** `(Ptr T)` renders as `<ptr>` today and stops there. With a registry the inspector follows
|
||||
it and renders what is actually at the other end.
|
||||
- **Use-after-free that names what died.** The address is in the registry and marked dead: *"this was an Enemy, freed
|
||||
at frame 412"* instead of garbage, a crash, or silence.
|
||||
- Point at any heap address and get a typed rendering rather than bytes.
|
||||
- **A memory breakdown by type** — how many bytes are Enemies, how many are strings. A real profiling tool for a game.
|
||||
- **Leak attribution at exit**, which generalises the debug tracking allocator already queued for counting forgotten
|
||||
textures.
|
||||
- It closes the **arena hole Valgrind found**: releasing a region could mark everything in it dead, where today the
|
||||
bytes stay quietly readable because `free-all` is retain-capacity and memcheck is never told.
|
||||
|
||||
**What it does not cover, and does not need to:** stack locals and globals, which the shadow stack and the static type
|
||||
table already answer by name.
|
||||
|
||||
**The cost to watch, and it is the design question.** An arena allocation is a bump pointer — close to free — and a
|
||||
registry insert per allocation could easily cost more than the allocation itself, in a loop that runs every frame.
|
||||
Mitigations to weigh: record per *region* rather than per allocation; record ranges rather than addresses; or make the
|
||||
registry opt-in per allocator so a frame arena can decline it. Decide this before building, because it determines
|
||||
whether the feature is usable in the loop it is most wanted in.
|
||||
|
||||
**Note on classes:** `defclass` instances will carry shape metadata by design, so they get identification for free and
|
||||
do not need the registry. This is for plain structs, `Vec`, `Map` and pool storage.
|
||||
|
||||
## Picked up first, 2026-09-13
|
||||
|
||||
Three things, in order. The first two are one line each and unblock a real game.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user