diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-01-19 18:11:46 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-01-19 18:11:46 +0100 |
commit | 7adf3bf4769b27bada8e9562d611d6c57263905a (patch) | |
tree | 43301ee1984eac9b38602c4c700bb565c1b08b66 | |
parent | 00295366b55bbf9001c8d8540ff541daa8a0fa8c (diff) | |
download | Nim-7adf3bf4769b27bada8e9562d611d6c57263905a.tar.gz |
Mark&Sweep GC: introduce nimTracing define for debugging
-rw-r--r-- | lib/system/gc2.nim | 5 | ||||
-rw-r--r-- | lib/system/gc_ms.nim | 39 |
2 files changed, 42 insertions, 2 deletions
diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index ca2a35f60..283919503 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -178,7 +178,10 @@ proc writeCell(file: File; msg: cstring, c: PCell) = let id = c.id else: 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", msg, id, kind, didEscape(c), col, c.filename, c.line) else: diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 101185dfb..34d16a719 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -75,6 +75,9 @@ type toDispose: SharedList[pointer] gcThreadId: int additionalRoots: CellSeq # dummy roots for GC_ref/unref + when defined(nimTracing): + tracing: bool + indentation: int var gch {.rtlThreadVar.}: GcHeap @@ -380,6 +383,13 @@ proc mark(gch: var GcHeap, c: PCell) = forAllChildren(d, waMarkPrecise) else: # 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 gcAssert gch.tempStack.len == 0, "stack not empty!" forAllChildren(c, waMarkPrecise) @@ -390,13 +400,24 @@ proc mark(gch: var GcHeap, c: PCell) = d.refCount = rcBlack 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) = if p == nil: return var c: PCell = usrToCell(p) gcAssert(c != nil, "doOperation: 1") case op 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.} = doOperation(d, WalkOp(op)) @@ -433,8 +454,17 @@ when false: proc markGlobals(gch: var GcHeap) = 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]() + when defined(nimTracing): + if gch.tracing: + c_fprintf(stdout, "------- thread locals marking phase:\n") 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 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) = when not nimCoroutines: gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize()) + when defined(nimTracing): + if gch.tracing: + c_fprintf(stdout, "------- stack marking phase:\n") prepareForInteriorPointerChecking(gch.region) markStackAndRegisters(gch) markGlobals(gch) @@ -495,6 +528,10 @@ when not defined(useNimRtl): gch.cycleThreshold = high(gch.cycleThreshold)-1 # set to the max value to suppress the cycle detector + when defined(nimTracing): + proc GC_logTrace*() = + gch.tracing = true + proc GC_fullCollect() = acquire(gch) var oldThreshold = gch.cycleThreshold |