ARC: cycle detector (#12823)

* first implementation of the =trace and =dispose hooks for the cycle collector
* a cycle collector for ARC: progress
* manual: the .acyclic pragma is a thing once again
* gcbench: adaptations for --gc:arc
* enable valgrind tests for the strutils tests
* testament: better valgrind support
* ARC refactoring: growable jumpstacks
* ARC cycle detector: non-recursive algorithm
* moved and renamed core/ files back to system/
* refactoring: --gc:arc vs --gc:orc since 'orc' is even more experimental and we want to ship --gc:arc soonish
This commit is contained in:
Andreas Rumpf 2019-12-17 17:37:50 +01:00 • committed by GitHub
commit 83a736a34a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 939 additions and 229 deletions

View file

@ -0,0 +1,64 @@
discard """
output: '''BEGIN
END
END 2
0'''
cmd: '''nim c --gc:orc $file'''
"""
# extracted from thavlak.nim
type
BasicBlock = ref object
inEdges: seq[BasicBlock]
outEdges: seq[BasicBlock]
name: int
proc newBasicBlock(name: int): BasicBlock =
result = BasicBlock(
inEdges: newSeq[BasicBlock](),
outEdges: newSeq[BasicBlock](),
name: name
)
type
Cfg = object
basicBlockMap: seq[BasicBlock]
startNode: BasicBlock
proc newCfg(): Cfg =
result = Cfg(
basicBlockMap: newSeq[BasicBlock](),
startNode: nil)
proc createNode(cfg: var Cfg, name: int): BasicBlock =
if name < cfg.basicBlockMap.len:
result = cfg.basicBlockMap[name]
else:
result = newBasicBlock(name)
cfg.basicBlockMap.setLen name+1
cfg.basicBlockMap[name] = result
proc newBasicBlockEdge(cfg: var Cfg, fromName, toName: int) =
echo "BEGIN"
let fr = cfg.createNode(fromName)
let to = cfg.createNode(toName)
fr.outEdges.add(to)
to.inEdges.add(fr)
proc run(cfg: var Cfg) =
cfg.startNode = cfg.createNode(0) # RC = 2
newBasicBlockEdge(cfg, 0, 1) #
echo "END"
discard cfg.createNode(1)
proc main =
var c = newCfg()
c.run
echo "END 2"
let mem = getOccupiedMem()
main()
echo getOccupiedMem() - mem