added system.deallocHeap feature for Nim's native GCs
This commit is contained in:
parent
ad608838bf
commit
e968fbb7dd
3 changed files with 32 additions and 27 deletions
|
|
@ -238,21 +238,6 @@ proc nimGCunref(p: pointer) {.compilerProc.} =
|
||||||
|
|
||||||
include gc_common
|
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) =
|
template beforeDealloc(gch: var GcHeap; c: PCell; msg: typed) =
|
||||||
when false:
|
when false:
|
||||||
for i in 0..gch.decStack.len-1:
|
for i in 0..gch.decStack.len-1:
|
||||||
|
|
|
||||||
|
|
@ -351,3 +351,35 @@ else:
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# end of non-portable code
|
# 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()
|
||||||
|
|
|
||||||
|
|
@ -221,18 +221,6 @@ when defined(nimGcRefLeak):
|
||||||
|
|
||||||
include gc_common
|
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() =
|
proc initGC() =
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
gch.cycleThreshold = InitialThreshold
|
gch.cycleThreshold = InitialThreshold
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue