diff options
Diffstat (limited to 'tests/gc')
-rw-r--r-- | tests/gc/closureleak.nim | 14 | ||||
-rw-r--r-- | tests/gc/cyclecollector.nim | 5 | ||||
-rw-r--r-- | tests/gc/gcleak.nim | 9 | ||||
-rw-r--r-- | tests/gc/gcleak2.nim | 14 | ||||
-rw-r--r-- | tests/gc/gcleak3.nim | 8 | ||||
-rw-r--r-- | tests/gc/gcleak4.nim | 2 | ||||
-rw-r--r-- | tests/gc/gcleak5.nim | 2 | ||||
-rw-r--r-- | tests/gc/growobjcrash.nim | 9 | ||||
-rw-r--r-- | tests/gc/panicoverride.nim | 14 | ||||
-rw-r--r-- | tests/gc/tdisable_orc.nim | 9 | ||||
-rw-r--r-- | tests/gc/thavlak.nim | 19 | ||||
-rw-r--r-- | tests/gc/trace_globals.nim | 33 | ||||
-rw-r--r-- | tests/gc/tregionleak.nim | 23 | ||||
-rw-r--r-- | tests/gc/tstandalone.nim | 14 |
14 files changed, 146 insertions, 29 deletions
diff --git a/tests/gc/closureleak.nim b/tests/gc/closureleak.nim index 0265431d0..e67beb513 100644 --- a/tests/gc/closureleak.nim +++ b/tests/gc/closureleak.nim @@ -11,9 +11,19 @@ var foo_counter = 0 var alive_foos = newseq[int](0) when defined(gcDestructors): - proc `=destroy`(some: var TFoo) = + proc `=destroy`(some: TFoo) = alive_foos.del alive_foos.find(some.id) - `=destroy`(some.fn) + # TODO: fixme: investigate why `=destroy` requires `some.fn` to be `gcsafe` + # the debugging info below came from `symPrototype` in the liftdestructors + # proc (){.closure, gcsafe.}, {tfThread, tfHasAsgn, tfCheckedForDestructor, tfExplicitCallConv} + # var proc (){.closure, gcsafe.}, {tfHasGCedMem} + # it worked by accident with var T destructors because in the sempass2 + # + # let argtype = skipTypes(a.typ, abstractInst) # !!! it does't skip `tyVar` + # if argtype.kind == tyProc and notGcSafe(argtype) and not tracked.inEnforcedGcSafe: + # localError(tracked.config, n.info, $n & " is not GC safe") + {.cast(gcsafe).}: + `=destroy`(some.fn) else: proc free*(some: ref TFoo) = diff --git a/tests/gc/cyclecollector.nim b/tests/gc/cyclecollector.nim index 7b47758f2..2d02a7a3c 100644 --- a/tests/gc/cyclecollector.nim +++ b/tests/gc/cyclecollector.nim @@ -9,7 +9,10 @@ type proc createCycle(leaf: string): Node = new result result.a = result - shallowCopy result.leaf, leaf + when defined(gcArc) or defined(gcOrc): + result.leaf = leaf + else: + shallowCopy result.leaf, leaf proc main = for i in 0 .. 100_000: diff --git a/tests/gc/gcleak.nim b/tests/gc/gcleak.nim index 0b2e6e14d..0bf993968 100644 --- a/tests/gc/gcleak.nim +++ b/tests/gc/gcleak.nim @@ -12,7 +12,14 @@ type proc makeObj(): TTestObj = result.x = "Hello" -for i in 1 .. 100_000: +const numIter = + # see tests/gc/gcleak2.nim + when defined(boehmgc): + 1_000 + elif defined(gcMarkAndSweep): 10_000 + else: 100_000 + +for i in 1 .. numIter: when defined(gcMarkAndSweep) or defined(boehmgc): GC_fullcollect() var obj = makeObj() diff --git a/tests/gc/gcleak2.nim b/tests/gc/gcleak2.nim index fe1718aef..bc943dbe7 100644 --- a/tests/gc/gcleak2.nim +++ b/tests/gc/gcleak2.nim @@ -14,8 +14,20 @@ proc makeObj(): TTestObj = result.x = "Hello" result.s = @[1,2,3] +const numIter = + when defined(boehmgc): + # super slow because GC_fullcollect() at each iteration; especially + # on OSX 10.15 where it takes ~170s + # `getOccupiedMem` should be constant after each iteration for i >= 3 + 1_000 + elif defined(gcMarkAndSweep): + # likewise, somewhat slow, 1_000_000 would run for 8s + # and same remark as above + 100_000 + else: 1_000_000 + proc inProc() = - for i in 1 .. 1_000_000: + for i in 1 .. numIter: when defined(gcMarkAndSweep) or defined(boehmgc): GC_fullcollect() var obj: TTestObj diff --git a/tests/gc/gcleak3.nim b/tests/gc/gcleak3.nim index 588e238e9..5e146d69f 100644 --- a/tests/gc/gcleak3.nim +++ b/tests/gc/gcleak3.nim @@ -17,14 +17,10 @@ for i in 0..1024: s.add(obj) proc limit*[t](a: var seq[t]) = - var loop = s.len() - 512 - for i in 0..loop: - #echo i - #GC_fullCollect() + while s.len > 0: if getOccupiedMem() > 3000_000: quit("still a leak!") - s.delete(i) + s.delete(0) s.limit() - echo "no leak: ", getOccupiedMem() diff --git a/tests/gc/gcleak4.nim b/tests/gc/gcleak4.nim index fbe18a386..a72db67b7 100644 --- a/tests/gc/gcleak4.nim +++ b/tests/gc/gcleak4.nim @@ -35,7 +35,7 @@ proc newPlus(a, b: sink(ref TExpr)): ref TPlusExpr = const Limit = when compileOption("gc", "markAndSweep") or compileOption("gc", "boehm"): 5*1024*1024 else: 500_000 -for i in 0..100_000: +for i in 0..50_000: var s: array[0..11, ref TExpr] for j in 0..high(s): s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4)) diff --git a/tests/gc/gcleak5.nim b/tests/gc/gcleak5.nim index 6ab50e19e..f1913831b 100644 --- a/tests/gc/gcleak5.nim +++ b/tests/gc/gcleak5.nim @@ -9,7 +9,7 @@ proc main = for ii in 0..50_000: #while true: var t = getTime() - var g = t.getGMTime() + var g = t.utc() #echo isOnStack(addr g) if i mod 100 == 0: diff --git a/tests/gc/growobjcrash.nim b/tests/gc/growobjcrash.nim index 07f92b8f4..ff1aa7e98 100644 --- a/tests/gc/growobjcrash.nim +++ b/tests/gc/growobjcrash.nim @@ -1,8 +1,4 @@ -discard """ - output: "works" -""" - -import cgi, strtabs +import std/[cgi, strtabs] proc handleRequest(query: string): StringTableRef = iterator foo(): StringTableRef {.closure.} = @@ -18,7 +14,7 @@ const Limit = 5*1024*1024 proc main = var counter = 0 - for i in 0 .. 100_000: + for i in 0 .. 10_000: for k, v in handleRequest("nick=Elina2&type=activate"): inc counter if counter mod 100 == 0: @@ -26,4 +22,3 @@ proc main = quit "but now a leak" main() -echo "works" diff --git a/tests/gc/panicoverride.nim b/tests/gc/panicoverride.nim new file mode 100644 index 000000000..0f28b0b72 --- /dev/null +++ b/tests/gc/panicoverride.nim @@ -0,0 +1,14 @@ + +proc printf(frmt: cstring) {.varargs, importc, header: "<stdio.h>", cdecl.} +proc exit(code: int) {.importc, header: "<stdlib.h>", cdecl.} + +{.push stack_trace: off, profiler:off.} + +proc rawoutput(s: string) = + printf("%s\n", s) + +proc panic(s: string) {.noreturn.} = + rawoutput(s) + exit(1) + +{.pop.} \ No newline at end of file diff --git a/tests/gc/tdisable_orc.nim b/tests/gc/tdisable_orc.nim new file mode 100644 index 000000000..b5f161c79 --- /dev/null +++ b/tests/gc/tdisable_orc.nim @@ -0,0 +1,9 @@ +discard """ + joinable: false +""" + +import std/asyncdispatch + +# bug #22256 +GC_disableMarkAndSweep() +waitFor sleepAsync(1000) diff --git a/tests/gc/thavlak.nim b/tests/gc/thavlak.nim index b4cdacf7c..cfd860e25 100644 --- a/tests/gc/thavlak.nim +++ b/tests/gc/thavlak.nim @@ -1,13 +1,13 @@ discard """ output: '''Welcome to LoopTesterApp, Nim edition Constructing Simple CFG... -15000 dummy loops +5000 dummy loops Constructing CFG... Performing Loop Recognition 1 Iteration -Another 5 iterations... -..... -Found 1 loops (including artificial root node) (5)''' +Another 3 iterations... +... +Found 1 loops (including artificial root node) (3)''' """ # bug #3184 @@ -384,9 +384,9 @@ proc run(self: var LoopTesterApp) = discard self.cfg.createNode(1) self.buildConnect(0, 2) - echo "15000 dummy loops" + echo "5000 dummy loops" - for i in 1..15000: + for i in 1..5000: withScratchRegion: var h = newHavlakLoopFinder(self.cfg, newLsg()) discard h.findLoops @@ -394,7 +394,7 @@ proc run(self: var LoopTesterApp) = echo "Constructing CFG..." var n = 2 - when not defined(gcOrc): + when true: # not defined(gcOrc): # currently cycle detection is so slow that we disable this part for parlooptrees in 1..10: discard self.cfg.createNode(n + 1) @@ -414,10 +414,10 @@ proc run(self: var LoopTesterApp) = var h = newHavlakLoopFinder(self.cfg, newLsg()) var loops = h.findLoops - echo "Another 5 iterations..." + echo "Another 3 iterations..." var sum = 0 - for i in 1..5: + for i in 1..3: withScratchRegion: write stdout, "." flushFile(stdout) @@ -437,4 +437,5 @@ proc main = let mem = getOccupiedMem() main() when defined(gcOrc): + GC_fullCollect() doAssert getOccupiedMem() == mem diff --git a/tests/gc/trace_globals.nim b/tests/gc/trace_globals.nim new file mode 100644 index 000000000..f62a15692 --- /dev/null +++ b/tests/gc/trace_globals.nim @@ -0,0 +1,33 @@ +discard """ + output: ''' +10000000 +10000000 +10000000''' +""" + +# bug #17085 + +#[ +refs https://github.com/nim-lang/Nim/issues/17085#issuecomment-786466595 +with --gc:boehm, this warning sometimes gets generated: +Warning: Repeated allocation of very large block (appr. size 14880768): +May lead to memory leak and poor performance. +nim CI now runs this test with `testWithoutBoehm` to avoid running it with --gc:boehm. +]# + +proc init(): string = + for a in 0..<10000000: + result.add 'c' + +proc f() = + var a {.global.} = init() + var b {.global.} = init() + var c {.global.} = init() + + echo a.len + # `echo` intentional according to + # https://github.com/nim-lang/Nim/pull/17469/files/0c9e94cb6b9ebca9da7cb19a063fba7aa409748e#r600016573 + echo b.len + echo c.len + +f() diff --git a/tests/gc/tregionleak.nim b/tests/gc/tregionleak.nim new file mode 100644 index 000000000..277cfc987 --- /dev/null +++ b/tests/gc/tregionleak.nim @@ -0,0 +1,23 @@ +discard """ + cmd: '''nim c --gc:regions $file''' + output: ''' +finalized +finalized +''' +""" + +proc finish(o: RootRef) = + echo "finalized" + +withScratchRegion: + var test: RootRef + new(test, finish) + +var + mr: MemRegion + test: RootRef + +withRegion(mr): + new(test, finish) + +deallocAll(mr) diff --git a/tests/gc/tstandalone.nim b/tests/gc/tstandalone.nim new file mode 100644 index 000000000..41dad9ba4 --- /dev/null +++ b/tests/gc/tstandalone.nim @@ -0,0 +1,14 @@ +discard """ + matrix: "--os:standalone --gc:none" + exitcode: 1 + output: "value out of range" +""" + +type + rangeType = range[0..1] + +var + r: rangeType = 0 + i = 2 + +r = rangeType(i) |