first compiling version of the new GC
This commit is contained in:
parent
0d8c762452
commit
070403ca5e
2 changed files with 46 additions and 19 deletions
|
|
@ -31,6 +31,12 @@ when withRealTime and not declared(getTicks):
|
||||||
when defined(memProfiler):
|
when defined(memProfiler):
|
||||||
proc nimProfile(requestedSize: int) {.benign.}
|
proc nimProfile(requestedSize: int) {.benign.}
|
||||||
|
|
||||||
|
type
|
||||||
|
ObjectSpaceIter = object
|
||||||
|
state: range[-1..0]
|
||||||
|
|
||||||
|
iterToProc(allObjects, ptr ObjectSpaceIter, allObjectsAsProc)
|
||||||
|
|
||||||
const
|
const
|
||||||
rcIncrement = 0b1000 # so that lowest 3 bits are not touched
|
rcIncrement = 0b1000 # so that lowest 3 bits are not touched
|
||||||
rcWhite = 0b000 # cell is colored white
|
rcWhite = 0b000 # cell is colored white
|
||||||
|
|
@ -85,6 +91,7 @@ type
|
||||||
region: MemRegion # garbage collected region
|
region: MemRegion # garbage collected region
|
||||||
stat: GcStat
|
stat: GcStat
|
||||||
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
||||||
|
spaceIter: ObjectSpaceIter
|
||||||
|
|
||||||
var
|
var
|
||||||
gch {.rtlThreadVar.}: GcHeap
|
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 =
|
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
collectCT(gch)
|
collectCT(gch)
|
||||||
var ol = usrToCell(old)
|
var ol = usrToCell(old)
|
||||||
|
gcAssert(isAllocatedPtr(gch.region, ol), "growObj: freed pointer?")
|
||||||
|
|
||||||
sysAssert(ol.typ != nil, "growObj: 1")
|
sysAssert(ol.typ != nil, "growObj: 1")
|
||||||
gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
|
gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
|
||||||
sysAssert(allocInv(gch.region), "growObj begin")
|
sysAssert(allocInv(gch.region), "growObj begin")
|
||||||
|
|
@ -547,6 +556,7 @@ proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
|
||||||
|
|
||||||
template takeStartTime(workPackageSize) {.dirty.} =
|
template takeStartTime(workPackageSize) {.dirty.} =
|
||||||
const workPackage = workPackageSize
|
const workPackage = workPackageSize
|
||||||
|
var debugticker = 1000
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
var steps = workPackage
|
var steps = workPackage
|
||||||
var t0: Ticks
|
var t0: Ticks
|
||||||
|
|
@ -554,8 +564,12 @@ template takeStartTime(workPackageSize) {.dirty.} =
|
||||||
|
|
||||||
template takeTime {.dirty.} =
|
template takeTime {.dirty.} =
|
||||||
when withRealTime: dec steps
|
when withRealTime: dec steps
|
||||||
|
dec debugticker
|
||||||
|
|
||||||
template checkTime {.dirty.} =
|
template checkTime {.dirty.} =
|
||||||
|
if debugticker <= 0:
|
||||||
|
echo "in loop"
|
||||||
|
debugticker = 1000
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
if steps == 0:
|
if steps == 0:
|
||||||
steps = workPackage
|
steps = workPackage
|
||||||
|
|
@ -580,35 +594,45 @@ proc freeCyclicCell(gch: var GcHeap, c: PCell) =
|
||||||
gcAssert(c.typ != nil, "freeCyclicCell")
|
gcAssert(c.typ != nil, "freeCyclicCell")
|
||||||
zeroMem(c, sizeof(Cell))
|
zeroMem(c, sizeof(Cell))
|
||||||
|
|
||||||
proc sweep(gch: var GcHeap) =
|
proc sweep(gch: var GcHeap): bool =
|
||||||
# XXX make this incremental!
|
takeStartTime(100)
|
||||||
for x in allObjects(gch.region):
|
echo "loop start"
|
||||||
|
while true:
|
||||||
|
let x = allObjectsAsProc(gch.region, addr gch.spaceIter)
|
||||||
|
if gch.spaceIter.state < 0: break
|
||||||
|
takeTime()
|
||||||
if isCell(x):
|
if isCell(x):
|
||||||
# cast to PCell is correct here:
|
# cast to PCell is correct here:
|
||||||
var c = cast[PCell](x)
|
var c = cast[PCell](x)
|
||||||
if c.color == rcWhite: freeCyclicCell(gch, c)
|
if c.color == rcWhite: freeCyclicCell(gch, c)
|
||||||
else: c.setColor(rcWhite)
|
else: c.setColor(rcWhite)
|
||||||
|
checkTime()
|
||||||
|
# prepare for next iteration:
|
||||||
|
echo "loop end"
|
||||||
|
gch.spaceIter = ObjectSpaceIter()
|
||||||
|
result = true
|
||||||
|
|
||||||
proc markS(gch: var GcHeap, c: PCell) =
|
proc markS(gch: var GcHeap, c: PCell) =
|
||||||
if x.color != rcGrey:
|
if c.color != rcGrey:
|
||||||
x.setColor(rcGrey)
|
c.setColor(rcGrey)
|
||||||
add(gch.greyStack, x)
|
add(gch.greyStack, c)
|
||||||
#forAllChildren(c, waMarkGrey)
|
#forAllChildren(c, waMarkGrey)
|
||||||
#x.setColor(rcBlack)
|
#x.setColor(rcBlack)
|
||||||
|
|
||||||
proc markIncrementally(gch: var GcHeap): bool =
|
proc markIncremental(gch: var GcHeap): bool =
|
||||||
var L = addr(gch.greyStack.len)
|
var L = addr(gch.greyStack.len)
|
||||||
takeStartTime(100)
|
takeStartTime(100)
|
||||||
while L[] > 0:
|
while L[] > 0:
|
||||||
var c = gch.greyStack.d[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]
|
gch.greyStack.d[0] = gch.greyStack.d[L[] - 1]
|
||||||
dec(L[])
|
dec(L[])
|
||||||
takeTime()
|
takeTime()
|
||||||
if c.color == clGrey:
|
if c.color == rcGrey:
|
||||||
|
c.setColor(rcBlack)
|
||||||
forAllChildren(c, waMarkGrey)
|
forAllChildren(c, waMarkGrey)
|
||||||
c.setColor(clBlack)
|
|
||||||
checkTime()
|
checkTime()
|
||||||
|
gcAssert gch.greyStack.len == 0, "markIncremental: greystack not empty "
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc markGlobals(gch: var GcHeap) =
|
proc markGlobals(gch: var GcHeap) =
|
||||||
|
|
@ -616,7 +640,7 @@ proc markGlobals(gch: var GcHeap) =
|
||||||
|
|
||||||
proc markLocals(gch: var GcHeap) =
|
proc markLocals(gch: var GcHeap) =
|
||||||
var d = gch.decStack.d
|
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"
|
sysAssert isAllocatedPtr(gch.region, d[i]), "markLocals"
|
||||||
markS(gch, d[i])
|
markS(gch, d[i])
|
||||||
|
|
||||||
|
|
@ -666,7 +690,7 @@ proc doOperation(p: pointer, op: WalkOp) =
|
||||||
else:
|
else:
|
||||||
markS(gch, c)
|
markS(gch, c)
|
||||||
of waMarkGrey:
|
of waMarkGrey:
|
||||||
if x.color != rcGrey:
|
if c.color != rcBlack:
|
||||||
c.setColor(rcGrey)
|
c.setColor(rcGrey)
|
||||||
add(gch.greyStack, c)
|
add(gch.greyStack, c)
|
||||||
#of waDebug: debugGraph(c)
|
#of waDebug: debugGraph(c)
|
||||||
|
|
@ -681,13 +705,16 @@ proc collectCycles(gch: var GcHeap): bool =
|
||||||
while gch.zct.len > 0: discard collectZCT(gch)
|
while gch.zct.len > 0: discard collectZCT(gch)
|
||||||
markGlobals(gch)
|
markGlobals(gch)
|
||||||
markLocals(gch)
|
markLocals(gch)
|
||||||
if markIncrementally(gch):
|
case gch.phase
|
||||||
|
of Phase.None, Phase.Marking:
|
||||||
|
gch.phase = Phase.Marking
|
||||||
|
if markIncremental(gch):
|
||||||
gch.phase = Phase.Sweeping
|
gch.phase = Phase.Sweeping
|
||||||
sweep(gch)
|
of Phase.Sweeping:
|
||||||
|
gcAssert gch.greyStack.len == 0, "greystack not empty"
|
||||||
|
if sweep(gch):
|
||||||
gch.phase = Phase.None
|
gch.phase = Phase.None
|
||||||
result = true
|
result = true
|
||||||
else:
|
|
||||||
gch.phase = Phase.Marking
|
|
||||||
|
|
||||||
proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
|
proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
|
||||||
# the addresses are not as cells on the stack, so turn them to cells:
|
# the addresses are not as cells on the stack, so turn them to cells:
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
# we need to decref here, otherwise the GC leaks!
|
# we need to decref here, otherwise the GC leaks!
|
||||||
when not defined(boehmGC) and not defined(nogc) and
|
when not defined(boehmGC) and not defined(nogc) and
|
||||||
not defined(gcMarkAndSweep) and not defined(gogc):
|
not defined(gcMarkAndSweep) and not defined(gogc):
|
||||||
when compileOption("gc", "v2"):
|
when false: # compileOption("gc", "v2"):
|
||||||
for i in newLen..result.len-1:
|
for i in newLen..result.len-1:
|
||||||
let len0 = gch.tempStack.len
|
let len0 = gch.tempStack.len
|
||||||
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue