summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-11-30 11:17:22 +0100
committerAraq <rumpf_a@web.de>2015-12-01 00:53:30 +0100
commit10530add48c02f6b9bdead653c44386ad9165875 (patch)
treea922dcaba5476f2ab4df314d4730e55af4fa1ca3
parent9ed635d5c092afdcbd9a6313ccf1dcd37c5344db (diff)
downloadNim-10530add48c02f6b9bdead653c44386ad9165875.tar.gz
next steps for the GC
-rw-r--r--lib/system/gc2.nim27
-rw-r--r--lib/system/mmdisp.nim2
2 files changed, 23 insertions, 6 deletions
diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim
index 1a51284f0..a4a08ab2c 100644
--- a/lib/system/gc2.nim
+++ b/lib/system/gc2.nim
@@ -39,9 +39,9 @@ iterToProc(allObjects, ptr ObjectSpaceIter, allObjectsAsProc)
 
 const
   rcIncrement = 0b1000 # so that lowest 3 bits are not touched
-  rcWhite = 0b000  # cell is colored white
+  rcBlack = 0b000
   rcGrey = 0b001   # traditional color for incremental mark&sweep
-  rcBlack = 0b010  # marked as alive; direct children also have been processed
+  rcWhite = 0b010
   rcUnused = 0b011
   ZctFlag = 0b100  # in ZCT
   rcShift = 3      # shift by rcShift to get the reference counter
@@ -153,7 +153,7 @@ when BitsPerPage mod (sizeof(int)*8) != 0:
 
 template color(c): expr = c.refCount and colorMask
 template setColor(c, col) =
-  when col == rcWhite:
+  when col == rcBlack:
     c.refcount = c.refcount and not colorMask
   else:
     c.refcount = c.refcount and not colorMask or col
@@ -584,6 +584,12 @@ template checkTime {.dirty.} =
 # ---------------- cycle collector -------------------------------------------
 
 proc freeCyclicCell(gch: var GcHeap, c: PCell) =
+  gcAssert(isAllocatedPtr(gch.region, c), "freeCyclicCell: freed pointer?")
+
+  var d = gch.decStack.d
+  for i in 0..gch.decStack.len-1:
+    gcAssert d[i] != c, "wtf man, freeing obviously alive stuff?!!"
+
   prepareDealloc(c)
   gcTrace(c, csCycFreed)
   when logGC: writeCell("cycle collector dealloc cell", c)
@@ -606,7 +612,7 @@ proc sweep(gch: var GcHeap): bool =
       var c = cast[PCell](x)
       gcAssert c.color != rcGrey, "cell is still grey?"
       if c.color == rcWhite: freeCyclicCell(gch, c)
-      else: c.setColor(rcWhite)
+      #else: c.setColor(rcWhite)
     checkTime()
   # prepare for next iteration:
   echo "loop end"
@@ -614,9 +620,20 @@ proc sweep(gch: var GcHeap): bool =
   result = true
 
 proc markS(gch: var GcHeap, c: PCell) =
-  if c.color == rcWhite:
+  # since we start with 'black' cells, we need to mark them here too:
+  if c.color != rcGrey:
     c.setColor(rcGrey)
     add(gch.greyStack, c)
+  when false:
+    # since we start with 'black' cells, we need to mark them unconditionally
+    # here. But this means that we mark too much. Duplicate roots (which can
+    # often happen for stack slots) lead to somewhat duplicate marking.
+    # XXX We could maybe prevent this somehow?
+    if c.color == rcWhite:
+      c.setColor(rcGrey)
+      add(gch.greyStack, c)
+    #elif c.color == rcBlack:
+    #  echo "cell is black?!"
   #forAllChildren(c, waMarkGrey)
   #x.setColor(rcBlack)
 
diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim
index 1c13f3ff8..4a06e5e70 100644
--- a/lib/system/mmdisp.nim
+++ b/lib/system/mmdisp.nim
@@ -17,7 +17,7 @@ const
   debugGC = false # we wish to debug the GC...
   logGC = false
   traceGC = false # extensive debugging
-  alwaysCycleGC = false
+  alwaysCycleGC = true
   alwaysGC = defined(fulldebug) # collect after every memory
                                 # allocation (for debugging)
   leakDetector = false