diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-05-23 12:54:01 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-05-23 12:54:01 +0200 |
commit | 55ec99b70b56e7fb258e4ba2bccdea3767ff8a51 (patch) | |
tree | a872a620384a0e46b67da8f38b3715b531ab1772 | |
parent | 9b609b26ca07ee78cb24e82fa89d31072f9f9133 (diff) | |
download | Nim-55ec99b70b56e7fb258e4ba2bccdea3767ff8a51.tar.gz |
new GC listens to GC_ref/GC_unref
-rw-r--r-- | lib/system/gc.nim | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/system/gc.nim b/lib/system/gc.nim index ed5b2d1e9..ee5eec30b 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -89,6 +89,7 @@ type stat: GcStat when useMarkForDebug or useBackupGc: marked: CellSet + additionalRoots: CellSeq # dummy roots for GC_ref/unref when hasThreadSupport: toDispose: SharedList[pointer] @@ -223,8 +224,23 @@ proc incRef(c: PCell) {.inline.} = # and not colorMask #writeCell("incRef", c) -proc nimGCref(p: pointer) {.compilerProc, inline.} = incRef(usrToCell(p)) -proc nimGCunref(p: pointer) {.compilerProc, inline.} = decRef(usrToCell(p)) +proc nimGCref(p: pointer) {.compilerProc.} = + # we keep it from being collected by pretending it's not even allocated: + add(gch.additionalRoots, usrToCell(p)) + incRef(usrToCell(p)) + +proc nimGCunref(p: pointer) {.compilerProc.} = + let cell = usrToCell(p) + var L = gch.additionalRoots.len-1 + var i = L + let d = gch.additionalRoots.d + while i >= 0: + if d[i] == cell: + d[i] = d[L] + dec gch.additionalRoots.len + break + dec(i) + decRef(usrToCell(p)) proc GC_addCycleRoot*[T](p: ref T) {.inline.} = ## adds 'p' to the cycle candidate set for the cycle collector. It is @@ -294,6 +310,7 @@ proc initGC() = init(gch.decStack) when useMarkForDebug or useBackupGc: init(gch.marked) + init(gch.additionalRoots) when hasThreadSupport: gch.toDispose = initSharedList[pointer]() @@ -608,6 +625,8 @@ when useMarkForDebug or useBackupGc: proc markGlobals(gch: var GcHeap) = for i in 0 .. < globalMarkersLen: globalMarkers[i]() + let d = gch.additionalRoots.d + for i in 0 .. < gch.additionalRoots.len: markS(gch, d[i]) when logGC: var |