new GC listens to GC_ref/GC_unref
This commit is contained in:
parent
9b609b26ca
commit
55ec99b70b
1 changed files with 21 additions and 2 deletions
|
|
@ -89,6 +89,7 @@ type
|
||||||
stat: GcStat
|
stat: GcStat
|
||||||
when useMarkForDebug or useBackupGc:
|
when useMarkForDebug or useBackupGc:
|
||||||
marked: CellSet
|
marked: CellSet
|
||||||
|
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
toDispose: SharedList[pointer]
|
toDispose: SharedList[pointer]
|
||||||
|
|
||||||
|
|
@ -223,8 +224,23 @@ proc incRef(c: PCell) {.inline.} =
|
||||||
# and not colorMask
|
# and not colorMask
|
||||||
#writeCell("incRef", c)
|
#writeCell("incRef", c)
|
||||||
|
|
||||||
proc nimGCref(p: pointer) {.compilerProc, inline.} = incRef(usrToCell(p))
|
proc nimGCref(p: pointer) {.compilerProc.} =
|
||||||
proc nimGCunref(p: pointer) {.compilerProc, inline.} = decRef(usrToCell(p))
|
# 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.} =
|
proc GC_addCycleRoot*[T](p: ref T) {.inline.} =
|
||||||
## adds 'p' to the cycle candidate set for the cycle collector. It is
|
## adds 'p' to the cycle candidate set for the cycle collector. It is
|
||||||
|
|
@ -294,6 +310,7 @@ proc initGC() =
|
||||||
init(gch.decStack)
|
init(gch.decStack)
|
||||||
when useMarkForDebug or useBackupGc:
|
when useMarkForDebug or useBackupGc:
|
||||||
init(gch.marked)
|
init(gch.marked)
|
||||||
|
init(gch.additionalRoots)
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
gch.toDispose = initSharedList[pointer]()
|
gch.toDispose = initSharedList[pointer]()
|
||||||
|
|
||||||
|
|
@ -608,6 +625,8 @@ when useMarkForDebug or useBackupGc:
|
||||||
|
|
||||||
proc markGlobals(gch: var GcHeap) =
|
proc markGlobals(gch: var GcHeap) =
|
||||||
for i in 0 .. < globalMarkersLen: globalMarkers[i]()
|
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:
|
when logGC:
|
||||||
var
|
var
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue