mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-09 22:43:34 +00:00
GCs support ForeignCells
This commit is contained in:
@@ -39,6 +39,9 @@ when withRealTime and not declared(getTicks):
|
||||
when defined(memProfiler):
|
||||
proc nimProfile(requestedSize: int) {.benign.}
|
||||
|
||||
when hasThreadSupport:
|
||||
import sharedlist
|
||||
|
||||
const
|
||||
rcIncrement = 0b1000 # so that lowest 3 bits are not touched
|
||||
rcBlack = 0b000 # cell is colored black; in use or free
|
||||
@@ -93,6 +96,9 @@ type
|
||||
stat: GcStat
|
||||
when useMarkForDebug or useBackupGc:
|
||||
marked: CellSet
|
||||
when hasThreadSupport:
|
||||
toDispose: SharedList[pointer]
|
||||
|
||||
{.deprecated: [TWalkOp: WalkOp, TFinalizer: Finalizer, TGcHeap: GcHeap,
|
||||
TGcStat: GcStat].}
|
||||
var
|
||||
@@ -304,6 +310,8 @@ proc initGC() =
|
||||
init(gch.decStack)
|
||||
when useMarkForDebug or useBackupGc:
|
||||
init(gch.marked)
|
||||
when hasThreadSupport:
|
||||
gch.toDispose = initSharedList[pointer]()
|
||||
|
||||
when useMarkForDebug or useBackupGc:
|
||||
type
|
||||
@@ -749,6 +757,9 @@ proc collectRoots(gch: var GcHeap) =
|
||||
collectWhite(s)
|
||||
|
||||
proc collectCycles(gch: var GcHeap) =
|
||||
when hasThreadSupport:
|
||||
for c in gch.toDispose:
|
||||
nimGCunref(c)
|
||||
# ensure the ZCT 'color' is not used:
|
||||
while gch.zct.len > 0: discard collectZCT(gch)
|
||||
when useBackupGc:
|
||||
|
||||
@@ -7,6 +7,31 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
type
|
||||
ForeignCell* = object
|
||||
data*: pointer
|
||||
owner: ptr GcHeap
|
||||
|
||||
proc protect*(x: pointer): ForeignCell =
|
||||
nimGCref(x)
|
||||
result.data = x
|
||||
result.owner = addr(gch)
|
||||
|
||||
proc dispose*(x: ForeignCell) =
|
||||
when hasThreadSupport:
|
||||
# if we own it we can free it directly:
|
||||
if x.owner == addr(gch):
|
||||
nimGCunref(x.data)
|
||||
else:
|
||||
x.owner.toDispose.add(x.data)
|
||||
else:
|
||||
nimGCunref(x.data)
|
||||
|
||||
proc isNotForeign*(x: ForeignCell): bool =
|
||||
## returns true if 'x' belongs to the calling thread.
|
||||
## No deep copy has to be performed then.
|
||||
x.owner == addr(gch)
|
||||
|
||||
proc len(stack: ptr GcStack): int =
|
||||
if stack == nil:
|
||||
return 0
|
||||
|
||||
@@ -68,6 +68,8 @@ type
|
||||
recGcLock: int # prevent recursion via finalizers; no thread lock
|
||||
region: MemRegion # garbage collected region
|
||||
stat: GcStat
|
||||
when hasThreadSupport:
|
||||
toDispose: SharedList[pointer]
|
||||
additionalRoots: CellSeq # dummy roots for GC_ref/unref
|
||||
{.deprecated: [TWalkOp: WalkOp, TFinalizer: Finalizer, TGcStat: GcStat,
|
||||
TGlobalMarkerProc: GlobalMarkerProc, TGcHeap: GcHeap].}
|
||||
@@ -179,6 +181,8 @@ proc initGC() =
|
||||
when withBitvectors:
|
||||
init(gch.allocated)
|
||||
init(gch.marked)
|
||||
when hasThreadSupport:
|
||||
gch.toDispose = initSharedList[pointer]()
|
||||
|
||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
|
||||
var d = cast[ByteAddress](dest)
|
||||
@@ -321,6 +325,9 @@ proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
|
||||
# ----------------- collector -----------------------------------------------
|
||||
|
||||
proc mark(gch: var GcHeap, c: PCell) =
|
||||
when hasThreadSupport:
|
||||
for c in gch.toDispose:
|
||||
nimGCunref(c)
|
||||
when withBitvectors:
|
||||
incl(gch.marked, c)
|
||||
gcAssert gch.tempStack.len == 0, "stack not empty!"
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
# Low level system locks and condition vars.
|
||||
|
||||
{.push stackTrace: off.}
|
||||
|
||||
when defined(Windows):
|
||||
type
|
||||
Handle = int
|
||||
@@ -118,3 +120,5 @@ else:
|
||||
|
||||
proc deinitSysCond(cond: var SysCond) {.noSideEffect,
|
||||
importc: "pthread_cond_destroy", header: "<pthread.h>".}
|
||||
|
||||
{.pop.}
|
||||
|
||||
Reference in New Issue
Block a user