Merge branch 'lang/memory-fence' into lang/leaks2
# Conflicts: # selfhost/ludicc.seed.ll # selfhost/ludicc.win.seed.ll # tools/ludic-cli/test.ludic
This commit is contained in:
commit
84155274c4
32 changed files with 1425 additions and 111 deletions
32
examples/lang/alloc_fence.ludic
Normal file
32
examples/lang/alloc_fence.ludic
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# alloc_fence.ludic - the allocation fence (docs/plan 25.1) judges frames once play has settled.
|
||||
# Everything a frame makes here is gone by the frame's end or goes on being reused: text only
|
||||
# compared (freed once compared), records held from before play written in place. No frame
|
||||
# keeps anything, so the run - which fails by default when one does - prints
|
||||
# `frames 300 kept 0 bad 0`.
|
||||
program AllocFence {
|
||||
property Box { a: int = 0 }
|
||||
|
||||
function round(i: int, kept: []Box) -> int {
|
||||
var bad = 0
|
||||
if `{i}-{i * 2}` != string(i) + "-" + string(i * 2) { bad += 1 }
|
||||
if `lake {i}` == "" { bad += 1 }
|
||||
for k in 0 .. len(kept) { kept[k].a = i + k } # records reused: List.clear and new ones would keep the old
|
||||
return bad
|
||||
}
|
||||
|
||||
entry {
|
||||
var kept = new []Box
|
||||
for k in 0 .. 8 { push(kept, new Box) }
|
||||
Mem.play()
|
||||
Mem.settled()
|
||||
var bad = 0
|
||||
var frames = 0
|
||||
for i in 0 .. 300 {
|
||||
bad += round(i, kept)
|
||||
Mem.frame()
|
||||
frames += 1
|
||||
}
|
||||
let kept_now = Mem.kept() # read before the line below makes its text
|
||||
print(`frames {frames} kept {kept_now} bad {Mem.bad_frames()}`)
|
||||
}
|
||||
}
|
||||
16
examples/lang/alloc_fence_auto.ludic
Normal file
16
examples/lang/alloc_fence_auto.ludic
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# alloc_fence_auto.ludic - nothing here names the fence but the frame's mark: tracking starts at the
|
||||
# first frame on its own, judging once R3D_ALLOC_WARM frames (600) in a row kept nothing, and frame
|
||||
# 1500 keeping a record fails the run with exit 86. Prints nothing when it fails, `through` if not.
|
||||
program AllocFenceAuto {
|
||||
property Box { a: int = 0 }
|
||||
entry {
|
||||
var held = new []Box
|
||||
for k in 0 .. 4 { push(held, new Box) }
|
||||
for f in 0 .. 2000 {
|
||||
if f < 300 { push(held, new Box { a: f }) } # loading: growing, not judged
|
||||
if f == 1500 { push(held, new Box { a: f }) }
|
||||
Mem.frame()
|
||||
}
|
||||
print("through")
|
||||
}
|
||||
}
|
||||
17
examples/lang/alloc_fence_leak.ludic
Normal file
17
examples/lang/alloc_fence_leak.ludic
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# alloc_fence_leak.ludic - frame 50 keeps one record in a list that outlives it. The fence fails
|
||||
# the run there (exit 86) and names this file's `new Box` line; under R3D_ALLOC_FENCE=count it
|
||||
# runs on and prints `kept 80 bad 1` (the record and the list's growth, at malloc's own sizes, in one frame).
|
||||
program AllocFenceLeak {
|
||||
property Box { a: int = 0, b: int = 0 }
|
||||
entry {
|
||||
var held = new []Box
|
||||
Mem.play()
|
||||
Mem.settled()
|
||||
for f in 0 .. 100 {
|
||||
if f == 50 { push(held, new Box { a: f }) }
|
||||
Mem.frame()
|
||||
}
|
||||
let kept_now = Mem.kept()
|
||||
print(`kept {kept_now} bad {Mem.bad_frames()}`)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue