diff --git a/lib/system/cellsets.nim b/lib/system/cellsets.nim index 7815f928bd..1fed45b7b5 100644 --- a/lib/system/cellsets.nim +++ b/lib/system/cellsets.nim @@ -252,12 +252,12 @@ iterator elementsExcept(t, s: CellSet): PCell {.inline.} = var r = t.head while r != nil: let ss = cellSetGet(s, r.key) - var i:uint = 0 + var i = 0'u while int(i) <= high(r.bits): var w = r.bits[i] if ss != nil: w = w and not ss.bits[i] - var j:uint = 0 + var j = 0'u while w != 0: if (w and 1) != 0: yield cast[PCell]((r.key shl PageShift) or diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 9289c7f55c..e1de2aade7 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -597,7 +597,13 @@ proc sweep(gch: var GcHeap) = if isCell(x): # cast to PCell is correct here: var c = cast[PCell](x) - if c notin gch.marked: freeCyclicCell(gch, c) + if c notin gch.marked: + # Don't free objects that have the ZctFlag set (created in finalizers) + if (c.refcount and ZctFlag) == 0: + freeCyclicCell(gch, c) + else: + # Clear the ZctFlag for the next collection cycle + c.refcount = c.refcount and not ZctFlag proc markS(gch: var GcHeap, c: PCell) = gcAssert isAllocatedPtr(gch.region, c), "markS: foreign heap root detected A!" diff --git a/testament/categories.nim b/testament/categories.nim index ee2da5bb8d..eba1e3cb27 100644 --- a/testament/categories.nim +++ b/testament/categories.nim @@ -83,7 +83,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string, isOrc = if "boehm" notin options: # hcr tests - + var basicHcrTest = makeTest("tests/dll/nimhcr_basic.nim", options & " --threads:off --forceBuild --hotCodeReloading:on " & rpath, cat) # test segfaults for now but compiles: if isOrc: basicHcrTest.spec.action = actionCompile @@ -165,6 +165,7 @@ proc gcTests(r: var TResults, cat: Category, options: string) = test "stackrefleak" test "cyclecollector" testWithoutBoehm "trace_globals" + test "tfinalizers" # ------------------------- threading tests ----------------------------------- diff --git a/tests/gc/tfinalizers.nim b/tests/gc/tfinalizers.nim new file mode 100644 index 0000000000..53295b71ab --- /dev/null +++ b/tests/gc/tfinalizers.nim @@ -0,0 +1,19 @@ + +type + PNode = ref TNode + TNode = object + le: PNode + +proc finalizeNode(n: PNode) = + var s = @[0] + +proc returnTree() = + var cycle: PNode + new(cycle, finalizeNode) + cycle.le = cycle + +for i in 1..100: + returnTree() + +GC_fullCollect() +GC_fullCollect()