diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/system/arc.nim | 6 | ||||
-rw-r--r-- | lib/system/orc.nim | 45 |
2 files changed, 32 insertions, 19 deletions
diff --git a/lib/system/arc.nim b/lib/system/arc.nim index 973b951d4..3e24c2506 100644 --- a/lib/system/arc.nim +++ b/lib/system/arc.nim @@ -161,6 +161,12 @@ proc nimRawDispose(p: pointer) {.compilerRtl.} = if head(p).rc >= rcIncrement: cstderr.rawWrite "[FATAL] dangling references exist\n" quit 1 + + when defined(gcOrc) and defined(nimArcDebug): + if (head(p).rc and 0b100) != 0: + cstderr.rawWrite "[FATAL] cycle root freed\n" + quit 1 + when defined(nimArcDebug): # we do NOT really free the memory here in order to reliably detect use-after-frees if freedCells.data == nil: init(freedCells) diff --git a/lib/system/orc.nim b/lib/system/orc.nim index cf8d6379a..1d856696c 100644 --- a/lib/system/orc.nim +++ b/lib/system/orc.nim @@ -297,8 +297,10 @@ proc collectCyclesBacon(j: var GcEnv) = const defaultThreshold = when defined(nimAdaptiveOrc): 128 else: 10_000 -var - rootsThreshold = defaultThreshold +when defined(nimStressOrc): + const rootsThreshold = 10 # broken with -d:nimStressOrc: 10 and for havlak iterations 1..8 +else: + var rootsThreshold = defaultThreshold proc collectCycles() = ## Collect cycles. @@ -320,28 +322,31 @@ proc collectCycles() = deinit j.traceStack deinit roots - # compute the threshold based on the previous history - # of the cycle collector's effectiveness: - # we're effective when we collected 50% or more of the nodes - # we touched. If we're effective, we can reset the threshold: - if j.freed * 2 >= j.touched: - when defined(nimAdaptiveOrc): - rootsThreshold = max(rootsThreshold div 2, 16) - else: - rootsThreshold = defaultThreshold - #cfprintf(cstderr, "[collectCycles] freed %ld, touched %ld new threshold %ld\n", j.freed, j.touched, rootsThreshold) - elif rootsThreshold < high(int) div 4: - rootsThreshold = rootsThreshold * 3 div 2 + + when not defined(nimStressOrc): + # compute the threshold based on the previous history + # of the cycle collector's effectiveness: + # we're effective when we collected 50% or more of the nodes + # we touched. If we're effective, we can reset the threshold: + if j.freed * 2 >= j.touched: + when defined(nimAdaptiveOrc): + rootsThreshold = max(rootsThreshold div 2, 16) + else: + rootsThreshold = defaultThreshold + #cfprintf(cstderr, "[collectCycles] freed %ld, touched %ld new threshold %ld\n", j.freed, j.touched, rootsThreshold) + elif rootsThreshold < high(int) div 4: + rootsThreshold = rootsThreshold * 3 div 2 when logOrc: cfprintf(cstderr, "[collectCycles] end; freed %ld new threshold %ld touched: %ld mem: %ld\n", j.freed, rootsThreshold, j.touched, getOccupiedMem()) proc registerCycle(s: Cell; desc: PNimTypeV2) = - if roots.len >= rootsThreshold: - collectCycles() - if roots.d == nil: init(roots) s.rootIdx = roots.len + if roots.d == nil: init(roots) add(roots, s, desc) + + if roots.len >= rootsThreshold: + collectCycles() #writeCell("[added root]", s) proc GC_fullCollect* = @@ -350,10 +355,12 @@ proc GC_fullCollect* = collectCycles() proc GC_enableMarkAndSweep*() = - rootsThreshold = defaultThreshold + when not defined(nimStressOrc): + rootsThreshold = defaultThreshold proc GC_disableMarkAndSweep*() = - rootsThreshold = high(int) + when not defined(nimStressOrc): + rootsThreshold = high(int) proc rememberCycle(isDestroyAction: bool; s: Cell; desc: PNimTypeV2) {.noinline.} = if isDestroyAction: |