ARC: fixes leaking new() statement (#12665)
This commit is contained in:
parent
107b40f097
commit
76179cbec2
3 changed files with 24 additions and 8 deletions
|
|
@ -32,7 +32,7 @@ type
|
||||||
uninit: IntSet # set of uninit'ed vars
|
uninit: IntSet # set of uninit'ed vars
|
||||||
uninitComputed: bool
|
uninitComputed: bool
|
||||||
|
|
||||||
const toDebug = "" # "server" # "serverNimAsyncContinue"
|
const toDebug {.strdefine.} = "" # "server" # "serverNimAsyncContinue"
|
||||||
|
|
||||||
template dbg(body) =
|
template dbg(body) =
|
||||||
when toDebug.len > 0:
|
when toDebug.len > 0:
|
||||||
|
|
@ -450,7 +450,11 @@ proc p(n: PNode; c: var Con): PNode =
|
||||||
for i in 1..<n.len:
|
for i in 1..<n.len:
|
||||||
n[i] = pArg(n[i], c, i < L and isSinkTypeForParam(parameters[i]))
|
n[i] = pArg(n[i], c, i < L and isSinkTypeForParam(parameters[i]))
|
||||||
result = n
|
result = n
|
||||||
of nkDiscardStmt: #Small optimization
|
if result[0].kind == nkSym and result[0].sym.magic in {mNew, mNewFinalize}:
|
||||||
|
if c.graph.config.selectedGC in {gcHooks, gcDestructors}:
|
||||||
|
let destroyOld = genDestroy(c, result[1])
|
||||||
|
result = newTree(nkStmtList, destroyOld, result)
|
||||||
|
of nkDiscardStmt: # Small optimization
|
||||||
if n[0].kind != nkEmpty:
|
if n[0].kind != nkEmpty:
|
||||||
n[0] = pArg(n[0], c, false)
|
n[0] = pArg(n[0], c, false)
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -233,9 +233,12 @@ proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} =
|
||||||
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
||||||
result = conf.cmd == cmdCompileToJS and not isCompileTime
|
result = conf.cmd == cmdCompileToJS and not isCompileTime
|
||||||
|
|
||||||
proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo) =
|
proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; owner: PSym) =
|
||||||
createTypeBoundOps(g, nil, refType.lastSon, info)
|
createTypeBoundOps(g, nil, refType.lastSon, info)
|
||||||
createTypeBoundOps(g, nil, refType, info)
|
createTypeBoundOps(g, nil, refType, info)
|
||||||
|
if (tfHasAsgn in refType.flags) or
|
||||||
|
optSeqDestructors in g.config.globalOptions:
|
||||||
|
owner.flags.incl sfInjectDestructors
|
||||||
|
|
||||||
proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||||
|
|
@ -261,7 +264,7 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||||
result.add(v)
|
result.add(v)
|
||||||
# add 'new' statement:
|
# add 'new' statement:
|
||||||
result.add newCall(getSysSym(g, n.info, "internalNew"), env)
|
result.add newCall(getSysSym(g, n.info, "internalNew"), env)
|
||||||
createTypeBoundOpsLL(g, env.typ, n.info)
|
createTypeBoundOpsLL(g, env.typ, n.info, owner)
|
||||||
result.add makeClosure(g, iter, env, n.info)
|
result.add makeClosure(g, iter, env, n.info)
|
||||||
|
|
||||||
proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
|
proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
|
||||||
|
|
@ -592,7 +595,7 @@ proc rawClosureCreation(owner: PSym;
|
||||||
let env2 = copyTree(env)
|
let env2 = copyTree(env)
|
||||||
env2.typ = unowned.typ
|
env2.typ = unowned.typ
|
||||||
result.add newAsgnStmt(unowned, env2, env.info)
|
result.add newAsgnStmt(unowned, env2, env.info)
|
||||||
createTypeBoundOpsLL(d.graph, unowned.typ, env.info)
|
createTypeBoundOpsLL(d.graph, unowned.typ, env.info, owner)
|
||||||
|
|
||||||
# add assignment statements for captured parameters:
|
# add assignment statements for captured parameters:
|
||||||
for i in 1..<owner.typ.n.len:
|
for i in 1..<owner.typ.n.len:
|
||||||
|
|
@ -615,7 +618,7 @@ proc rawClosureCreation(owner: PSym;
|
||||||
localError(d.graph.config, env.info, "internal error: cannot create up reference")
|
localError(d.graph.config, env.info, "internal error: cannot create up reference")
|
||||||
# we are not in the sem'check phase anymore! so pass 'nil' for the PContext
|
# we are not in the sem'check phase anymore! so pass 'nil' for the PContext
|
||||||
# and hope for the best:
|
# and hope for the best:
|
||||||
createTypeBoundOpsLL(d.graph, env.typ, owner.info)
|
createTypeBoundOpsLL(d.graph, env.typ, owner.info, owner)
|
||||||
|
|
||||||
proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass;
|
proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass;
|
||||||
info: TLineInfo; res: PNode) =
|
info: TLineInfo; res: PNode) =
|
||||||
|
|
@ -643,7 +646,7 @@ proc closureCreationForIter(iter: PNode;
|
||||||
addVar(vs, vnode)
|
addVar(vs, vnode)
|
||||||
result.add(vs)
|
result.add(vs)
|
||||||
result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode))
|
result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode))
|
||||||
createTypeBoundOpsLL(d.graph, vnode.typ, iter.info)
|
createTypeBoundOpsLL(d.graph, vnode.typ, iter.info, owner)
|
||||||
|
|
||||||
let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
|
let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
|
||||||
if upField != nil:
|
if upField != nil:
|
||||||
|
|
@ -926,7 +929,7 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
|
||||||
result.add(v)
|
result.add(v)
|
||||||
# add 'new' statement:
|
# add 'new' statement:
|
||||||
result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode))
|
result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode))
|
||||||
createTypeBoundOpsLL(g, env.typ, body.info)
|
createTypeBoundOpsLL(g, env.typ, body.info, owner)
|
||||||
|
|
||||||
elif op.kind == nkStmtListExpr:
|
elif op.kind == nkStmtListExpr:
|
||||||
let closure = op.lastSon
|
let closure = op.lastSon
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,18 @@ proc tlazyList =
|
||||||
var x = LazyList(c: proc () = echo(dep))
|
var x = LazyList(c: proc () = echo(dep))
|
||||||
x.c()
|
x.c()
|
||||||
|
|
||||||
|
type
|
||||||
|
Foo = ref object
|
||||||
|
|
||||||
|
proc tleakingNewStmt =
|
||||||
|
var x: Foo
|
||||||
|
for i in 0..10:
|
||||||
|
new(x)
|
||||||
|
|
||||||
let startMem = getOccupiedMem()
|
let startMem = getOccupiedMem()
|
||||||
tlazyList()
|
tlazyList()
|
||||||
|
|
||||||
mkManyLeaks()
|
mkManyLeaks()
|
||||||
tsimpleClosureIterator()
|
tsimpleClosureIterator()
|
||||||
|
tleakingNewStmt()
|
||||||
echo getOccupiedMem() - startMem
|
echo getOccupiedMem() - startMem
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue