summary refs log tree commit diff stats
path: root/tests/gc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gc')
-rw-r--r--tests/gc/closureleak.nim14
-rw-r--r--tests/gc/cyclecollector.nim5
-rw-r--r--tests/gc/gcleak.nim9
-rw-r--r--tests/gc/gcleak2.nim14
-rw-r--r--tests/gc/gcleak3.nim8
-rw-r--r--tests/gc/gcleak4.nim2
-rw-r--r--tests/gc/gcleak5.nim2
-rw-r--r--tests/gc/growobjcrash.nim9
-rw-r--r--tests/gc/panicoverride.nim14
-rw-r--r--tests/gc/tdisable_orc.nim9
-rw-r--r--tests/gc/thavlak.nim19
-rw-r--r--tests/gc/trace_globals.nim33
-rw-r--r--tests/gc/tregionleak.nim23
-rw-r--r--tests/gc/tstandalone.nim14
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)