summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-11-30 00:23:23 +0100
committerAraq <rumpf_a@web.de>2015-12-01 00:53:30 +0100
commit070403ca5eb9e7c1c9cdea5f930022408fca5000 (patch)
treecedbbcd44e64dd45018b0a975bd9fba345e12f7c
parent0d8c7624521207449f1b9194ed00084ebcb1c5f2 (diff)
downloadNim-070403ca5eb9e7c1c9cdea5f930022408fca5000.tar.gz
first compiling version of the new GC
-rw-r--r--lib/system/gc2.nim63
-rw-r--r--lib/system/sysstr.nim2
2 files changed, 46 insertions, 19 deletions
diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim
index 78901b1dc..89f299436 100644
--- a/lib/system/gc2.nim
+++ b/lib/system/gc2.nim
@@ -31,6 +31,12 @@ when withRealTime and not declared(getTicks):
 when defined(memProfiler):
   proc nimProfile(requestedSize: int) {.benign.}
 
+type
+  ObjectSpaceIter = object
+    state: range[-1..0]
+
+iterToProc(allObjects, ptr ObjectSpaceIter, allObjectsAsProc)
+
 const
   rcIncrement = 0b1000 # so that lowest 3 bits are not touched
   rcWhite = 0b000  # cell is colored white
@@ -85,6 +91,7 @@ type
     region: MemRegion        # garbage collected region
     stat: GcStat
     additionalRoots: CellSeq # dummy roots for GC_ref/unref
+    spaceIter: ObjectSpaceIter
 
 var
   gch {.rtlThreadVar.}: GcHeap
@@ -487,6 +494,8 @@ proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
 proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
   collectCT(gch)
   var ol = usrToCell(old)
+  gcAssert(isAllocatedPtr(gch.region, ol), "growObj: freed pointer?")
+
   sysAssert(ol.typ != nil, "growObj: 1")
   gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
   sysAssert(allocInv(gch.region), "growObj begin")
@@ -547,6 +556,7 @@ proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
 
 template takeStartTime(workPackageSize) {.dirty.} =
   const workPackage = workPackageSize
+  var debugticker = 1000
   when withRealTime:
     var steps = workPackage
     var t0: Ticks
@@ -554,8 +564,12 @@ template takeStartTime(workPackageSize) {.dirty.} =
 
 template takeTime {.dirty.} =
   when withRealTime: dec steps
+  dec debugticker
 
 template checkTime {.dirty.} =
+  if debugticker <= 0:
+    echo "in loop"
+    debugticker = 1000
   when withRealTime:
     if steps == 0:
       steps = workPackage
@@ -580,35 +594,45 @@ proc freeCyclicCell(gch: var GcHeap, c: PCell) =
     gcAssert(c.typ != nil, "freeCyclicCell")
     zeroMem(c, sizeof(Cell))
 
-proc sweep(gch: var GcHeap) =
-  # XXX make this incremental!
-  for x in allObjects(gch.region):
+proc sweep(gch: var GcHeap): bool =
+  takeStartTime(100)
+  echo "loop start"
+  while true:
+    let x = allObjectsAsProc(gch.region, addr gch.spaceIter)
+    if gch.spaceIter.state < 0: break
+    takeTime()
     if isCell(x):
       # cast to PCell is correct here:
       var c = cast[PCell](x)
       if c.color == rcWhite: freeCyclicCell(gch, c)
       else: c.setColor(rcWhite)
+    checkTime()
+  # prepare for next iteration:
+  echo "loop end"
+  gch.spaceIter = ObjectSpaceIter()
+  result = true
 
 proc markS(gch: var GcHeap, c: PCell) =
-  if x.color != rcGrey:
-    x.setColor(rcGrey)
-    add(gch.greyStack, x)
+  if c.color != rcGrey:
+    c.setColor(rcGrey)
+    add(gch.greyStack, c)
   #forAllChildren(c, waMarkGrey)
   #x.setColor(rcBlack)
 
-proc markIncrementally(gch: var GcHeap): bool =
+proc markIncremental(gch: var GcHeap): bool =
   var L = addr(gch.greyStack.len)
   takeStartTime(100)
   while L[] > 0:
     var c = gch.greyStack.d[0]
-    sysAssert(isAllocatedPtr(gch.region, c), "CollectZCT: isAllocatedPtr")
+    sysAssert(isAllocatedPtr(gch.region, c), "markIncremental: isAllocatedPtr")
     gch.greyStack.d[0] = gch.greyStack.d[L[] - 1]
     dec(L[])
     takeTime()
-    if c.color == clGrey:
+    if c.color == rcGrey:
+      c.setColor(rcBlack)
       forAllChildren(c, waMarkGrey)
-      c.setColor(clBlack)
     checkTime()
+  gcAssert gch.greyStack.len == 0, "markIncremental: greystack not empty "
   result = true
 
 proc markGlobals(gch: var GcHeap) =
@@ -616,7 +640,7 @@ proc markGlobals(gch: var GcHeap) =
 
 proc markLocals(gch: var GcHeap) =
   var d = gch.decStack.d
-  for i in 0..<gch.decStack.len:
+  for i in 0 .. < gch.decStack.len:
     sysAssert isAllocatedPtr(gch.region, d[i]), "markLocals"
     markS(gch, d[i])
 
@@ -666,7 +690,7 @@ proc doOperation(p: pointer, op: WalkOp) =
     else:
       markS(gch, c)
   of waMarkGrey:
-    if x.color != rcGrey:
+    if c.color != rcBlack:
       c.setColor(rcGrey)
       add(gch.greyStack, c)
   #of waDebug: debugGraph(c)
@@ -681,13 +705,16 @@ proc collectCycles(gch: var GcHeap): bool =
   while gch.zct.len > 0: discard collectZCT(gch)
   markGlobals(gch)
   markLocals(gch)
-  if markIncrementally(gch):
-    gch.phase = Phase.Sweeping
-    sweep(gch)
-    gch.phase = Phase.None
-    result = true
-  else:
+  case gch.phase
+  of Phase.None, Phase.Marking:
     gch.phase = Phase.Marking
+    if markIncremental(gch):
+      gch.phase = Phase.Sweeping
+  of Phase.Sweeping:
+    gcAssert gch.greyStack.len == 0, "greystack not empty"
+    if sweep(gch):
+      gch.phase = Phase.None
+      result = true
 
 proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
   # the addresses are not as cells on the stack, so turn them to cells:
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 326c601bd..e2137e8f4 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -229,7 +229,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
     # we need to decref here, otherwise the GC leaks!
     when not defined(boehmGC) and not defined(nogc) and
          not defined(gcMarkAndSweep) and not defined(gogc):
-      when compileOption("gc", "v2"):
+      when false: # compileOption("gc", "v2"):
         for i in newLen..result.len-1:
           let len0 = gch.tempStack.len
           forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%