cleaned up some debugging code

This commit is contained in:
Zahary Karadjov 2013-01-20 21:19:49 +02:00
commit 86bf97a730
8 changed files with 66 additions and 110 deletions

View file

@ -188,19 +188,9 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n", linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
else: else:
if cnimdbg:
echo "ASSIGN REF ", dest.k, " ", dest.s, " ", dest.r.ropeToStr
if dest.heapRoot != nil:
echo "ROOTED AT ", dest.heapRoot.ropeToStr
linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n", linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
else: else:
if cnimdbg:
echo "ASSIGN REF ", dest.k, " ", dest.s, " ", dest.r.ropeToStr
if dest.heapRoot != nil:
echo "ROOTED AT ", dest.heapRoot.ropeToStr
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
addrLoc(dest), rdLoc(src)) addrLoc(dest), rdLoc(src))
if needToKeepAlive in flags: keepAlive(p, dest) if needToKeepAlive in flags: keepAlive(p, dest)

View file

@ -1133,8 +1133,9 @@ proc rawNewModule(module: PSym): BModule =
result = rawNewModule(module, module.filename) result = rawNewModule(module, module.filename)
proc newModule(module: PSym): BModule = proc newModule(module: PSym): BModule =
result = getCgenModule(module) # we should create only one cgen module for each module sym
if result == nil: InternalAssert getCgenModule(module) == nil
result = rawNewModule(module) result = rawNewModule(module)
growCache gModules, module.position growCache gModules, module.position
gModules[module.position] = result gModules[module.position] = result
@ -1142,9 +1143,6 @@ proc newModule(module: PSym): BModule =
if (optDeadCodeElim in gGlobalOptions): if (optDeadCodeElim in gGlobalOptions):
if (sfDeadCodeElim in module.flags): if (sfDeadCodeElim in module.flags):
InternalError("added pending module twice: " & module.filename) InternalError("added pending module twice: " & module.filename)
else:
echo "CGEN CACHED MODULE: ", result.filename
assert optCaasEnabled in gGlobalOptions
proc myOpen(module: PSym): PPassContext = proc myOpen(module: PSym): PPassContext =
result = newModule(module) result = newModule(module)
@ -1260,7 +1258,6 @@ proc updateCachedModule(m: BModule) =
let cfilenoext = changeFileExt(cfile, "") let cfilenoext = changeFileExt(cfile, "")
if mergeRequired(m): if mergeRequired(m):
echo "MERGE REQUIRED FOR ", m.filename
mergeFiles(cfile, m) mergeFiles(cfile, m)
genInitCode(m) genInitCode(m)
finishTypeDescriptions(m) finishTypeDescriptions(m)
@ -1271,6 +1268,7 @@ proc updateCachedModule(m: BModule) =
addFileToLink(cfilenoext) addFileToLink(cfilenoext)
proc cgenCaasUpdate* = proc cgenCaasUpdate* =
# XXX(zah): clean-up the fromCache mess
for m in cgenModules(): for m in cgenModules():
if m.fromCache: m.updateCachedModule if m.fromCache: m.updateCachedModule

View file

@ -143,7 +143,8 @@ proc newProc*(prc: PSym, module: BModule): BProc =
iterator cgenModules*: var BModule = iterator cgenModules*: var BModule =
for i in 0..high(gModules): for i in 0..high(gModules):
# some modules (like stdin) may exist only in memory. # ultimately, we are iterating over the file ids here.
# they won't have a cgen BModule for them and we must skip them. # some "files" won't have an associated cgen module (like stdin)
# and we must skip over them.
if gModules[i] != nil: yield gModules[i] if gModules[i] != nil: yield gModules[i]

View file

@ -509,10 +509,10 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) =
else: lexMessage(L, errInvalidCharacterConstant) else: lexMessage(L, errInvalidCharacterConstant)
else: lexMessage(L, errInvalidCharacterConstant) else: lexMessage(L, errInvalidCharacterConstant)
proc newString(s: cstring, l: int): string = proc newString(s: cstring, len: int): string =
## XXX, how come there is no support for this? ## XXX, how come there is no support for this?
result = newString(l) result = newString(len)
for i in 0 .. <l: for i in 0 .. <len:
result[i] = s[i] result[i] = s[i]
proc HandleCRLF(L: var TLexer, pos: int): int = proc HandleCRLF(L: var TLexer, pos: int): int =

View file

@ -442,7 +442,12 @@ proc resetMemory =
GC_fullCollect() GC_fullCollect()
echo GC_getStatistics() echo GC_getStatistics()
const
SimiluateCaasMemReset = false
PrintRopeCacheStats = false
proc MainCommand = proc MainCommand =
when SimiluateCaasMemReset:
gGlobalOptions.incl(optCaasEnabled) gGlobalOptions.incl(optCaasEnabled)
# In "nimrod serve" scenario, each command must reset the registered passes # In "nimrod serve" scenario, each command must reset the registered passes
@ -561,19 +566,21 @@ proc MainCommand =
gGlobalOptions.incl(optCaasEnabled) gGlobalOptions.incl(optCaasEnabled)
msgs.gErrorMax = high(int) # do not stop after first error msgs.gErrorMax = high(int) # do not stop after first error
serve(MainCommand) serve(MainCommand)
else:
else: rawMessage(errInvalidCommandX, command) rawMessage(errInvalidCommandX, command)
if msgs.gErrorCounter == 0 and gCmd notin {cmdInterpret, cmdRun}: if msgs.gErrorCounter == 0 and gCmd notin {cmdInterpret, cmdRun}:
rawMessage(hintSuccessX, [$gLinesCompiled, rawMessage(hintSuccessX, [$gLinesCompiled,
formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3), formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3),
formatSize(getTotalMem())]) formatSize(getTotalMem())])
when PrintRopeCacheStats:
echo "rope cache stats: " echo "rope cache stats: "
echo " tries : ", gCacheTries echo " tries : ", gCacheTries
echo " misses: ", gCacheMisses echo " misses: ", gCacheMisses
echo " int tries: ", gCacheIntTries echo " int tries: ", gCacheIntTries
echo " efficiency: ", formatFloat(1-(gCacheMisses.float/gCacheTries.float), ffDecimal, 3) echo " efficiency: ", formatFloat(1-(gCacheMisses.float/gCacheTries.float), ffDecimal, 3)
# resetMemory() when SimiluateCaasMemReset:
resetMemory()

View file

@ -96,6 +96,8 @@ const
# XXX: still has problems in release mode in the compiler itself. # XXX: still has problems in release mode in the compiler itself.
# investigate how it affects growObj # investigate how it affects growObj
CollectCyclesStats = false
type type
TWalkOp = enum TWalkOp = enum
waPush waPush
@ -203,8 +205,6 @@ proc addZCT(zct: var TCellSeq, c: PCell) {.noinline.} =
if c.isBitDown(rcZct): if c.isBitDown(rcZct):
c.setBit rcZct c.setBit rcZct
zct.add c zct.add c
# writecell("adding to ZCT 1", c)
# cprintf ("called from %d\n", framePtr.prev.line)
template setStackTop(gch) = template setStackTop(gch) =
# This must be called immediately after we enter the GC code # This must be called immediately after we enter the GC code
@ -257,7 +257,6 @@ proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp)
# we need the prototype here for debugging purposes # we need the prototype here for debugging purposes
proc prepareDealloc(cell: PCell) = proc prepareDealloc(cell: PCell) =
# writecell("finalizers", cell)
if cell.typ.finalizer != nil: if cell.typ.finalizer != nil:
# the finalizer could invoke something that # the finalizer could invoke something that
# allocates memory; this could trigger a garbage # allocates memory; this could trigger a garbage
@ -397,7 +396,6 @@ template doDecRef(cc: PCell,
# this is the last reference from the heap # this is the last reference from the heap
# add to a zero-count-table that will be matched against stack pointers # add to a zero-count-table that will be matched against stack pointers
rtlAddZCT(c) rtlAddZCT(c)
# writeCell("decref to 0", c)
else: else:
when cycleFlag != Acyclic: when cycleFlag != Acyclic:
if cycleFlag == Cyclic or canBeCycleRoot(c): if cycleFlag == Cyclic or canBeCycleRoot(c):
@ -559,7 +557,6 @@ proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
# all slots 68% # all slots 68%
var L = gch.zct.len var L = gch.zct.len
var d = gch.zct.d var d = gch.zct.d
#writecell("ZCT ADDING 2", res)
when true: when true:
# loop unrolled for performance: # loop unrolled for performance:
template replaceZctEntry(i: expr) = template replaceZctEntry(i: expr) =
@ -622,7 +619,6 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap, rc1: bool): pointer =
addNewObjToZCT(res, gch) addNewObjToZCT(res, gch)
if NewObjectsAreCycleRoots and canBeCycleRoot(res): if NewObjectsAreCycleRoots and canBeCycleRoot(res):
# writeCell("cyclic allocation", res)
res.setBit(rcInCycleRoots) res.setBit(rcInCycleRoots)
res.setColor rcCycleCandidate res.setColor rcCycleCandidate
gch.cycleRoots.add res gch.cycleRoots.add res
@ -647,7 +643,6 @@ proc freeCell(gch: var TGcHeap, c: PCell) =
else: else:
sysAssert(c.typ != nil, "collectCycles") sysAssert(c.typ != nil, "collectCycles")
zeroMem(c, sizeof(TCell)) zeroMem(c, sizeof(TCell))
# writecell("nuked cell", c)
template eraseAt(cells: var TCellSeq, at: int): stmt = template eraseAt(cells: var TCellSeq, at: int): stmt =
cells.d[at] = cells.d[cells.len - 1] cells.d[at] = cells.d[cells.len - 1]
@ -706,16 +701,13 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
var d = gch.zct.d var d = gch.zct.d
while j >= 0: while j >= 0:
if d[j] == ol: if d[j] == ol:
#writecell("replaced old", ol)
d[j] = res d[j] = res
#writecell("replaced new", res)
break break
dec(j) dec(j)
if ol.isBitUp(rcInCycleRoots): if ol.isBitUp(rcInCycleRoots):
for i in 0 .. <gch.cycleRoots.len: for i in 0 .. <gch.cycleRoots.len:
if gch.cycleRoots.d[i] == ol: if gch.cycleRoots.d[i] == ol:
#writecell("evicted cycleroot", ol)
eraseAt(gch.cycleRoots, i) eraseAt(gch.cycleRoots, i)
freeCell(gch, ol) freeCell(gch, ol)
@ -785,9 +777,7 @@ proc collectCycles(gch: var TGcHeap) =
if gch.cycleRoots.len == 0: return if gch.cycleRoots.len == 0: return
gch.stat.cycleTableSize = max(gch.stat.cycleTableSize, gch.cycleRoots.len) gch.stat.cycleTableSize = max(gch.stat.cycleTableSize, gch.cycleRoots.len)
#c_printf "collect cycles table:\n" when CollectCyclesStats:
#for i in 0 .. <gch.cycleRoots.len:
# writecell("CROOT ", gch.cycleRoots.d[i])
let l0 = gch.cycleRoots.len let l0 = gch.cycleRoots.len
let tStart = getTicks() let tStart = getTicks()
@ -826,6 +816,8 @@ proc collectCycles(gch: var TGcHeap) =
earlyMarkAliveRec(c) earlyMarkAliveRec(c)
earlyMarkAlive(gch.decStack) earlyMarkAlive(gch.decStack)
when CollectCyclesStats:
let tAfterEarlyMarkAlive = getTicks() let tAfterEarlyMarkAlive = getTicks()
template recursiveDecRef(cell) = template recursiveDecRef(cell) =
@ -843,7 +835,6 @@ proc collectCycles(gch: var TGcHeap) =
inc decrefs inc decrefs
if c.color != rcDecRefApplied: if c.color != rcDecRefApplied:
c.setColor rcDecRefApplied c.setColor rcDecRefApplied
# writeCell("decref", c)
c.forAllChildren waPush c.forAllChildren waPush
template markRoots(roots) = template markRoots(roots) =
@ -862,8 +853,9 @@ proc collectCycles(gch: var TGcHeap) =
freeCell(gch, c) freeCell(gch, c)
markRoots(gch.cycleRoots) markRoots(gch.cycleRoots)
let tAfterMark = getTicks()
when CollectCyclesStats:
let tAfterMark = getTicks()
c_printf "COLLECT CYCLES %d: %d/%d\n", gcCollectionIdx, gch.cycleRoots.len, l0 c_printf "COLLECT CYCLES %d: %d/%d\n", gcCollectionIdx, gch.cycleRoots.len, l0
template recursiveMarkAlive(cell) = template recursiveMarkAlive(cell) =
@ -877,7 +869,6 @@ proc collectCycles(gch: var TGcHeap) =
if ignoreObject(c): continue if ignoreObject(c): continue
inc c.refcount, rcIncrement inc c.refcount, rcIncrement
inc increfs inc increfs
# writeCell("mark alive", c)
if c.color != rcAlive: if c.color != rcAlive:
c.setColor rcAlive c.setColor rcAlive
@ -905,6 +896,8 @@ proc collectCycles(gch: var TGcHeap) =
c.forAllChildren waPush c.forAllChildren waPush
scanRoots(gch.cycleRoots) scanRoots(gch.cycleRoots)
when CollectCyclesStats:
let tAfterScan = getTicks() let tAfterScan = getTicks()
template collectDead(roots) = template collectDead(roots) =
@ -938,8 +931,9 @@ proc collectCycles(gch: var TGcHeap) =
freeCell(gch, gch.freeStack.d[i]) freeCell(gch, gch.freeStack.d[i])
collectDead(gch.cycleRoots) collectDead(gch.cycleRoots)
let tFinal = getTicks()
when CollectCyclesStats:
let tFinal = getTicks()
cprintf "times:\n early mark alive: %d ms\n mark: %d ms\n scan: %d ms\n collect: %d ms\n decrefs: %d\n increfs: %d\n marked dead: %d\n collected: %d\n", cprintf "times:\n early mark alive: %d ms\n mark: %d ms\n scan: %d ms\n collect: %d ms\n decrefs: %d\n increfs: %d\n marked dead: %d\n collected: %d\n",
(tAfterEarlyMarkAlive - tStart) div 1_000_000, (tAfterEarlyMarkAlive - tStart) div 1_000_000,
(tAfterMark - tAfterEarlyMarkAlive) div 1_000_000, (tAfterMark - tAfterEarlyMarkAlive) div 1_000_000,
@ -963,20 +957,7 @@ proc collectCycles(gch: var TGcHeap) =
# CollectZCT may add new cycle candidates and we may decide to loop here # CollectZCT may add new cycle candidates and we may decide to loop here
# if gch.cycleRoots.len > 0: repeat # if gch.cycleRoots.len > 0: repeat
# quit 1
var gcDebugging* = false var gcDebugging* = false
var vis*: proc (a: pointer, b: PNimType)
proc debugNode(n: ptr TNimNode) =
c_fprintf(c_stdout, "node %s\n", n.name)
for i in 0..n.len-1:
debugNode(n.sons[i])
proc debugTyp(x: PNimType) =
c_fprintf(c_stdout, "type %d\n", x.kind)
if x.node != nil:
debugNode(x.node)
var seqdbg* : proc (s: PGenericSeq) {.cdecl.} var seqdbg* : proc (s: PGenericSeq) {.cdecl.}
@ -992,7 +973,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
# mark the cell: # mark the cell:
if objStart.isBitDown(rcReallyDead): if objStart.isBitDown(rcReallyDead):
if gcDebugging: if gcDebugging:
writeCell("marking ", objStart) # writeCell("marking ", objStart)
else: else:
inc objStart.refcount, rcIncrement inc objStart.refcount, rcIncrement
gch.decStack.add objStart gch.decStack.add objStart
@ -1174,18 +1155,14 @@ proc releaseCell(gch: var TGcHeap, cell: PCell) =
prepareDealloc(cell) prepareDealloc(cell)
cell.setColor rcReallyDead cell.setColor rcReallyDead
#writecell("RELEASING ", cell)
let l1 = gch.tempStack.len let l1 = gch.tempStack.len
cell.forAllChildren waPush cell.forAllChildren waPush
let l2 = gch.tempStack.len let l2 = gch.tempStack.len
for i in l1 .. <l2: for i in l1 .. <l2:
var cc = gch.tempStack.d[i] var cc = gch.tempStack.d[i]
#writecell("SON ", cc)
if cc.refcount--(LocalHeap): if cc.refcount--(LocalHeap):
releaseCell(gch, cc) releaseCell(gch, cc)
else: else:
#writecell("crashy", cc)
if canbeCycleRoot(cc): if canbeCycleRoot(cc):
addCycleRoot(gch.cycleRoots, cc) addCycleRoot(gch.cycleRoots, cc)
@ -1203,10 +1180,6 @@ proc releaseCell(gch: var TGcHeap, cell: PCell) =
# We can ignore it now as the ZCT cleaner will reach it soon. # We can ignore it now as the ZCT cleaner will reach it soon.
proc CollectZCT(gch: var TGcHeap): bool = proc CollectZCT(gch: var TGcHeap): bool =
#cprintf "ZCT TABLE START:\n"
#for i in 0 .. <gch.zct.len:
# writecell("ZCT CELL", gch.zct.d[i])
#cprintf "ZCT TABLE END\n"
const workPackage = 100 const workPackage = 100
var L = addr(gch.zct.len) var L = addr(gch.zct.len)
@ -1217,14 +1190,10 @@ proc CollectZCT(gch: var TGcHeap): bool =
while L[] > 0: while L[] > 0:
var c = gch.zct.d[0] var c = gch.zct.d[0]
if c.isBitDown(rcZct): sysAssert c.isBitUp(rcZct), "CollectZCT: rcZct missing!"
writecell("BAD ZCT", c)
quit 1
# writecell("ZCT PROCESS", c)
sysAssert(isAllocatedPtr(gch.region, c), "CollectZCT: isAllocatedPtr") sysAssert(isAllocatedPtr(gch.region, c), "CollectZCT: isAllocatedPtr")
# remove from ZCT:
sysAssert((c.refcount and rcZct) == rcZct, "collectZCT")
# remove from ZCT:
c.clearBit(rcZct) c.clearBit(rcZct)
gch.zct.d[0] = gch.zct.d[L[] - 1] gch.zct.d[0] = gch.zct.d[L[] - 1]
dec(L[]) dec(L[])
@ -1238,13 +1207,9 @@ proc CollectZCT(gch: var TGcHeap): bool =
# freed. **KEEP THIS IN MIND WHEN MAKING THIS INCREMENTAL!** # freed. **KEEP THIS IN MIND WHEN MAKING THIS INCREMENTAL!**
if c.color == rcRetiredBuffer: if c.color == rcRetiredBuffer:
if c.isBitDown(rcInCycleRoots): if c.isBitDown(rcInCycleRoots):
# writecell("retired buffer", c)
freeCell(gch, c) freeCell(gch, c)
else: else:
if c.color == rcReallyDead: # if c.color == rcReallyDead: writeCell("ReallyDead in ZCT?", c)
# writeCell("ReallyDead in ZCT?", c)
# writecell("bad cell in zct", c)
releaseCell(gch, c) releaseCell(gch, c)
when withRealtime: when withRealtime:
if steps == 0: if steps == 0:
@ -1270,7 +1235,6 @@ proc unmarkStackAndRegisters(gch: var TGcHeap) =
sysAssert c.typ != nil, "unmarkStackAndRegisters 2" sysAssert c.typ != nil, "unmarkStackAndRegisters 2"
if c.color == rcRetiredBuffer: if c.color == rcRetiredBuffer:
# writecell("unmark retired", c)
continue continue
# XXX no need for an atomic dec here: # XXX no need for an atomic dec here:
@ -1284,11 +1248,8 @@ proc unmarkStackAndRegisters(gch: var TGcHeap) =
# a leak if it's orphaned through the stack reference # a leak if it's orphaned through the stack reference
# that's because the write-barrier won't be executed for stack # that's because the write-barrier won't be executed for stack
# locations # locations
#writeCell("restoring balance cycle roots", c)
addCycleRoot(gch.cycleRoots, c) addCycleRoot(gch.cycleRoots, c)
#writecell("unmark stack cell", c)
gch.decStack.len = 0 gch.decStack.len = 0
proc collectCTBody(gch: var TGcHeap) = proc collectCTBody(gch: var TGcHeap) =

View file

@ -14,14 +14,14 @@
{.push checks:off.} {.push checks:off.}
const const
debugGC = true # we wish to debug the GC... debugGC = false # we wish to debug the GC...
logGC = false logGC = false
traceGC = true # extensive debugging traceGC = false # extensive debugging
alwaysCycleGC = false alwaysCycleGC = false
alwaysGC = false # collect after every memory allocation (for debugging) alwaysGC = false # collect after every memory allocation (for debugging)
leakDetector = false leakDetector = false
overwriteFree = false overwriteFree = false
trackAllocationSource = true or leakDetector trackAllocationSource = leakDetector
cycleGC = true # (de)activate the cycle GC cycleGC = true # (de)activate the cycle GC
reallyDealloc = true # for debugging purposes this can be set to false reallyDealloc = true # for debugging purposes this can be set to false

View file

@ -213,7 +213,6 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic) doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic)
gch.tempStack.len = len0 gch.tempStack.len = len0
# XXX add a proper addCycleRoot barrier here!
# and set the memory to nil: # and set the memory to nil:
zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +% zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +%
(newLen*%elemSize)), (result.len-%newLen) *% elemSize) (newLen*%elemSize)), (result.len-%newLen) *% elemSize)