From 7524610b310203c423f0fd593a05baca603e3a6c Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 5 Jan 2015 02:27:24 +0100 Subject: fixes #1796 --- lib/system/gc.nim | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'lib/system') diff --git a/lib/system/gc.nim b/lib/system/gc.nim index e0db3fba4..58587cf7f 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -49,7 +49,7 @@ type waMarkGlobal, # part of the backup/debug mark&sweep waMarkPrecise, # part of the backup/debug mark&sweep waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack, - waCollectWhite, + waCollectWhite #, waDebug TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} # A ref type can have a finalizer that is called before the object's @@ -595,9 +595,15 @@ proc scan(s: PCell) = else: s.setColor(rcWhite) forAllChildren(s, waScan) - + proc collectWhite(s: PCell) = - if s.color == rcWhite and s notin gch.cycleRoots: + # This is a hacky way to deal with the following problem (bug #1796) + # Consider this content in cycleRoots: + # x -> a; y -> a where 'a' is an acyclic object so not included in + # cycleRoots itself. Then 'collectWhite' used to free 'a' twice. The + # 'isAllocatedPtr' check prevents this. This also means we do not need + # to query 's notin gch.cycleRoots' at all. + if isAllocatedPtr(gch.region, s) and s.color == rcWhite: s.setColor(rcBlack) forAllChildren(s, waCollectWhite) freeCyclicCell(gch, s) @@ -648,6 +654,28 @@ when useMarkForDebug or useBackupGc: if objStart != nil: markS(gch, objStart) +when logGC: + var + cycleCheckA: array[100, PCell] + cycleCheckALen = 0 + + proc alreadySeen(c: PCell): bool = + for i in 0 .. Date: Tue, 6 Jan 2015 01:28:18 +0100 Subject: Some GC renames to get rid of deprecation warnings --- lib/system/gc2.nim | 2 +- lib/system/mmdisp.nim | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/system') diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index ee52b54f5..b0173b78f 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -1344,7 +1344,7 @@ when not defined(useNimRtl): else: dec(gch.recGcLock) - proc GC_setStrategy(strategy: TGC_Strategy) = + proc GC_setStrategy(strategy: GC_Strategy) = case strategy of gcThroughput: nil of gcResponsiveness: nil diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index e091c0889..a1a0353ca 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -144,7 +144,7 @@ when defined(boehmgc): proc GC_disable() = boehmGC_disable() proc GC_enable() = boehmGC_enable() proc GC_fullCollect() = boehmGCfullCollect() - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -221,7 +221,7 @@ elif defined(nogc) and defined(useMalloc): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -281,7 +281,7 @@ elif defined(nogc): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" -- cgit 1.4.1-2-gfad0