Merge pull request #2150 from def-/gc2-compiling
Make gc2 compile again and fix some deprecation warnings
This commit is contained in:
commit
13c2d9b8e2
2 changed files with 73 additions and 71 deletions
|
|
@ -128,7 +128,7 @@ type
|
||||||
# cycle roots table that uses a cheap linear scan
|
# cycle roots table that uses a cheap linear scan
|
||||||
# to find only possitively dead objects.
|
# to find only possitively dead objects.
|
||||||
# One strategy is to perform it only for new objects
|
# One strategy is to perform it only for new objects
|
||||||
# allocated between the invocations of CollectZCT.
|
# allocated between the invocations of collectZCT.
|
||||||
# This index indicates the start of the range of
|
# This index indicates the start of the range of
|
||||||
# such new objects within the table.
|
# such new objects within the table.
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
|
|
@ -140,7 +140,7 @@ var
|
||||||
gch* {.rtlThreadVar.}: TGcHeap
|
gch* {.rtlThreadVar.}: TGcHeap
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
InstantiateForRegion(gch.region)
|
instantiateForRegion(gch.region)
|
||||||
|
|
||||||
template acquire(gch: TGcHeap) =
|
template acquire(gch: TGcHeap) =
|
||||||
when hasThreadSupport and hasSharedHeap:
|
when hasThreadSupport and hasSharedHeap:
|
||||||
|
|
@ -233,11 +233,11 @@ template addCycleRoot(cycleRoots: var TCellSeq, c: PCell) =
|
||||||
|
|
||||||
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
||||||
# convert object (=pointer to refcount) to pointer to userdata
|
# convert object (=pointer to refcount) to pointer to userdata
|
||||||
result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
|
result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell)))
|
||||||
|
|
||||||
proc usrToCell*(usr: pointer): PCell {.inline.} =
|
proc usrToCell*(usr: pointer): PCell {.inline.} =
|
||||||
# convert pointer to userdata to object (=pointer to refcount)
|
# convert pointer to userdata to object (=pointer to refcount)
|
||||||
result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
|
result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell)))
|
||||||
|
|
||||||
proc canbeCycleRoot(c: PCell): bool {.inline.} =
|
proc canbeCycleRoot(c: PCell): bool {.inline.} =
|
||||||
result = ntfAcyclic notin c.typ.flags
|
result = ntfAcyclic notin c.typ.flags
|
||||||
|
|
@ -255,10 +255,10 @@ when BitsPerPage mod (sizeof(int)*8) != 0:
|
||||||
|
|
||||||
# forward declarations:
|
# forward declarations:
|
||||||
proc collectCT(gch: var TGcHeap)
|
proc collectCT(gch: var TGcHeap)
|
||||||
proc IsOnStack*(p: pointer): bool {.noinline.}
|
proc isOnStack*(p: pointer): bool {.noinline.}
|
||||||
proc forAllChildren(cell: PCell, op: TWalkOp)
|
proc forAllChildren(cell: PCell, op: TWalkOp)
|
||||||
proc doOperation(p: pointer, op: TWalkOp)
|
proc doOperation(p: pointer, op: TWalkOp)
|
||||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp)
|
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp)
|
||||||
# we need the prototype here for debugging purposes
|
# we need the prototype here for debugging purposes
|
||||||
|
|
||||||
proc prepareDealloc(cell: PCell) =
|
proc prepareDealloc(cell: PCell) =
|
||||||
|
|
@ -432,7 +432,7 @@ proc nimGCunrefNoCycle(p: pointer) {.compilerProc, inline.} =
|
||||||
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 2")
|
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 2")
|
||||||
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 5")
|
sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 5")
|
||||||
|
|
||||||
template doAsgnRef(dest: ppointer, src: pointer,
|
template doAsgnRef(dest: PPointer, src: pointer,
|
||||||
heapType = LocalHeap, cycleFlag = MaybeCyclic): stmt =
|
heapType = LocalHeap, cycleFlag = MaybeCyclic): stmt =
|
||||||
sysAssert(not isOnStack(dest), "asgnRef")
|
sysAssert(not isOnStack(dest), "asgnRef")
|
||||||
# BUGFIX: first incRef then decRef!
|
# BUGFIX: first incRef then decRef!
|
||||||
|
|
@ -440,20 +440,20 @@ template doAsgnRef(dest: ppointer, src: pointer,
|
||||||
if dest[] != nil: doDecRef(usrToCell(dest[]), heapType, cycleFlag)
|
if dest[] != nil: doDecRef(usrToCell(dest[]), heapType, cycleFlag)
|
||||||
dest[] = src
|
dest[] = src
|
||||||
|
|
||||||
proc asgnRef(dest: ppointer, src: pointer) {.compilerProc, inline.} =
|
proc asgnRef(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
||||||
# the code generator calls this proc!
|
# the code generator calls this proc!
|
||||||
doAsgnRef(dest, src, LocalHeap, MaybeCyclic)
|
doAsgnRef(dest, src, LocalHeap, MaybeCyclic)
|
||||||
|
|
||||||
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
|
# the code generator calls this proc if it is known at compile time that no
|
||||||
# cycle is possible.
|
# cycle is possible.
|
||||||
doAsgnRef(dest, src, LocalHeap, Acyclic)
|
doAsgnRef(dest, src, LocalHeap, Acyclic)
|
||||||
|
|
||||||
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
|
||||||
# stack. It is used by the code generator if it cannot decide wether a
|
# stack. It is used by the code generator if it cannot decide wether a
|
||||||
# reference is in the stack or not (this can happen for var parameters).
|
# reference is in the stack or not (this can happen for var parameters).
|
||||||
if not IsOnStack(dest):
|
if not isOnStack(dest):
|
||||||
if src != nil: doIncRef(usrToCell(src))
|
if src != nil: doIncRef(usrToCell(src))
|
||||||
# XXX we must detect a shared heap here
|
# XXX we must detect a shared heap here
|
||||||
# better idea may be to just eliminate the need for unsureAsgnRef
|
# better idea may be to just eliminate the need for unsureAsgnRef
|
||||||
|
|
@ -470,16 +470,16 @@ proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerProc.} =
|
||||||
|
|
||||||
when hasThreadSupport and hasSharedHeap:
|
when hasThreadSupport and hasSharedHeap:
|
||||||
# shared heap version of the above procs
|
# shared heap version of the above procs
|
||||||
proc asgnRefSh(dest: ppointer, src: pointer) {.compilerProc, inline.} =
|
proc asgnRefSh(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
||||||
doAsgnRef(dest, src, SharedHeap, MaybeCyclic)
|
doAsgnRef(dest, src, SharedHeap, MaybeCyclic)
|
||||||
|
|
||||||
proc asgnRefNoCycleSh(dest: ppointer, src: pointer) {.compilerProc, inline.} =
|
proc asgnRefNoCycleSh(dest: PPointer, src: pointer) {.compilerProc, inline.} =
|
||||||
doAsgnRef(dest, src, SharedHeap, Acyclic)
|
doAsgnRef(dest, src, SharedHeap, Acyclic)
|
||||||
|
|
||||||
proc initGC() =
|
proc initGC() =
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
when traceGC:
|
when traceGC:
|
||||||
for i in low(TCellState)..high(TCellState): Init(states[i])
|
for i in low(TCellState)..high(TCellState): init(states[i])
|
||||||
gch.cycleThreshold = InitialCycleThreshold
|
gch.cycleThreshold = InitialCycleThreshold
|
||||||
gch.stat.stackScans = 0
|
gch.stat.stackScans = 0
|
||||||
gch.stat.cycleCollections = 0
|
gch.stat.cycleCollections = 0
|
||||||
|
|
@ -491,11 +491,11 @@ proc initGC() =
|
||||||
init(gch.zct)
|
init(gch.zct)
|
||||||
init(gch.tempStack)
|
init(gch.tempStack)
|
||||||
init(gch.freeStack)
|
init(gch.freeStack)
|
||||||
Init(gch.cycleRoots)
|
init(gch.cycleRoots)
|
||||||
Init(gch.decStack)
|
init(gch.decStack)
|
||||||
|
|
||||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
||||||
var d = cast[TAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
||||||
of nkList:
|
of nkList:
|
||||||
|
|
@ -503,7 +503,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
||||||
# inlined for speed
|
# inlined for speed
|
||||||
if n.sons[i].kind == nkSlot:
|
if n.sons[i].kind == nkSlot:
|
||||||
if n.sons[i].typ.kind in {tyRef, tyString, tySequence}:
|
if n.sons[i].typ.kind in {tyRef, tyString, tySequence}:
|
||||||
doOperation(cast[ppointer](d +% n.sons[i].offset)[], op)
|
doOperation(cast[PPointer](d +% n.sons[i].offset)[], op)
|
||||||
else:
|
else:
|
||||||
forAllChildrenAux(cast[pointer](d +% n.sons[i].offset),
|
forAllChildrenAux(cast[pointer](d +% n.sons[i].offset),
|
||||||
n.sons[i].typ, op)
|
n.sons[i].typ, op)
|
||||||
|
|
@ -514,19 +514,19 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
||||||
if m != nil: forAllSlotsAux(dest, m, op)
|
if m != nil: forAllSlotsAux(dest, m, op)
|
||||||
of nkNone: sysAssert(false, "forAllSlotsAux")
|
of nkNone: sysAssert(false, "forAllSlotsAux")
|
||||||
|
|
||||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
|
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) =
|
||||||
var d = cast[TAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
if dest == nil: return # nothing to do
|
if dest == nil: return # nothing to do
|
||||||
if ntfNoRefs notin mt.flags:
|
if ntfNoRefs notin mt.flags:
|
||||||
case mt.Kind
|
case mt.kind
|
||||||
of tyRef, tyString, tySequence: # leaf:
|
of tyRef, tyString, tySequence: # leaf:
|
||||||
doOperation(cast[ppointer](d)[], op)
|
doOperation(cast[PPointer](d)[], op)
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
forAllSlotsAux(dest, mt.node, op)
|
forAllSlotsAux(dest, mt.node, op)
|
||||||
of tyArray, tyArrayConstr, tyOpenArray:
|
of tyArray, tyArrayConstr, tyOpenArray:
|
||||||
for i in 0..(mt.size div mt.base.size)-1:
|
for i in 0..(mt.size div mt.base.size)-1:
|
||||||
forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op)
|
forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op)
|
||||||
else: nil
|
else: discard
|
||||||
|
|
||||||
proc forAllChildren(cell: PCell, op: TWalkOp) =
|
proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||||
sysAssert(cell != nil, "forAllChildren: 1")
|
sysAssert(cell != nil, "forAllChildren: 1")
|
||||||
|
|
@ -536,18 +536,18 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||||
if marker != nil:
|
if marker != nil:
|
||||||
marker(cellToUsr(cell), op.int)
|
marker(cellToUsr(cell), op.int)
|
||||||
else:
|
else:
|
||||||
case cell.typ.Kind
|
case cell.typ.kind
|
||||||
of tyRef: # common case
|
of tyRef: # common case
|
||||||
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
||||||
of tySequence:
|
of tySequence:
|
||||||
var d = cast[TAddress](cellToUsr(cell))
|
var d = cast[ByteAddress](cellToUsr(cell))
|
||||||
var s = cast[PGenericSeq](d)
|
var s = cast[PGenericSeq](d)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
let baseAddr = d +% GenericSeqSize
|
let baseAddr = d +% GenericSeqSize
|
||||||
for i in 0..s.len-1:
|
for i in 0..s.len-1:
|
||||||
forAllChildrenAux(cast[pointer](baseAddr +% i *% cell.typ.base.size),
|
forAllChildrenAux(cast[pointer](baseAddr +% i *% cell.typ.base.size),
|
||||||
cell.typ.base, op)
|
cell.typ.base, op)
|
||||||
else: nil
|
else: discard
|
||||||
|
|
||||||
proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
|
proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
|
||||||
# we check the last 8 entries (cache line) for a slot that could be reused.
|
# we check the last 8 entries (cache line) for a slot that could be reused.
|
||||||
|
|
@ -605,7 +605,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap, rc1: bool): pointer =
|
||||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
|
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
|
||||||
sysAssert(allocInv(gch.region), "rawNewObj after rawAlloc")
|
sysAssert(allocInv(gch.region), "rawNewObj after rawAlloc")
|
||||||
|
|
||||||
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
|
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
|
||||||
|
|
||||||
res.typ = typ
|
res.typ = typ
|
||||||
|
|
||||||
|
|
@ -708,10 +708,10 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
# call user-defined move code
|
# call user-defined move code
|
||||||
# call user-defined default constructor
|
# call user-defined default constructor
|
||||||
copyMem(res, ol, oldsize + sizeof(TCell))
|
copyMem(res, ol, oldsize + sizeof(TCell))
|
||||||
zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)),
|
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
||||||
newsize-oldsize)
|
newsize-oldsize)
|
||||||
|
|
||||||
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||||
sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
|
sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
|
|
@ -786,10 +786,10 @@ type
|
||||||
FromChildren,
|
FromChildren,
|
||||||
FromRoot
|
FromRoot
|
||||||
|
|
||||||
proc CollectZCT(gch: var TGcHeap): bool
|
proc collectZCT(gch: var TGcHeap): bool
|
||||||
|
|
||||||
template pseudoRecursion(typ: TRecursionType, body: stmt): stmt =
|
template pseudoRecursion(typ: TRecursionType, body: stmt): stmt =
|
||||||
#
|
discard
|
||||||
|
|
||||||
proc trimCycleRoots(gch: var TGcHeap, startIdx = gch.cycleRootsTrimIdx) =
|
proc trimCycleRoots(gch: var TGcHeap, startIdx = gch.cycleRootsTrimIdx) =
|
||||||
var i = startIdx
|
var i = startIdx
|
||||||
|
|
@ -967,17 +967,17 @@ proc collectCycles(gch: var TGcHeap) =
|
||||||
maybedeads,
|
maybedeads,
|
||||||
collected
|
collected
|
||||||
|
|
||||||
Deinit(gch.cycleRoots)
|
deinit(gch.cycleRoots)
|
||||||
Init(gch.cycleRoots)
|
init(gch.cycleRoots)
|
||||||
|
|
||||||
Deinit(gch.freeStack)
|
deinit(gch.freeStack)
|
||||||
Init(gch.freeStack)
|
init(gch.freeStack)
|
||||||
|
|
||||||
when MarkingSkipsAcyclicObjects:
|
when MarkingSkipsAcyclicObjects:
|
||||||
# Collect the acyclic objects that became unreachable due to collected
|
# Collect the acyclic objects that became unreachable due to collected
|
||||||
# cyclic objects.
|
# cyclic objects.
|
||||||
discard CollectZCT(gch)
|
discard collectZCT(gch)
|
||||||
# CollectZCT may add new cycle candidates and we may decide to loop here
|
# collectZCT may add new cycle candidates and we may decide to loop here
|
||||||
# if gch.cycleRoots.len > 0: repeat
|
# if gch.cycleRoots.len > 0: repeat
|
||||||
|
|
||||||
var gcDebugging* = false
|
var gcDebugging* = false
|
||||||
|
|
@ -988,7 +988,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
|
||||||
# the addresses are not as cells on the stack, so turn them to cells:
|
# the addresses are not as cells on the stack, so turn them to cells:
|
||||||
sysAssert(allocInv(gch.region), "gcMark begin")
|
sysAssert(allocInv(gch.region), "gcMark begin")
|
||||||
var cell = usrToCell(p)
|
var cell = usrToCell(p)
|
||||||
var c = cast[TAddress](cell)
|
var c = cast[ByteAddress](cell)
|
||||||
if c >% PageSize:
|
if c >% PageSize:
|
||||||
# fast check: does it look like a cell?
|
# fast check: does it look like a cell?
|
||||||
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
||||||
|
|
@ -997,6 +997,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
|
||||||
if objStart.color != rcReallyDead:
|
if objStart.color != rcReallyDead:
|
||||||
if gcDebugging:
|
if gcDebugging:
|
||||||
# writeCell("marking ", objStart)
|
# writeCell("marking ", objStart)
|
||||||
|
discard
|
||||||
else:
|
else:
|
||||||
inc objStart.refcount, rcIncrement
|
inc objStart.refcount, rcIncrement
|
||||||
gch.decStack.add objStart
|
gch.decStack.add objStart
|
||||||
|
|
@ -1009,6 +1010,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
|
||||||
# coincidence due to the conservative stack marking.
|
# coincidence due to the conservative stack marking.
|
||||||
when debugGC:
|
when debugGC:
|
||||||
# writeCell("marking dead object", objStart)
|
# writeCell("marking dead object", objStart)
|
||||||
|
discard
|
||||||
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?"
|
||||||
|
|
@ -1024,12 +1026,12 @@ proc markThreadStacks(gch: var TGcHeap) =
|
||||||
while it != nil:
|
while it != nil:
|
||||||
# mark registers:
|
# mark registers:
|
||||||
for i in 0 .. high(it.registers): gcMark(gch, it.registers[i])
|
for i in 0 .. high(it.registers): gcMark(gch, it.registers[i])
|
||||||
var sp = cast[TAddress](it.stackBottom)
|
var sp = cast[ByteAddress](it.stackBottom)
|
||||||
var max = cast[TAddress](it.stackTop)
|
var max = cast[ByteAddress](it.stackTop)
|
||||||
# XXX stack direction?
|
# XXX stack direction?
|
||||||
# XXX unroll this loop:
|
# XXX unroll this loop:
|
||||||
while sp <=% max:
|
while sp <=% max:
|
||||||
gcMark(gch, cast[ppointer](sp)[])
|
gcMark(gch, cast[PPointer](sp)[])
|
||||||
sp = sp +% sizeof(pointer)
|
sp = sp +% sizeof(pointer)
|
||||||
it = it.next
|
it = it.next
|
||||||
|
|
||||||
|
|
@ -1051,8 +1053,8 @@ when not defined(useNimRtl):
|
||||||
# the first init must be the one that defines the stack bottom:
|
# the first init must be the one that defines the stack bottom:
|
||||||
if gch.stackBottom == nil: gch.stackBottom = theStackBottom
|
if gch.stackBottom == nil: gch.stackBottom = theStackBottom
|
||||||
else:
|
else:
|
||||||
var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2
|
var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2
|
||||||
var b = cast[TAddress](gch.stackBottom)
|
var b = cast[ByteAddress](gch.stackBottom)
|
||||||
#c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom)
|
#c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom)
|
||||||
when stackIncreases:
|
when stackIncreases:
|
||||||
gch.stackBottom = cast[pointer](min(a, b))
|
gch.stackBottom = cast[pointer](min(a, b))
|
||||||
|
|
@ -1073,9 +1075,9 @@ when defined(sparc): # For SPARC architecture.
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var stackTop {.volatile.}: pointer
|
var stackTop {.volatile.}: pointer
|
||||||
stackTop = addr(stackTop)
|
stackTop = addr(stackTop)
|
||||||
var b = cast[TAddress](gch.stackBottom)
|
var b = cast[ByteAddress](gch.stackBottom)
|
||||||
var a = cast[TAddress](stackTop)
|
var a = cast[ByteAddress](stackTop)
|
||||||
var x = cast[TAddress](p)
|
var x = cast[ByteAddress](p)
|
||||||
result = a <=% x and x <=% b
|
result = a <=% x and x <=% b
|
||||||
|
|
||||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||||
|
|
@ -1092,7 +1094,7 @@ when defined(sparc): # For SPARC architecture.
|
||||||
# Addresses decrease as the stack grows.
|
# Addresses decrease as the stack grows.
|
||||||
while sp <= max:
|
while sp <= max:
|
||||||
gcMark(gch, sp[])
|
gcMark(gch, sp[])
|
||||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
sp = cast[PPointer](cast[ByteAddress](sp) +% sizeof(pointer))
|
||||||
|
|
||||||
elif defined(ELATE):
|
elif defined(ELATE):
|
||||||
{.error: "stack marking code is to be written for this architecture".}
|
{.error: "stack marking code is to be written for this architecture".}
|
||||||
|
|
@ -1104,20 +1106,20 @@ elif stackIncreases:
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var stackTop {.volatile.}: pointer
|
var stackTop {.volatile.}: pointer
|
||||||
stackTop = addr(stackTop)
|
stackTop = addr(stackTop)
|
||||||
var a = cast[TAddress](gch.stackBottom)
|
var a = cast[ByteAddress](gch.stackBottom)
|
||||||
var b = cast[TAddress](stackTop)
|
var b = cast[ByteAddress](stackTop)
|
||||||
var x = cast[TAddress](p)
|
var x = cast[ByteAddress](p)
|
||||||
result = a <=% x and x <=% b
|
result = a <=% x and x <=% b
|
||||||
|
|
||||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||||
var registers: C_JmpBuf
|
var registers: C_JmpBuf
|
||||||
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||||
var max = cast[TAddress](gch.stackBottom)
|
var max = cast[ByteAddress](gch.stackBottom)
|
||||||
var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
|
var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
|
||||||
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
||||||
# otherwise sp would be below the registers structure).
|
# otherwise sp would be below the registers structure).
|
||||||
while sp >=% max:
|
while sp >=% max:
|
||||||
gcMark(gch, cast[ppointer](sp)[])
|
gcMark(gch, cast[PPointer](sp)[])
|
||||||
sp = sp -% sizeof(pointer)
|
sp = sp -% sizeof(pointer)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
@ -1127,9 +1129,9 @@ else:
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var stackTop {.volatile.}: pointer
|
var stackTop {.volatile.}: pointer
|
||||||
stackTop = addr(stackTop)
|
stackTop = addr(stackTop)
|
||||||
var b = cast[TAddress](gch.stackBottom)
|
var b = cast[ByteAddress](gch.stackBottom)
|
||||||
var a = cast[TAddress](stackTop)
|
var a = cast[ByteAddress](stackTop)
|
||||||
var x = cast[TAddress](p)
|
var x = cast[ByteAddress](p)
|
||||||
result = a <=% x and x <=% b
|
result = a <=% x and x <=% b
|
||||||
|
|
||||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||||
|
|
@ -1141,18 +1143,18 @@ else:
|
||||||
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||||
when MinimumStackMarking:
|
when MinimumStackMarking:
|
||||||
# mark the registers
|
# mark the registers
|
||||||
var jmpbufPtr = cast[TAddress](addr(registers))
|
var jmpbufPtr = cast[ByteAddress](addr(registers))
|
||||||
var jmpbufEnd = jmpbufPtr +% jmpbufSize
|
var jmpbufEnd = jmpbufPtr +% jmpbufSize
|
||||||
|
|
||||||
while jmpbufPtr <=% jmpbufEnd:
|
while jmpbufPtr <=% jmpbufEnd:
|
||||||
gcMark(gch, cast[ppointer](jmpbufPtr)[])
|
gcMark(gch, cast[PPointer](jmpbufPtr)[])
|
||||||
jmpbufPtr = jmpbufPtr +% sizeof(pointer)
|
jmpbufPtr = jmpbufPtr +% sizeof(pointer)
|
||||||
|
|
||||||
var sp = cast[TAddress](gch.stackTop)
|
var sp = cast[ByteAddress](gch.stackTop)
|
||||||
else:
|
else:
|
||||||
var sp = cast[TAddress](addr(registers))
|
var sp = cast[ByteAddress](addr(registers))
|
||||||
# mark the user stack
|
# mark the user stack
|
||||||
var max = cast[TAddress](gch.stackBottom)
|
var max = cast[ByteAddress](gch.stackBottom)
|
||||||
# loop unrolled:
|
# loop unrolled:
|
||||||
while sp <% max - 8*sizeof(pointer):
|
while sp <% max - 8*sizeof(pointer):
|
||||||
gcMark(gch, cast[PStackSlice](sp)[0])
|
gcMark(gch, cast[PStackSlice](sp)[0])
|
||||||
|
|
@ -1166,7 +1168,7 @@ else:
|
||||||
sp = sp +% sizeof(pointer)*8
|
sp = sp +% sizeof(pointer)*8
|
||||||
# last few entries:
|
# last few entries:
|
||||||
while sp <=% max:
|
while sp <=% max:
|
||||||
gcMark(gch, cast[ppointer](sp)[])
|
gcMark(gch, cast[PPointer](sp)[])
|
||||||
sp = sp +% sizeof(pointer)
|
sp = sp +% sizeof(pointer)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
@ -1202,7 +1204,7 @@ proc releaseCell(gch: var TGcHeap, cell: PCell) =
|
||||||
# recursion).
|
# recursion).
|
||||||
# We can ignore it now as the ZCT cleaner will reach it soon.
|
# We can ignore it now as the ZCT cleaner will reach it soon.
|
||||||
|
|
||||||
proc CollectZCT(gch: var TGcHeap): bool =
|
proc collectZCT(gch: var TGcHeap): bool =
|
||||||
const workPackage = 100
|
const workPackage = 100
|
||||||
var L = addr(gch.zct.len)
|
var L = addr(gch.zct.len)
|
||||||
|
|
||||||
|
|
@ -1213,8 +1215,8 @@ proc CollectZCT(gch: var TGcHeap): bool =
|
||||||
|
|
||||||
while L[] > 0:
|
while L[] > 0:
|
||||||
var c = gch.zct.d[0]
|
var c = gch.zct.d[0]
|
||||||
sysAssert c.isBitUp(rcZct), "CollectZCT: rcZct missing!"
|
sysAssert c.isBitUp(rcZct), "collectZCT: rcZct missing!"
|
||||||
sysAssert(isAllocatedPtr(gch.region, c), "CollectZCT: isAllocatedPtr")
|
sysAssert(isAllocatedPtr(gch.region, c), "collectZCT: isAllocatedPtr")
|
||||||
|
|
||||||
# remove from ZCT:
|
# remove from ZCT:
|
||||||
c.clearBit(rcZct)
|
c.clearBit(rcZct)
|
||||||
|
|
@ -1295,7 +1297,7 @@ proc collectCTBody(gch: var TGcHeap) =
|
||||||
sysAssert gch.zct.len == 0, "zct is not null after collect cycles"
|
sysAssert gch.zct.len == 0, "zct is not null after collect cycles"
|
||||||
inc(gch.stat.cycleCollections)
|
inc(gch.stat.cycleCollections)
|
||||||
gch.cycleThreshold = max(InitialCycleThreshold, getOccupiedMem() *
|
gch.cycleThreshold = max(InitialCycleThreshold, getOccupiedMem() *
|
||||||
cycleIncrease)
|
CycleIncrease)
|
||||||
gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold)
|
gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold)
|
||||||
unmarkStackAndRegisters(gch)
|
unmarkStackAndRegisters(gch)
|
||||||
sysAssert(allocInv(gch.region), "collectCT: end")
|
sysAssert(allocInv(gch.region), "collectCT: end")
|
||||||
|
|
@ -1346,10 +1348,10 @@ when not defined(useNimRtl):
|
||||||
|
|
||||||
proc GC_setStrategy(strategy: GC_Strategy) =
|
proc GC_setStrategy(strategy: GC_Strategy) =
|
||||||
case strategy
|
case strategy
|
||||||
of gcThroughput: nil
|
of gcThroughput: discard
|
||||||
of gcResponsiveness: nil
|
of gcResponsiveness: discard
|
||||||
of gcOptimizeSpace: nil
|
of gcOptimizeSpace: discard
|
||||||
of gcOptimizeTime: nil
|
of gcOptimizeTime: discard
|
||||||
|
|
||||||
proc GC_enableMarkAndSweep() =
|
proc GC_enableMarkAndSweep() =
|
||||||
gch.cycleThreshold = InitialCycleThreshold
|
gch.cycleThreshold = InitialCycleThreshold
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
when compileOption("gc", "v2"):
|
when compileOption("gc", "v2"):
|
||||||
for i in newLen..result.len-1:
|
for i in newLen..result.len-1:
|
||||||
let len0 = gch.tempStack.len
|
let len0 = gch.tempStack.len
|
||||||
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
|
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
||||||
GenericSeqSize +% (i*%elemSize)),
|
GenericSeqSize +% (i*%elemSize)),
|
||||||
extGetCellType(result).base, waPush)
|
extGetCellType(result).base, waPush)
|
||||||
let len1 = gch.tempStack.len
|
let len1 = gch.tempStack.len
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue