Mark&Sweep GC: introduce nimTracing define for debugging
This commit is contained in:
parent
00295366b5
commit
7adf3bf476
2 changed files with 42 additions and 2 deletions
|
|
@ -178,7 +178,10 @@ proc writeCell(file: File; msg: cstring, c: PCell) =
|
||||||
let id = c.id
|
let id = c.id
|
||||||
else:
|
else:
|
||||||
let id = c
|
let id = c
|
||||||
when leakDetector:
|
when defined(nimTypeNames):
|
||||||
|
c_fprintf(file, "%s %p %d escaped=%ld color=%c of type %s\n",
|
||||||
|
msg, id, kind, didEscape(c), col, c.typ.name)
|
||||||
|
elif leakDetector:
|
||||||
c_fprintf(file, "%s %p %d escaped=%ld color=%c from %s(%ld)\n",
|
c_fprintf(file, "%s %p %d escaped=%ld color=%c from %s(%ld)\n",
|
||||||
msg, id, kind, didEscape(c), col, c.filename, c.line)
|
msg, id, kind, didEscape(c), col, c.filename, c.line)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,9 @@ type
|
||||||
toDispose: SharedList[pointer]
|
toDispose: SharedList[pointer]
|
||||||
gcThreadId: int
|
gcThreadId: int
|
||||||
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
||||||
|
when defined(nimTracing):
|
||||||
|
tracing: bool
|
||||||
|
indentation: int
|
||||||
|
|
||||||
var
|
var
|
||||||
gch {.rtlThreadVar.}: GcHeap
|
gch {.rtlThreadVar.}: GcHeap
|
||||||
|
|
@ -380,6 +383,13 @@ proc mark(gch: var GcHeap, c: PCell) =
|
||||||
forAllChildren(d, waMarkPrecise)
|
forAllChildren(d, waMarkPrecise)
|
||||||
else:
|
else:
|
||||||
# XXX no 'if c.refCount != rcBlack' here?
|
# XXX no 'if c.refCount != rcBlack' here?
|
||||||
|
when defined(nimTracing):
|
||||||
|
if gch.tracing:
|
||||||
|
for i in 1..gch.indentation: c_fprintf(stdout, " ")
|
||||||
|
c_fprintf(stdout, "start marking %p of type %s ((\n",
|
||||||
|
c, c.typ.name)
|
||||||
|
inc gch.indentation, 2
|
||||||
|
|
||||||
c.refCount = rcBlack
|
c.refCount = rcBlack
|
||||||
gcAssert gch.tempStack.len == 0, "stack not empty!"
|
gcAssert gch.tempStack.len == 0, "stack not empty!"
|
||||||
forAllChildren(c, waMarkPrecise)
|
forAllChildren(c, waMarkPrecise)
|
||||||
|
|
@ -390,13 +400,24 @@ proc mark(gch: var GcHeap, c: PCell) =
|
||||||
d.refCount = rcBlack
|
d.refCount = rcBlack
|
||||||
forAllChildren(d, waMarkPrecise)
|
forAllChildren(d, waMarkPrecise)
|
||||||
|
|
||||||
|
when defined(nimTracing):
|
||||||
|
if gch.tracing:
|
||||||
|
dec gch.indentation, 2
|
||||||
|
for i in 1..gch.indentation: c_fprintf(stdout, " ")
|
||||||
|
c_fprintf(stdout, "finished marking %p of type %s))\n",
|
||||||
|
c, c.typ.name)
|
||||||
|
|
||||||
proc doOperation(p: pointer, op: WalkOp) =
|
proc doOperation(p: pointer, op: WalkOp) =
|
||||||
if p == nil: return
|
if p == nil: return
|
||||||
var c: PCell = usrToCell(p)
|
var c: PCell = usrToCell(p)
|
||||||
gcAssert(c != nil, "doOperation: 1")
|
gcAssert(c != nil, "doOperation: 1")
|
||||||
case op
|
case op
|
||||||
of waMarkGlobal: mark(gch, c)
|
of waMarkGlobal: mark(gch, c)
|
||||||
of waMarkPrecise: add(gch.tempStack, c)
|
of waMarkPrecise:
|
||||||
|
when defined(nimTracing):
|
||||||
|
if c.refcount == rcWhite: mark(gch, c)
|
||||||
|
else:
|
||||||
|
add(gch.tempStack, c)
|
||||||
|
|
||||||
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
|
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
|
||||||
doOperation(d, WalkOp(op))
|
doOperation(d, WalkOp(op))
|
||||||
|
|
@ -433,8 +454,17 @@ when false:
|
||||||
|
|
||||||
proc markGlobals(gch: var GcHeap) =
|
proc markGlobals(gch: var GcHeap) =
|
||||||
if gch.gcThreadId == 0:
|
if gch.gcThreadId == 0:
|
||||||
|
when defined(nimTracing):
|
||||||
|
if gch.tracing:
|
||||||
|
c_fprintf(stdout, "------- globals marking phase:\n")
|
||||||
for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
|
for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
|
||||||
|
when defined(nimTracing):
|
||||||
|
if gch.tracing:
|
||||||
|
c_fprintf(stdout, "------- thread locals marking phase:\n")
|
||||||
for i in 0 .. threadLocalMarkersLen-1: threadLocalMarkers[i]()
|
for i in 0 .. threadLocalMarkersLen-1: threadLocalMarkers[i]()
|
||||||
|
when defined(nimTracing):
|
||||||
|
if gch.tracing:
|
||||||
|
c_fprintf(stdout, "------- additional roots marking phase:\n")
|
||||||
let d = gch.additionalRoots.d
|
let d = gch.additionalRoots.d
|
||||||
for i in 0 .. gch.additionalRoots.len-1: mark(gch, d[i])
|
for i in 0 .. gch.additionalRoots.len-1: mark(gch, d[i])
|
||||||
|
|
||||||
|
|
@ -454,6 +484,9 @@ proc markStackAndRegisters(gch: var GcHeap) {.noinline, cdecl.} =
|
||||||
proc collectCTBody(gch: var GcHeap) =
|
proc collectCTBody(gch: var GcHeap) =
|
||||||
when not nimCoroutines:
|
when not nimCoroutines:
|
||||||
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
|
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
|
||||||
|
when defined(nimTracing):
|
||||||
|
if gch.tracing:
|
||||||
|
c_fprintf(stdout, "------- stack marking phase:\n")
|
||||||
prepareForInteriorPointerChecking(gch.region)
|
prepareForInteriorPointerChecking(gch.region)
|
||||||
markStackAndRegisters(gch)
|
markStackAndRegisters(gch)
|
||||||
markGlobals(gch)
|
markGlobals(gch)
|
||||||
|
|
@ -495,6 +528,10 @@ when not defined(useNimRtl):
|
||||||
gch.cycleThreshold = high(gch.cycleThreshold)-1
|
gch.cycleThreshold = high(gch.cycleThreshold)-1
|
||||||
# set to the max value to suppress the cycle detector
|
# set to the max value to suppress the cycle detector
|
||||||
|
|
||||||
|
when defined(nimTracing):
|
||||||
|
proc GC_logTrace*() =
|
||||||
|
gch.tracing = true
|
||||||
|
|
||||||
proc GC_fullCollect() =
|
proc GC_fullCollect() =
|
||||||
acquire(gch)
|
acquire(gch)
|
||||||
var oldThreshold = gch.cycleThreshold
|
var oldThreshold = gch.cycleThreshold
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue