Remove dead code (#9777)
* gc/gc2: remove unused ref counting stuff * also removes some false threading support - hasSharedHeap is always false in gc/gc2 * gc: remove some threading cruft * remove asgnRefNoCycle * compiler: remove TLoc.dup (unused)
This commit is contained in:
parent
ea5fc9f204
commit
87568830ab
7 changed files with 32 additions and 155 deletions
|
|
@ -768,7 +768,6 @@ type
|
||||||
flags*: TLocFlags # location's flags
|
flags*: TLocFlags # location's flags
|
||||||
lode*: PNode # Node where the location came from; can be faked
|
lode*: PNode # Node where the location came from; can be faked
|
||||||
r*: Rope # rope value of location (code generators)
|
r*: Rope # rope value of location (code generators)
|
||||||
dup*: Rope # duplicated location for precise stack scans
|
|
||||||
|
|
||||||
# ---------------- end of backend information ------------------------------
|
# ---------------- end of backend information ------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,13 +172,8 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||||
elif dest.storage == OnHeap:
|
elif dest.storage == OnHeap:
|
||||||
# location is on heap
|
|
||||||
if canFormAcycle(dest.t):
|
|
||||||
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
|
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src))
|
addrLoc(p.config, dest), rdLoc(src))
|
||||||
else:
|
|
||||||
linefmt(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n",
|
|
||||||
addrLoc(p.config, dest), rdLoc(src))
|
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
|
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src))
|
addrLoc(p.config, dest), rdLoc(src))
|
||||||
|
|
|
||||||
|
|
@ -100,14 +100,6 @@ var
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
instantiateForRegion(gch.region)
|
instantiateForRegion(gch.region)
|
||||||
|
|
||||||
template acquire(gch: GcHeap) =
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
acquireSys(HeapLock)
|
|
||||||
|
|
||||||
template release(gch: GcHeap) =
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
releaseSys(HeapLock)
|
|
||||||
|
|
||||||
template gcAssert(cond: bool, msg: string) =
|
template gcAssert(cond: bool, msg: string) =
|
||||||
when defined(useGcAssert):
|
when defined(useGcAssert):
|
||||||
if not cond:
|
if not cond:
|
||||||
|
|
@ -177,15 +169,6 @@ proc doOperation(p: pointer, op: WalkOp) {.benign.}
|
||||||
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.benign.}
|
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.benign.}
|
||||||
# we need the prototype here for debugging purposes
|
# we need the prototype here for debugging purposes
|
||||||
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
template `--`(x: untyped): untyped = atomicDec(x, rcIncrement) <% rcIncrement
|
|
||||||
template `++`(x: untyped) = discard atomicInc(x, rcIncrement)
|
|
||||||
else:
|
|
||||||
template `--`(x: untyped): untyped =
|
|
||||||
dec(x, rcIncrement)
|
|
||||||
x <% rcIncrement
|
|
||||||
template `++`(x: untyped) = inc(x, rcIncrement)
|
|
||||||
|
|
||||||
proc incRef(c: PCell) {.inline.} =
|
proc incRef(c: PCell) {.inline.} =
|
||||||
gcAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr")
|
gcAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr")
|
||||||
c.refcount = c.refcount +% rcIncrement
|
c.refcount = c.refcount +% rcIncrement
|
||||||
|
|
@ -194,28 +177,19 @@ proc incRef(c: PCell) {.inline.} =
|
||||||
|
|
||||||
proc nimGCref(p: pointer) {.compilerProc.} =
|
proc nimGCref(p: pointer) {.compilerProc.} =
|
||||||
# we keep it from being collected by pretending it's not even allocated:
|
# we keep it from being collected by pretending it's not even allocated:
|
||||||
add(gch.additionalRoots, usrToCell(p))
|
let c = usrToCell(p)
|
||||||
incRef(usrToCell(p))
|
add(gch.additionalRoots, c)
|
||||||
|
incRef(c)
|
||||||
proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} =
|
|
||||||
# we MUST access gch as a global here, because this crosses DLL boundaries!
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
acquireSys(HeapLock)
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
releaseSys(HeapLock)
|
|
||||||
|
|
||||||
proc rtlAddZCT(c: PCell) {.rtl, inl.} =
|
proc rtlAddZCT(c: PCell) {.rtl, inl.} =
|
||||||
# we MUST access gch as a global here, because this crosses DLL boundaries!
|
# we MUST access gch as a global here, because this crosses DLL boundaries!
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
acquireSys(HeapLock)
|
|
||||||
addZCT(gch.zct, c)
|
addZCT(gch.zct, c)
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
releaseSys(HeapLock)
|
|
||||||
|
|
||||||
proc decRef(c: PCell) {.inline.} =
|
proc decRef(c: PCell) {.inline.} =
|
||||||
gcAssert(isAllocatedPtr(gch.region, c), "decRef: interiorPtr")
|
gcAssert(isAllocatedPtr(gch.region, c), "decRef: interiorPtr")
|
||||||
gcAssert(c.refcount >=% rcIncrement, "decRef")
|
gcAssert(c.refcount >=% rcIncrement, "decRef")
|
||||||
if --c.refcount:
|
c.refcount = c.refcount -% rcIncrement
|
||||||
|
if c.refcount <% rcIncrement:
|
||||||
rtlAddZCT(c)
|
rtlAddZCT(c)
|
||||||
|
|
||||||
proc nimGCunref(p: pointer) {.compilerProc.} =
|
proc nimGCunref(p: pointer) {.compilerProc.} =
|
||||||
|
|
@ -239,19 +213,9 @@ template beforeDealloc(gch: var GcHeap; c: PCell; msg: typed) =
|
||||||
if gch.decStack.d[i] == c:
|
if gch.decStack.d[i] == c:
|
||||||
sysAssert(false, msg)
|
sysAssert(false, msg)
|
||||||
|
|
||||||
proc GC_addCycleRoot*[T](p: ref T) {.inline.} =
|
|
||||||
## adds 'p' to the cycle candidate set for the cycle collector. It is
|
|
||||||
## necessary if you used the 'acyclic' pragma for optimization
|
|
||||||
## purposes and need to break cycles manually.
|
|
||||||
rtlAddCycleRoot(usrToCell(cast[pointer](p)))
|
|
||||||
|
|
||||||
proc nimGCunrefNoCycle(p: pointer) {.compilerProc, inline.} =
|
proc nimGCunrefNoCycle(p: pointer) {.compilerProc, inline.} =
|
||||||
sysAssert(allocInv(gch.region), "begin nimGCunrefNoCycle")
|
sysAssert(allocInv(gch.region), "begin nimGCunrefNoCycle")
|
||||||
var c = usrToCell(p)
|
decRef(usrToCell(p))
|
||||||
gcAssert(isAllocatedPtr(gch.region, c), "nimGCunrefNoCycle: isAllocatedPtr")
|
|
||||||
if --c.refcount:
|
|
||||||
rtlAddZCT(c)
|
|
||||||
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 2")
|
|
||||||
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 5")
|
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 5")
|
||||||
|
|
||||||
proc nimGCunrefRC1(p: pointer) {.compilerProc, inline.} =
|
proc nimGCunrefRC1(p: pointer) {.compilerProc, inline.} =
|
||||||
|
|
@ -265,17 +229,8 @@ proc asgnRef(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
||||||
if dest[] != nil: decRef(usrToCell(dest[]))
|
if dest[] != nil: decRef(usrToCell(dest[]))
|
||||||
dest[] = src
|
dest[] = src
|
||||||
|
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
# the code generator calls this proc if it is known at compile time that no
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
# cycle is possible.
|
|
||||||
if src != nil:
|
|
||||||
var c = usrToCell(src)
|
|
||||||
++c.refcount
|
|
||||||
if dest[] != nil:
|
|
||||||
var c = usrToCell(dest[])
|
|
||||||
if --c.refcount:
|
|
||||||
rtlAddZCT(c)
|
|
||||||
dest[] = src
|
|
||||||
|
|
||||||
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerProc.} =
|
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerProc.} =
|
||||||
# unsureAsgnRef updates the reference counters only if dest is not on the
|
# unsureAsgnRef updates the reference counters only if dest is not on the
|
||||||
|
|
@ -440,7 +395,6 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||||
# generates a new object and sets its reference counter to 0
|
# generates a new object and sets its reference counter to 0
|
||||||
incTypeSize typ, size
|
incTypeSize typ, size
|
||||||
sysAssert(allocInv(gch.region), "rawNewObj begin")
|
sysAssert(allocInv(gch.region), "rawNewObj begin")
|
||||||
acquire(gch)
|
|
||||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||||
collectCT(gch)
|
collectCT(gch)
|
||||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
||||||
|
|
@ -457,7 +411,6 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||||
when logGC: writeCell("new cell", res)
|
when logGC: writeCell("new cell", res)
|
||||||
track("rawNewObj", res, size)
|
track("rawNewObj", res, size)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
release(gch)
|
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
res.id = gch.idGenerator * 1000_000 + gch.gcThreadId
|
res.id = gch.idGenerator * 1000_000 + gch.gcThreadId
|
||||||
|
|
@ -488,7 +441,6 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
# generates a new object and sets its reference counter to 1
|
# generates a new object and sets its reference counter to 1
|
||||||
incTypeSize typ, size
|
incTypeSize typ, size
|
||||||
sysAssert(allocInv(gch.region), "newObjRC1 begin")
|
sysAssert(allocInv(gch.region), "newObjRC1 begin")
|
||||||
acquire(gch)
|
|
||||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||||
collectCT(gch)
|
collectCT(gch)
|
||||||
sysAssert(allocInv(gch.region), "newObjRC1 after collectCT")
|
sysAssert(allocInv(gch.region), "newObjRC1 after collectCT")
|
||||||
|
|
@ -504,7 +456,6 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
when logGC: writeCell("new cell", res)
|
when logGC: writeCell("new cell", res)
|
||||||
track("newObjRC1", res, size)
|
track("newObjRC1", res, size)
|
||||||
gcTrace(res, csAllocated)
|
gcTrace(res, csAllocated)
|
||||||
release(gch)
|
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
res.id = gch.idGenerator * 1000_000 + gch.gcThreadId
|
res.id = gch.idGenerator * 1000_000 + gch.gcThreadId
|
||||||
|
|
@ -521,7 +472,6 @@ proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
|
||||||
when defined(memProfiler): nimProfile(size)
|
when defined(memProfiler): nimProfile(size)
|
||||||
|
|
||||||
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
acquire(gch)
|
|
||||||
collectCT(gch)
|
collectCT(gch)
|
||||||
var ol = usrToCell(old)
|
var ol = usrToCell(old)
|
||||||
sysAssert(ol.typ != nil, "growObj: 1")
|
sysAssert(ol.typ != nil, "growObj: 1")
|
||||||
|
|
@ -577,7 +527,6 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
else:
|
else:
|
||||||
sysAssert(ol.typ != nil, "growObj: 5")
|
sysAssert(ol.typ != nil, "growObj: 5")
|
||||||
zeroMem(ol, sizeof(Cell))
|
zeroMem(ol, sizeof(Cell))
|
||||||
release(gch)
|
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
res.id = gch.idGenerator * 1000_000 + gch.gcThreadId
|
res.id = gch.idGenerator * 1000_000 + gch.gcThreadId
|
||||||
|
|
@ -665,11 +614,9 @@ proc doOperation(p: pointer, op: WalkOp) =
|
||||||
# c_fprintf(stdout, "[GC] decref bug: %p", c)
|
# c_fprintf(stdout, "[GC] decref bug: %p", c)
|
||||||
gcAssert(isAllocatedPtr(gch.region, c), "decRef: waZctDecRef")
|
gcAssert(isAllocatedPtr(gch.region, c), "decRef: waZctDecRef")
|
||||||
gcAssert(c.refcount >=% rcIncrement, "doOperation 2")
|
gcAssert(c.refcount >=% rcIncrement, "doOperation 2")
|
||||||
#c.refcount = c.refcount -% rcIncrement
|
|
||||||
when logGC: writeCell("decref (from doOperation)", c)
|
when logGC: writeCell("decref (from doOperation)", c)
|
||||||
track("waZctDecref", p, 0)
|
track("waZctDecref", p, 0)
|
||||||
decRef(c)
|
decRef(c)
|
||||||
#if c.refcount <% rcIncrement: addZCT(gch.zct, c)
|
|
||||||
of waPush:
|
of waPush:
|
||||||
add(gch.tempStack, c)
|
add(gch.tempStack, c)
|
||||||
of waMarkGlobal:
|
of waMarkGlobal:
|
||||||
|
|
@ -707,13 +654,13 @@ proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
|
||||||
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
||||||
if objStart != nil:
|
if objStart != nil:
|
||||||
# mark the cell:
|
# mark the cell:
|
||||||
objStart.refcount = objStart.refcount +% rcIncrement
|
incRef(objStart)
|
||||||
add(gch.decStack, objStart)
|
add(gch.decStack, objStart)
|
||||||
when false:
|
when false:
|
||||||
if isAllocatedPtr(gch.region, cell):
|
if isAllocatedPtr(gch.region, cell):
|
||||||
sysAssert false, "allocated pointer but not interior?"
|
sysAssert false, "allocated pointer but not interior?"
|
||||||
# mark the cell:
|
# mark the cell:
|
||||||
cell.refcount = cell.refcount +% rcIncrement
|
incRef(cell)
|
||||||
add(gch.decStack, cell)
|
add(gch.decStack, cell)
|
||||||
sysAssert(allocInv(gch.region), "gcMark end")
|
sysAssert(allocInv(gch.region), "gcMark end")
|
||||||
|
|
||||||
|
|
@ -787,11 +734,6 @@ proc unmarkStackAndRegisters(gch: var GcHeap) =
|
||||||
for i in 0..gch.decStack.len-1:
|
for i in 0..gch.decStack.len-1:
|
||||||
sysAssert isAllocatedPtr(gch.region, d[i]), "unmarkStackAndRegisters"
|
sysAssert isAllocatedPtr(gch.region, d[i]), "unmarkStackAndRegisters"
|
||||||
decRef(d[i])
|
decRef(d[i])
|
||||||
#var c = d[i]
|
|
||||||
# XXX no need for an atomic dec here:
|
|
||||||
#if --c.refcount:
|
|
||||||
# addZCT(gch.zct, c)
|
|
||||||
#sysAssert c.typ != nil, "unmarkStackAndRegisters 2"
|
|
||||||
gch.decStack.len = 0
|
gch.decStack.len = 0
|
||||||
|
|
||||||
proc collectCTBody(gch: var GcHeap) =
|
proc collectCTBody(gch: var GcHeap) =
|
||||||
|
|
@ -850,13 +792,11 @@ when withRealTime:
|
||||||
gch.maxPause = MaxPauseInUs.toNano
|
gch.maxPause = MaxPauseInUs.toNano
|
||||||
|
|
||||||
proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool) =
|
proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool) =
|
||||||
acquire(gch)
|
|
||||||
gch.maxPause = us.toNano
|
gch.maxPause = us.toNano
|
||||||
if (gch.zct.len >= ZctThreshold or (cycleGC and
|
if (gch.zct.len >= ZctThreshold or (cycleGC and
|
||||||
getOccupiedMem(gch.region)>=gch.cycleThreshold) or alwaysGC) or
|
getOccupiedMem(gch.region)>=gch.cycleThreshold) or alwaysGC) or
|
||||||
strongAdvice:
|
strongAdvice:
|
||||||
collectCTBody(gch)
|
collectCTBody(gch)
|
||||||
release(gch)
|
|
||||||
|
|
||||||
proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
|
proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
|
||||||
if stackSize >= 0:
|
if stackSize >= 0:
|
||||||
|
|
@ -880,17 +820,11 @@ when withRealTime:
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
proc GC_disable() =
|
proc GC_disable() =
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
discard atomicInc(gch.recGcLock, 1)
|
|
||||||
else:
|
|
||||||
inc(gch.recGcLock)
|
inc(gch.recGcLock)
|
||||||
proc GC_enable() =
|
proc GC_enable() =
|
||||||
if gch.recGcLock <= 0:
|
if gch.recGcLock <= 0:
|
||||||
raise newException(AssertionError,
|
raise newException(AssertionError,
|
||||||
"API usage error: GC_enable called but GC is already enabled")
|
"API usage error: GC_enable called but GC is already enabled")
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
discard atomicDec(gch.recGcLock, 1)
|
|
||||||
else:
|
|
||||||
dec(gch.recGcLock)
|
dec(gch.recGcLock)
|
||||||
|
|
||||||
proc GC_setStrategy(strategy: GC_Strategy) =
|
proc GC_setStrategy(strategy: GC_Strategy) =
|
||||||
|
|
@ -904,12 +838,10 @@ when not defined(useNimRtl):
|
||||||
# set to the max value to suppress the cycle detector
|
# set to the max value to suppress the cycle detector
|
||||||
|
|
||||||
proc GC_fullCollect() =
|
proc GC_fullCollect() =
|
||||||
acquire(gch)
|
|
||||||
var oldThreshold = gch.cycleThreshold
|
var oldThreshold = gch.cycleThreshold
|
||||||
gch.cycleThreshold = 0 # forces cycle collection
|
gch.cycleThreshold = 0 # forces cycle collection
|
||||||
collectCT(gch)
|
collectCT(gch)
|
||||||
gch.cycleThreshold = oldThreshold
|
gch.cycleThreshold = oldThreshold
|
||||||
release(gch)
|
|
||||||
|
|
||||||
proc GC_getStatistics(): string =
|
proc GC_getStatistics(): string =
|
||||||
result = "[GC] total memory: " & $(getTotalMem()) & "\n" &
|
result = "[GC] total memory: " & $(getTotalMem()) & "\n" &
|
||||||
|
|
|
||||||
|
|
@ -112,14 +112,6 @@ var
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
instantiateForRegion(gch.region)
|
instantiateForRegion(gch.region)
|
||||||
|
|
||||||
template acquire(gch: GcHeap) =
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
acquireSys(HeapLock)
|
|
||||||
|
|
||||||
template release(gch: GcHeap) =
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
releaseSys(HeapLock)
|
|
||||||
|
|
||||||
# Which color to use for new objects is tricky: When we're marking,
|
# Which color to use for new objects is tricky: When we're marking,
|
||||||
# they have to be *white* so that everything is marked that is only
|
# they have to be *white* so that everything is marked that is only
|
||||||
# reachable from them. However, when we are sweeping, they have to
|
# reachable from them. However, when we are sweeping, they have to
|
||||||
|
|
@ -204,10 +196,6 @@ proc doOperation(p: pointer, op: WalkOp) {.benign.}
|
||||||
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.benign.}
|
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) {.benign.}
|
||||||
# we need the prototype here for debugging purposes
|
# we need the prototype here for debugging purposes
|
||||||
|
|
||||||
proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} =
|
|
||||||
# we MUST access gch as a global here, because this crosses DLL boundaries!
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc nimGCref(p: pointer) {.compilerProc.} =
|
proc nimGCref(p: pointer) {.compilerProc.} =
|
||||||
let cell = usrToCell(p)
|
let cell = usrToCell(p)
|
||||||
markAsEscaped(cell)
|
markAsEscaped(cell)
|
||||||
|
|
@ -240,13 +228,8 @@ template markGrey(x: PCell) =
|
||||||
x.setColor(rcGrey)
|
x.setColor(rcGrey)
|
||||||
add(gch.greyStack, x)
|
add(gch.greyStack, x)
|
||||||
|
|
||||||
proc GC_addCycleRoot*[T](p: ref T) {.inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
||||||
## adds 'p' to the cycle candidate set for the cycle collector. It is
|
# the code generator calls this proc!
|
||||||
## necessary if you used the 'acyclic' pragma for optimization
|
|
||||||
## purposes and need to break cycles manually.
|
|
||||||
discard
|
|
||||||
|
|
||||||
template asgnRefImpl =
|
|
||||||
gcAssert(not isOnStack(dest), "asgnRef")
|
gcAssert(not isOnStack(dest), "asgnRef")
|
||||||
# BUGFIX: first incRef then decRef!
|
# BUGFIX: first incRef then decRef!
|
||||||
if src != nil:
|
if src != nil:
|
||||||
|
|
@ -255,12 +238,8 @@ template asgnRefImpl =
|
||||||
markGrey(s)
|
markGrey(s)
|
||||||
dest[] = src
|
dest[] = src
|
||||||
|
|
||||||
proc asgnRef(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
# the code generator calls this proc!
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
asgnRefImpl()
|
|
||||||
|
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
|
||||||
asgnRefImpl()
|
|
||||||
|
|
||||||
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerProc.} =
|
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerProc.} =
|
||||||
# unsureAsgnRef marks 'src' as grey only if dest is not on the
|
# unsureAsgnRef marks 'src' as grey only if dest is not on the
|
||||||
|
|
@ -396,7 +375,6 @@ proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
|
||||||
result = newSeq(typ, len)
|
result = newSeq(typ, len)
|
||||||
|
|
||||||
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
acquire(gch)
|
|
||||||
collectCT(gch)
|
collectCT(gch)
|
||||||
var ol = usrToCell(old)
|
var ol = usrToCell(old)
|
||||||
sysAssert(ol.typ != nil, "growObj: 1")
|
sysAssert(ol.typ != nil, "growObj: 1")
|
||||||
|
|
@ -420,7 +398,6 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
res.id = gch.idGenerator
|
res.id = gch.idGenerator
|
||||||
release(gch)
|
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
when defined(memProfiler): nimProfile(newsize-oldsize)
|
when defined(memProfiler): nimProfile(newsize-oldsize)
|
||||||
|
|
||||||
|
|
@ -732,15 +709,9 @@ when withRealTime:
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
proc GC_disable() =
|
proc GC_disable() =
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
discard atomicInc(gch.recGcLock, 1)
|
|
||||||
else:
|
|
||||||
inc(gch.recGcLock)
|
inc(gch.recGcLock)
|
||||||
proc GC_enable() =
|
proc GC_enable() =
|
||||||
if gch.recGcLock > 0:
|
if gch.recGcLock > 0:
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
discard atomicDec(gch.recGcLock, 1)
|
|
||||||
else:
|
|
||||||
dec(gch.recGcLock)
|
dec(gch.recGcLock)
|
||||||
|
|
||||||
proc GC_setStrategy(strategy: GC_Strategy) =
|
proc GC_setStrategy(strategy: GC_Strategy) =
|
||||||
|
|
|
||||||
|
|
@ -85,14 +85,6 @@ var
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
instantiateForRegion(gch.region)
|
instantiateForRegion(gch.region)
|
||||||
|
|
||||||
template acquire(gch: GcHeap) =
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
acquireSys(HeapLock)
|
|
||||||
|
|
||||||
template release(gch: GcHeap) =
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
releaseSys(HeapLock)
|
|
||||||
|
|
||||||
template gcAssert(cond: bool, msg: string) =
|
template gcAssert(cond: bool, msg: string) =
|
||||||
when defined(useGcAssert):
|
when defined(useGcAssert):
|
||||||
if not cond:
|
if not cond:
|
||||||
|
|
@ -276,7 +268,6 @@ proc forAllChildren(cell: PCell, op: WalkOp) =
|
||||||
proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||||
# generates a new object and sets its reference counter to 0
|
# generates a new object and sets its reference counter to 0
|
||||||
incTypeSize typ, size
|
incTypeSize typ, size
|
||||||
acquire(gch)
|
|
||||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||||
collectCT(gch, size + sizeof(Cell))
|
collectCT(gch, size + sizeof(Cell))
|
||||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
||||||
|
|
@ -288,7 +279,6 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||||
res.filename = framePtr.prev.filename
|
res.filename = framePtr.prev.filename
|
||||||
res.line = framePtr.prev.line
|
res.line = framePtr.prev.line
|
||||||
res.refcount = 0
|
res.refcount = 0
|
||||||
release(gch)
|
|
||||||
when withBitvectors: incl(gch.allocated, res)
|
when withBitvectors: incl(gch.allocated, res)
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
|
|
@ -333,7 +323,6 @@ when not defined(gcDestructors):
|
||||||
when defined(memProfiler): nimProfile(size)
|
when defined(memProfiler): nimProfile(size)
|
||||||
|
|
||||||
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
||||||
acquire(gch)
|
|
||||||
collectCT(gch, newsize + sizeof(Cell))
|
collectCT(gch, newsize + sizeof(Cell))
|
||||||
var ol = usrToCell(old)
|
var ol = usrToCell(old)
|
||||||
sysAssert(ol.typ != nil, "growObj: 1")
|
sysAssert(ol.typ != nil, "growObj: 1")
|
||||||
|
|
@ -353,7 +342,6 @@ when not defined(gcDestructors):
|
||||||
when useCellIds:
|
when useCellIds:
|
||||||
inc gch.idGenerator
|
inc gch.idGenerator
|
||||||
res.id = gch.idGenerator
|
res.id = gch.idGenerator
|
||||||
release(gch)
|
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
when defined(memProfiler): nimProfile(newsize-oldsize)
|
when defined(memProfiler): nimProfile(newsize-oldsize)
|
||||||
|
|
||||||
|
|
@ -503,17 +491,11 @@ proc collectCT(gch: var GcHeap; size: int) =
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
proc GC_disable() =
|
proc GC_disable() =
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
atomicInc(gch.recGcLock, 1)
|
|
||||||
else:
|
|
||||||
inc(gch.recGcLock)
|
inc(gch.recGcLock)
|
||||||
proc GC_enable() =
|
proc GC_enable() =
|
||||||
if gch.recGcLock <= 0:
|
if gch.recGcLock <= 0:
|
||||||
raise newException(AssertionError,
|
raise newException(AssertionError,
|
||||||
"API usage error: GC_enable called but GC is already enabled")
|
"API usage error: GC_enable called but GC is already enabled")
|
||||||
when hasThreadSupport and hasSharedHeap:
|
|
||||||
atomicDec(gch.recGcLock, 1)
|
|
||||||
else:
|
|
||||||
dec(gch.recGcLock)
|
dec(gch.recGcLock)
|
||||||
|
|
||||||
proc GC_setStrategy(strategy: GC_Strategy) = discard
|
proc GC_setStrategy(strategy: GC_Strategy) = discard
|
||||||
|
|
@ -530,12 +512,10 @@ when not defined(useNimRtl):
|
||||||
gch.tracing = true
|
gch.tracing = true
|
||||||
|
|
||||||
proc GC_fullCollect() =
|
proc GC_fullCollect() =
|
||||||
acquire(gch)
|
|
||||||
var oldThreshold = gch.cycleThreshold
|
var oldThreshold = gch.cycleThreshold
|
||||||
gch.cycleThreshold = 0 # forces cycle collection
|
gch.cycleThreshold = 0 # forces cycle collection
|
||||||
collectCT(gch, 0)
|
collectCT(gch, 0)
|
||||||
gch.cycleThreshold = oldThreshold
|
gch.cycleThreshold = oldThreshold
|
||||||
release(gch)
|
|
||||||
|
|
||||||
proc GC_getStatistics(): string =
|
proc GC_getStatistics(): string =
|
||||||
result = "[GC] total memory: " & $getTotalMem() & "\n" &
|
result = "[GC] total memory: " & $getTotalMem() & "\n" &
|
||||||
|
|
|
||||||
|
|
@ -339,8 +339,8 @@ proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
dest[] = src
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
|
|
||||||
proc alloc(size: Natural): pointer =
|
proc alloc(size: Natural): pointer =
|
||||||
result = c_malloc(size)
|
result = c_malloc(size)
|
||||||
|
|
|
||||||
|
|
@ -170,8 +170,8 @@ when defined(boehmgc):
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
dest[] = src
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
|
|
||||||
type
|
type
|
||||||
MemRegion = object
|
MemRegion = object
|
||||||
|
|
@ -326,8 +326,8 @@ elif defined(gogc):
|
||||||
writebarrierptr(dest, src)
|
writebarrierptr(dest, src)
|
||||||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||||
writebarrierptr(dest, src)
|
writebarrierptr(dest, src)
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
writebarrierptr(dest, src)
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
|
|
||||||
type
|
type
|
||||||
MemRegion = object
|
MemRegion = object
|
||||||
|
|
@ -416,8 +416,8 @@ elif defined(nogc) and defined(useMalloc):
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
dest[] = src
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
|
|
||||||
type
|
type
|
||||||
MemRegion = object
|
MemRegion = object
|
||||||
|
|
@ -473,8 +473,8 @@ elif defined(nogc):
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||||
dest[] = src
|
dest[] = src
|
||||||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline,
|
||||||
dest[] = src
|
deprecated: "old compiler compat".} = asgnRef(dest, src)
|
||||||
|
|
||||||
var allocator {.rtlThreadVar.}: MemRegion
|
var allocator {.rtlThreadVar.}: MemRegion
|
||||||
instantiateForRegion(allocator)
|
instantiateForRegion(allocator)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue