added system.deallocHeap feature for Nim's native GCs

This commit is contained in:
Andreas Rumpf
2017-07-22 11:38:47 +02:00
parent ad608838bf
commit e968fbb7dd
3 changed files with 32 additions and 27 deletions

View File

@@ -238,21 +238,6 @@ proc nimGCunref(p: pointer) {.compilerProc.} =
include gc_common
proc prepareDealloc(cell: PCell) =
when useMarkForDebug:
gcAssert(cell notin gch.marked, "Cell still alive!")
let t = cell.typ
if t.finalizer != nil:
# the finalizer could invoke something that
# allocates memory; this could trigger a garbage
# collection. Since we are already collecting we
# prevend recursive entering here by a lock.
# XXX: we should set the cell's children to nil!
inc(gch.recGcLock)
(cast[Finalizer](t.finalizer))(cellToUsr(cell))
dec(gch.recGcLock)
decTypeSize(cell, t)
template beforeDealloc(gch: var GcHeap; c: PCell; msg: typed) =
when false:
for i in 0..gch.decStack.len-1:

View File

@@ -351,3 +351,35 @@ else:
# ----------------------------------------------------------------------------
# end of non-portable code
# ----------------------------------------------------------------------------
proc prepareDealloc(cell: PCell) =
when declared(useMarkForDebug):
when useMarkForDebug:
gcAssert(cell notin gch.marked, "Cell still alive!")
let t = cell.typ
if t.finalizer != nil:
# the finalizer could invoke something that
# allocates memory; this could trigger a garbage
# collection. Since we are already collecting we
# prevend recursive entering here by a lock.
# XXX: we should set the cell's children to nil!
inc(gch.recGcLock)
(cast[Finalizer](t.finalizer))(cellToUsr(cell))
dec(gch.recGcLock)
decTypeSize(cell, t)
proc deallocHeap*(runFinalizers = true; allowGcAfterwards = true) =
## Frees the thread local heap. Runs every finalizer if ``runFinalizers```
## is true. If ``allowGcAfterwards`` is true, a minimal amount of allocation
## happens to ensure the GC can continue to work after the call
## to ``deallocHeap``.
if runFinalizers:
for x in allObjects(gch.region):
if isCell(x):
# cast to PCell is correct here:
var c = cast[PCell](x)
prepareDealloc(c)
deallocOsPages(gch.region)
zeroMem(addr gch.region, sizeof(gch.region))
if allowGcAfterwards:
initGC()

View File

@@ -221,18 +221,6 @@ when defined(nimGcRefLeak):
include gc_common
proc prepareDealloc(cell: PCell) =
if cell.typ.finalizer != nil:
# the finalizer could invoke something that
# allocates memory; this could trigger a garbage
# collection. Since we are already collecting we
# prevend recursive entering here by a lock.
# XXX: we should set the cell's children to nil!
inc(gch.recGcLock)
(cast[Finalizer](cell.typ.finalizer))(cellToUsr(cell))
dec(gch.recGcLock)
decTypeSize cell, cell.typ
proc initGC() =
when not defined(useNimRtl):
gch.cycleThreshold = InitialThreshold