From 04933b773a64b8d6437e4c2280e4033e107cb86a Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 12 Feb 2026 13:29:22 +0100 Subject: [PATCH] YRC: bugfixes (#25512) --- lib/system/yrc.nim | 68 +++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 49 deletions(-) diff --git a/lib/system/yrc.nim b/lib/system/yrc.nim index 9a9920cee8..a681917de2 100644 --- a/lib/system/yrc.nim +++ b/lib/system/yrc.nim @@ -217,6 +217,9 @@ proc nimIncRefCyclic(p: pointer; cyclic: bool) {.compilerRtl, inl.} = break proc mergePendingRoots() = + # Merge buffered RC operations. Note: Unlike truly concurrent collectors, + # we don't need to set color to black on incRef because collection runs + # under the global lock, so no concurrent mutations happen during collection. for i in 0.. 0) for cycle detection - # Only process roots from lowMark to immediateFreeStart (cycleStart == immediateFreeStart after swap loop) - for i in lowMark.. 0: - let (entry, childDesc) = j.traceStack.pop() - let t = head entry[] - entry[] = nil - # Recursively trace children to nil their descendants too - trace(t, childDesc, j) - - # Clear roots before freeing to prevent nested collectCycles() from accessing freed cells roots.len = 0 - # Free all roots (both immediate-free and cycle-detected) together + # Free all collected objects # Destructors must not call nimDecRefIsLastCyclicStatic (add to toDec) during this phase for i in 0 ..< j.toFree.len: let s = j.toFree.d[i][0] - s.rc = s.rc and not inRootsFlag when orcLeakDetector: writeCell("CYCLIC OBJECT FREED", s, j.toFree.d[i][1]) free(s, j.toFree.d[i][1]) when not defined(nimStressOrc): rootsThreshold = oldThreshold - j.freed = j.freed +% j.toFree.len +% immediateFreeCount + j.freed = j.freed +% j.toFree.len deinit j.toFree when defined(nimOrcStats):