summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-10-31 22:32:27 +0100
committerAraq <rumpf_a@web.de>2013-10-31 22:32:27 +0100
commitf73cec7f0198fdebe118585b05557e4a53d08aea (patch)
tree63dd538ad84e6a5a9ca07bcba486bb13248f3458 /lib/system
parenteb72857ea229aa1a65f9dc0962840ede2a9e68ed (diff)
downloadNim-f73cec7f0198fdebe118585b05557e4a53d08aea.tar.gz
GC: even more stress testing
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/alloc.nim15
-rw-r--r--lib/system/gc.nim21
-rw-r--r--lib/system/mmdisp.nim1
3 files changed, 29 insertions, 8 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 744c26d36..2bab79212 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -520,11 +520,18 @@ proc allocInv(a: TMemRegion): bool =
   for s in low(a.freeSmallChunks)..high(a.freeSmallChunks):
     var c = a.freeSmallChunks[s]
     while c != nil:
-      if c.next == c: return false
-      if c.size != s * MemAlign: return false
+      if c.next == c: 
+        echo "[SYSASSERT] c.next == c"
+        return false
+      if c.size != s * MemAlign: 
+        echo "[SYSASSERT] c.size != s * MemAlign"
+        return false
       var it = c.freeList
       while it != nil:
-        if it.zeroField != 0: return false
+        if it.zeroField != 0: 
+          echo "[SYSASSERT] it.zeroField != 0"
+          cprintf("%ld %p\n", it.zeroField, it)
+          return false
         it = it.next
       c = c.next
   result = true
@@ -591,6 +598,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
     add(a, a.root, cast[TAddress](result), cast[TAddress](result)+%size)
   sysAssert(isAccessible(a, result), "rawAlloc 14")
   sysAssert(allocInv(a), "rawAlloc: end")
+  when logAlloc: cprintf("rawAlloc: %ld %p\n", requestedSize, result)
 
 proc rawAlloc0(a: var TMemRegion, requestedSize: int): pointer =
   result = rawAlloc(a, requestedSize)
@@ -638,6 +646,7 @@ proc rawDealloc(a: var TMemRegion, p: pointer) =
     del(a, a.root, cast[int](addr(c.data)))
     freeBigChunk(a, c)
   sysAssert(allocInv(a), "rawDealloc: end")
+  when logAlloc: cprintf("rawDealloc: %p\n", p)
 
 proc isAllocatedPtr(a: TMemRegion, p: pointer): bool = 
   if isAccessible(a, p):
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index c5d4d2aa2..48705db96 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -9,7 +9,7 @@
 
 #            Garbage Collector
 #
-# The basic algorithm is *Deferrent Reference Counting* with cycle detection.
+# The basic algorithm is *Deferred Reference Counting* with cycle detection.
 # This is achieved by combining a Deutsch-Bobrow garbage collector
 # together with Christoper's partial mark-sweep garbage collector.
 #
@@ -407,12 +407,17 @@ proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
         return
     add(gch.zct, res)
 
+{.push stackTrace: off, profiler:off.}
+proc gcInvariant*(msg: string) =
+  sysAssert(allocInv(gch.region), msg)
+{.pop.}
+
 proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
   # generates a new object and sets its reference counter to 0
+  sysAssert(allocInv(gch.region), "rawNewObj begin")
   acquire(gch)
   gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
   collectCT(gch)
-  sysAssert(allocInv(gch.region), "rawNewObj begin")
   var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
   gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
   # now it is buffered in the ZCT
@@ -517,7 +522,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
     writeCell("growObj new cell", res)
   gcTrace(ol, csZctFreed)
   gcTrace(res, csAllocated)
-  when reallyDealloc: rawDealloc(gch.region, ol)
+  when reallyDealloc: 
+    sysAssert(allocInv(gch.region), "growObj before dealloc")
+    rawDealloc(gch.region, ol)
   else:
     sysAssert(ol.typ != nil, "growObj: 5")
     zeroMem(ol, sizeof(TCell))
@@ -537,7 +544,9 @@ proc freeCyclicCell(gch: var TGcHeap, c: PCell) =
   prepareDealloc(c)
   gcTrace(c, csCycFreed)
   when logGC: writeCell("cycle collector dealloc cell", c)
-  when reallyDealloc: rawDealloc(gch.region, c)
+  when reallyDealloc: 
+    sysAssert(allocInv(gch.region), "free cyclic cell")
+    rawDealloc(gch.region, c)
   else:
     gcAssert(c.typ != nil, "freeCyclicCell")
     zeroMem(c, sizeof(TCell))
@@ -910,7 +919,9 @@ proc collectZCT(gch: var TGcHeap): bool =
       # access invalid memory. This is done by prepareDealloc():
       prepareDealloc(c)
       forAllChildren(c, waZctDecRef)
-      when reallyDealloc: rawDealloc(gch.region, c)
+      when reallyDealloc: 
+        sysAssert(allocInv(gch.region), "collectZCT: rawDealloc")
+        rawDealloc(gch.region, c)
       else:
         sysAssert(c.typ != nil, "collectZCT 2")
         zeroMem(c, sizeof(TCell))
diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim
index c9801abad..118272ee3 100644
--- a/lib/system/mmdisp.nim
+++ b/lib/system/mmdisp.nim
@@ -28,6 +28,7 @@ const
   reallyOsDealloc = true
   coalescRight = true
   coalescLeft = true
+  logAlloc = false
 
 type
   PPointer = ptr pointer