From 21420d8b0976dc034feb90ab2878ae0dd63121ae Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 13 Nov 2024 05:57:31 +0800 Subject: [PATCH] fixes #24402; Memory leak under Arc/Orc on inline iterators with nested seq (#24419) fixes #24402 ```nim iterator myPairsInline*[T](twoDarray: seq[seq[T]]): (int, seq[T]) {.inline.} = for indexValuePair in twoDarray.pairs: yield indexValuePair proc innerTestTotalMem() = var my2dArray: seq[seq[int32]] = @[] # fill with some data... for i in 0'i32..100: var z = @[i, i+1] my2dArray.add z for oneDindex, innerArray in myPairsInline(my2dArray): discard innerTestTotalMem() ``` In `for oneDindex, innerArray in myPairsInline(my2dArray)`, `oneDindex` and `innerArray` becomes `cursors` because they satisfy the criterion of `isSimpleIteratorVar`. On the one hand, it is not correct to have them point to the temporary generated by tuple unpacking, which left the memory of the temporary uncleaned up. On the other hand, we don't need to generate a temporary for a symbol node when unpacking the tuple. --- compiler/transf.nim | 35 +++++++++++++++------------- tests/arc/t24402.nim | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 tests/arc/t24402.nim diff --git a/compiler/transf.nim b/compiler/transf.nim index 59e4453fd7..5cf43e6a3f 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -366,6 +366,19 @@ proc transformAsgn(c: PTransf, n: PNode): PNode = result[0] = letSection result[1] = asgnNode +template assignTupleUnpacking(c: PTransf, e: PNode) = + for i in 0.. 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() \ No newline at end of file