diff options
author | Araq <rumpf_a@web.de> | 2018-01-15 17:41:05 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2018-01-15 17:41:05 +0100 |
commit | f1089db1755c1e8cc5bcf965cac64014005cac3a (patch) | |
tree | afdfea52b76b32cc8b96d0d068f5ff130dd4c8d2 /lib/system/gc2.nim | |
parent | 24a6583fa76289bfd725b61b9bd5effad7f5765a (diff) | |
download | Nim-f1089db1755c1e8cc5bcf965cac64014005cac3a.tar.gz |
GC: enable precise global/thread local storage tracing
Diffstat (limited to 'lib/system/gc2.nim')
-rw-r--r-- | lib/system/gc2.nim | 59 |
1 files changed, 26 insertions, 33 deletions
diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index cd90c6d62..ca2a35f60 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -104,7 +104,7 @@ type pDumpHeapFile: pointer # File that is used for GC_dumpHeap when hasThreadSupport: toDispose: SharedList[pointer] - isMainThread: bool + gcThreadId: int var gch {.rtlThreadVar.}: GcHeap @@ -120,23 +120,6 @@ template release(gch: GcHeap) = when hasThreadSupport and hasSharedHeap: releaseSys(HeapLock) -proc initGC() = - when not defined(useNimRtl): - gch.red = (1-gch.black) - gch.cycleThreshold = InitialCycleThreshold - gch.stat.stackScans = 0 - gch.stat.completedCollections = 0 - gch.stat.maxThreshold = 0 - gch.stat.maxStackSize = 0 - gch.stat.maxStackCells = 0 - gch.stat.cycleTableSize = 0 - # init the rt - init(gch.additionalRoots) - init(gch.greyStack) - when hasThreadSupport: - init(gch.toDispose) - gch.isMainThread = true - # Which color to use for new objects is tricky: When we're marking, # they have to be *white* so that everything is marked that is only # reachable from them. However, when we are sweeping, they have to @@ -342,6 +325,24 @@ proc gcInvariant*() = include gc_common +proc initGC() = + when not defined(useNimRtl): + gch.red = (1-gch.black) + gch.cycleThreshold = InitialCycleThreshold + gch.stat.stackScans = 0 + gch.stat.completedCollections = 0 + gch.stat.maxThreshold = 0 + gch.stat.maxStackSize = 0 + gch.stat.maxStackCells = 0 + gch.stat.cycleTableSize = 0 + # init the rt + init(gch.additionalRoots) + init(gch.greyStack) + when hasThreadSupport: + init(gch.toDispose) + gch.gcThreadId = atomicInc(gHeapidGenerator) - 1 + gcAssert(gch.gcThreadId >= 0, "invalid computed thread ID") + proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer = # generates a new object and sets its reference counter to 0 sysAssert(allocInv(gch.region), "rawNewObj begin") @@ -480,7 +481,7 @@ proc GC_dumpHeap*(file: File) = c_fprintf(file, "onstack %p\n", d[i]) else: c_fprintf(file, "onstack_invalid %p\n", d[i]) - if gch.isMainThread: + if gch.gcThreadId == 0: for i in 0 .. globalMarkersLen-1: globalMarkers[i]() for i in 0 .. threadLocalMarkersLen-1: threadLocalMarkers[i]() while true: @@ -569,7 +570,7 @@ proc markIncremental(gch: var GcHeap): bool = result = true proc markGlobals(gch: var GcHeap) = - if gch.isMainThread: + if gch.gcThreadId == 0: for i in 0 .. globalMarkersLen-1: globalMarkers[i]() for i in 0 .. threadLocalMarkersLen-1: threadLocalMarkers[i]() @@ -591,22 +592,14 @@ proc doOperation(p: pointer, op: WalkOp) = markRoot(gch, c) else: dumpRoot(gch, c) - when hasThreadSupport: - # could point to a cell which we don't own and don't want to touch/trace - if isAllocatedPtr(gch.region, c): handleRoot() - else: - #gcAssert(isAllocatedPtr(gch.region, c), "doOperation: waMarkGlobal") + handleRoot() + discard allocInv(gch.region) + of waMarkGrey: + when false: if not isAllocatedPtr(gch.region, c): - c_fprintf(stdout, "[GC] not allocated anymore: MarkGlobal %p\n", c) + c_fprintf(stdout, "[GC] not allocated anymore: MarkGrey %p\n", c) #GC_dumpHeap() sysAssert(false, "wtf") - handleRoot() - discard allocInv(gch.region) - of waMarkGrey: - if not isAllocatedPtr(gch.region, c): - c_fprintf(stdout, "[GC] not allocated anymore: MarkGrey %p\n", c) - #GC_dumpHeap() - sysAssert(false, "wtf") if c.color == 1-gch.black: c.setColor(rcGrey) add(gch.greyStack, c) |