mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 11:42:33 +00:00
@@ -1319,9 +1319,9 @@ proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp): Rope =
|
||||
genProc(m, theProc)
|
||||
result = theProc.loc.r
|
||||
else:
|
||||
if op == attachedTrace and m.config.selectedGC == gcOrc and
|
||||
containsGarbageCollectedRef(t):
|
||||
when false:
|
||||
when false:
|
||||
if op == attachedTrace and m.config.selectedGC == gcOrc and
|
||||
containsGarbageCollectedRef(t):
|
||||
# unfortunately this check is wrong for an object type that only contains
|
||||
# .cursor fields like 'Node' inside 'cycleleak'.
|
||||
internalError(m.config, info, "no attached trace proc found")
|
||||
|
||||
@@ -448,6 +448,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
# follow all elements:
|
||||
forallElements(c, t, body, x, y)
|
||||
of attachedDispose:
|
||||
forallElements(c, t, body, x, y)
|
||||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
||||
|
||||
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
|
||||
@@ -158,7 +158,7 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType
|
||||
else:
|
||||
rawAddSon(result, getCompilerProc(g, "RootObj").typ)
|
||||
result.n = newNodeI(nkRecList, info)
|
||||
let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info)),
|
||||
let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info) & "_" & $owner.name.s),
|
||||
owner, info, owner.options)
|
||||
incl s.flags, sfAnon
|
||||
s.typ = result
|
||||
|
||||
@@ -40,7 +40,7 @@ template setColor(c, col) =
|
||||
proc nimIncRefCyclic(p: pointer) {.compilerRtl, inl.} =
|
||||
let h = head(p)
|
||||
inc h.rc, rcIncrement
|
||||
h.setColor colPurple # mark as potential cycle!
|
||||
#h.setColor colPurple # mark as potential cycle!
|
||||
|
||||
const
|
||||
useJumpStack = false # for thavlak the jump stack doesn't improve the performance at all
|
||||
@@ -74,6 +74,19 @@ proc free(s: Cell; desc: PNimType) {.inline.} =
|
||||
|
||||
if desc.disposeImpl != nil:
|
||||
cast[DisposeProc](desc.disposeImpl)(p)
|
||||
|
||||
when false:
|
||||
cstderr.rawWrite desc.name
|
||||
cstderr.rawWrite " "
|
||||
if desc.disposeImpl == nil:
|
||||
cstderr.rawWrite "lacks dispose"
|
||||
if desc.traceImpl != nil:
|
||||
cstderr.rawWrite ", but has trace\n"
|
||||
else:
|
||||
cstderr.rawWrite ", and lacks trace\n"
|
||||
else:
|
||||
cstderr.rawWrite "has dispose!\n"
|
||||
|
||||
nimRawDispose(p)
|
||||
|
||||
proc nimTraceRef(q: pointer; desc: PNimType; env: pointer) {.compilerRtl.} =
|
||||
@@ -342,8 +355,8 @@ proc nimDecRefIsLastCyclicDyn(p: pointer): bool {.compilerRtl, inl.} =
|
||||
#cprintf("[DESTROY] %p\n", p)
|
||||
else:
|
||||
dec cell.rc, rcIncrement
|
||||
if cell.color == colPurple:
|
||||
rememberCycle(result, cell, cast[ptr PNimType](p)[])
|
||||
#if cell.color == colPurple:
|
||||
rememberCycle(result, cell, cast[ptr PNimType](p)[])
|
||||
|
||||
proc nimDecRefIsLastCyclicStatic(p: pointer; desc: PNimType): bool {.compilerRtl, inl.} =
|
||||
if p != nil:
|
||||
@@ -353,5 +366,5 @@ proc nimDecRefIsLastCyclicStatic(p: pointer; desc: PNimType): bool {.compilerRtl
|
||||
#cprintf("[DESTROY] %p %s\n", p, desc.name)
|
||||
else:
|
||||
dec cell.rc, rcIncrement
|
||||
if cell.color == colPurple:
|
||||
rememberCycle(result, cell, desc)
|
||||
#if cell.color == colPurple:
|
||||
rememberCycle(result, cell, desc)
|
||||
|
||||
88
tests/arc/tasyncleak2.nim
Normal file
88
tests/arc/tasyncleak2.nim
Normal file
@@ -0,0 +1,88 @@
|
||||
discard """
|
||||
output: "success"
|
||||
cmd: "nim c --gc:orc $file"
|
||||
"""
|
||||
|
||||
# issue #15076
|
||||
import deques, strutils, asyncdispatch
|
||||
|
||||
proc doNothing(): Future[void] =
|
||||
#[
|
||||
var
|
||||
:env
|
||||
:env_1
|
||||
try:
|
||||
`=destroy`(:env)
|
||||
internalNew(:env)
|
||||
`=sink`(:env.retFuture1, newFuture("doNothing"))
|
||||
|
||||
`=destroy_1`(:env_1)
|
||||
internalNew(:env_1)
|
||||
`=`(:env_1.:up, :env)
|
||||
`=sink_1`(:env.nameIterVar2, (doNothingIter, :env_1))
|
||||
|
||||
(doNothingNimAsyncContinue, :env)()
|
||||
return `=_1`(result, :env.retFuture1)
|
||||
finally:
|
||||
`=destroy`(:env)
|
||||
]#
|
||||
|
||||
var retFuture = newFuture[void]("doNothing")
|
||||
iterator doNothingIter(): FutureBase {.closure.} =
|
||||
# inspected ARC code: looks correct!
|
||||
block:
|
||||
var qqq = initDeque[string]()
|
||||
for i in 0 .. 1000:
|
||||
qqq.addLast($i)
|
||||
complete(retFuture) # env.up.retFuture1
|
||||
|
||||
var nameIterVar = doNothingIter # iter_Env -> retFuture ->
|
||||
|
||||
proc doNothingNimAsyncContinue() {.closure.} =
|
||||
# inspected ARC code: looks correct
|
||||
if not nameIterVar.finished:
|
||||
var next_gensym0 = nameIterVar()
|
||||
while (not next_gensym0.isNil) and next_gensym0.finished:
|
||||
next_gensym0 = nameIterVar()
|
||||
if nameIterVar.finished:
|
||||
break
|
||||
if next_gensym0 != nil:
|
||||
{.gcsafe.}:
|
||||
next_gensym0.addCallback cast[proc () {.closure, gcsafe.}](doNothingNimAsyncContinue)
|
||||
|
||||
doNothingNimAsyncContinue()
|
||||
return retFuture
|
||||
|
||||
proc main(): Future[void] =
|
||||
template await[T](f_gensym12: Future[T]): auto {.used.} =
|
||||
var internalTmpFuture_gensym12: FutureBase = f_gensym12
|
||||
yield internalTmpFuture_gensym12
|
||||
(cast[type(f_gensym12)](internalTmpFuture_gensym12)).read()
|
||||
|
||||
var retFuture = newFuture[void]("main")
|
||||
iterator mainIter(): FutureBase {.closure.} =
|
||||
block:
|
||||
for x in 0 .. 1000:
|
||||
await doNothing()
|
||||
complete(retFuture)
|
||||
|
||||
var nameIterVar_gensym11 = mainIter
|
||||
proc mainNimAsyncContinue() {.closure.} =
|
||||
if not nameIterVar_gensym11.finished:
|
||||
var next_gensym11 = unown nameIterVar_gensym11()
|
||||
while (not next_gensym11.isNil) and next_gensym11.finished:
|
||||
next_gensym11 = unown nameIterVar_gensym11()
|
||||
if nameIterVar_gensym11.finished:
|
||||
break
|
||||
if next_gensym11 != nil:
|
||||
{.gcsafe.}:
|
||||
next_gensym11.addCallback cast[proc () {.closure, gcsafe.}](mainNimAsyncContinue)
|
||||
|
||||
mainNimAsyncContinue()
|
||||
return retFuture
|
||||
|
||||
for i in 0..9:
|
||||
waitFor main()
|
||||
GC_fullCollect()
|
||||
assert getOccupiedMem() < 1024
|
||||
echo "success"
|
||||
Reference in New Issue
Block a user