render3d's stream_new holds its pool through a local (`let live = s.chunks; push(live, new Chunk)`): the flow edge from s.chunks to live carried ESC to nothing, the Chunk records were LOCAL, and the arena reset them under the stream - the row and horse scenarios' crash at 0xdddd... in fn_stream_update. An ESC class is now HEAP too, so every alias of kept memory is, and a value stored through it is kept. Bidirectional alias edges were tried first and over-kept through returns (el_place, rim). - examples/lang/arena_alias.ludic: the stream_new shape; poisoned it read 3 3000, now 3 1518 - examples/modules/alloc_ok_private.ludic: @alloc_ok on a module's private function and on a statement in its private generic, declared at run time (it already passes: a guard) - the game: frame_allocs, frame_keeps, owned_leaks 0; the lab builds under `arena strict`; the row scenario poisoned (R3D_ARENA_CHECK=1, 2400 frames) runs clean, bad 0 kept 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
28 lines
1.1 KiB
Text
28 lines
1.1 KiB
Text
# arena_alias.ludic - a record whose list is filled through a local alias (`let live = s.cells`, as
|
|
# render3d's stream_new fills its chunk pool) and which a pool then keeps. After `let x = y`, x and y
|
|
# are one piece of memory: what is stored through x is kept when y is. Built with --arena and
|
|
# poisoned on every reset it prints `3 1518`, as the heap does.
|
|
program ArenaAlias {
|
|
property Cell { v: int = 0 }
|
|
property Holder { cells: []Cell = new []Cell }
|
|
property Pool { all: []Holder = new []Holder }
|
|
function make(p: Pool, f: int) -> void {
|
|
let s = new Holder
|
|
let live = s.cells
|
|
for i in 0 .. 3 { push(live, new Cell { v: f + i }) }
|
|
push(p.all, s)
|
|
}
|
|
function step(p: Pool, f: int) -> void { if f == 500 - 1 or f == 5 { make(p, f) } }
|
|
entry {
|
|
let p = new Pool
|
|
for f in 0 .. 500 {
|
|
step(p, f)
|
|
Mem.frame()
|
|
}
|
|
var sum = 0
|
|
for i in 0 .. len(p.all[0].cells) { sum += p.all[0].cells[i].v }
|
|
let h = p.all[len(p.all) - 1]
|
|
for i in 0 .. len(h.cells) { sum += h.cells[i].v }
|
|
print(`{len(p.all[0].cells)} {sum}`)
|
|
}
|
|
}
|