diff options
author | Araq <rumpf_a@web.de> | 2015-11-30 11:17:22 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-12-01 00:53:30 +0100 |
commit | 10530add48c02f6b9bdead653c44386ad9165875 (patch) | |
tree | a922dcaba5476f2ab4df314d4730e55af4fa1ca3 | |
parent | 9ed635d5c092afdcbd9a6313ccf1dcd37c5344db (diff) | |
download | Nim-10530add48c02f6b9bdead653c44386ad9165875.tar.gz |
next steps for the GC
-rw-r--r-- | lib/system/gc2.nim | 27 | ||||
-rw-r--r-- | lib/system/mmdisp.nim | 2 |
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 |