Skip to content

Commit

Permalink
fixes #24402; Memory leak under Arc/Orc on inline iterators with nest…
Browse files Browse the repository at this point in the history
…ed seq
  • Loading branch information
ringabout committed Nov 8, 2024
1 parent b3c1fba commit d647927
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
6 changes: 4 additions & 2 deletions compiler/transf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ proc transformYield(c: PTransf, n: PNode): PNode =
let lhs = c.transCon.forStmt[i]
let rhs = transform(c, v)
result.add(asgnTo(lhs, rhs))
elif e.kind notin {nkAddr, nkHiddenAddr}: # no need to generate temp for address operation
elif e.kind notin {nkAddr, nkHiddenAddr} and e.kind != nkSym:
# no need to generate temp for address operation + nodes without sideeffects
# TODO do not use temp for nodes which cannot have side-effects
var tmp = newTemp(c, e.typ, e.info)
let v = newNodeI(nkVarSection, e.info)
Expand Down Expand Up @@ -435,7 +436,8 @@ proc transformYield(c: PTransf, n: PNode): PNode =
else:
notLiteralTuple = true

if e.kind notin {nkAddr, nkHiddenAddr} and notLiteralTuple:
if e.kind notin {nkAddr, nkHiddenAddr} and notLiteralTuple and e.kind != nkSym:
# no need to generate temp for address operation + nodes without sideeffects
# TODO do not use temp for nodes which cannot have side-effects
var tmp = newTemp(c, e.typ, e.info)
let v = newNodeI(nkVarSection, e.info)
Expand Down
54 changes: 54 additions & 0 deletions tests/arc/t24402.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
discard """
joinable: false
"""

# bug #24402

iterator myPairsInline*[T](twoDarray: seq[seq[T]]): (int, seq[T]) {.inline.} =
for indexValuePair in twoDarray.pairs:
yield indexValuePair

iterator myPairsClosure*[T](twoDarray: seq[seq[T]]): (int, seq[T]) {.closure.} =
for indexValuePair in twoDarray.pairs:
yield indexValuePair

template testTotalMem(iter: untyped): int =
proc innerTestTotalMem(): int {.gensym.} =
result = 0

# do the same operation 100 times, which should have similar mem footprint
# as doing it once.
for iterNum in 0..100:
result = max(result, getTotalMem()) # record current mem footprint

# initialize nested sequence
var my2dArray: seq[seq[int32]] = @[]

# fill with some data...
for i in 0'i32..10_000:
var z = @[i, i+1]
my2dArray.add z

# use that data somehow...
var otherContainer: seq[int32] = @[]
var count = 0'i32
for oneDindex, innerArray in my2dArray.iter:
for value in innerArray:
inc count
if oneDindex > 50 and value < 200:
otherContainer.add count

innerTestTotalMem()

proc main =
let closureMem = testTotalMem(myPairsClosure) #1052672
let inlineMem = testTotalMem(myPairsInline) #20328448

when defined(echoFootprint):
echo "Closure memory footprint: " & $closureMem
echo "Inline memory footprint: " & $inlineMem

# check that mem footprint is relatively similar b/t each method
doAssert (closureMem - inlineMem).abs < (closureMem div 10)

main()

0 comments on commit d647927

Please sign in to comment.