Replaced ignoreStackAndRegisters with stackSize in GC_step
This commit is contained in:
parent
f288eb7543
commit
0dc35b7841
3 changed files with 55 additions and 33 deletions
14
doc/gc.txt
14
doc/gc.txt
|
|
@ -56,7 +56,7 @@ file as well). With this switch the GC supports the following operations:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
proc GC_setMaxPause*(MaxPauseInUs: int)
|
proc GC_setMaxPause*(MaxPauseInUs: int)
|
||||||
proc GC_step*(us: int, strongAdvice, ignoreStackAndRegisters = false)
|
proc GC_step*(us: int, strongAdvice = false, stackSize = -1)
|
||||||
|
|
||||||
The unit of the parameters ``MaxPauseInUs`` and ``us`` is microseconds.
|
The unit of the parameters ``MaxPauseInUs`` and ``us`` is microseconds.
|
||||||
|
|
||||||
|
|
@ -75,11 +75,13 @@ These two procs are the two modus operandi of the realtime GC:
|
||||||
This allows the GC to perform some work for up to ``us`` time. This is
|
This allows the GC to perform some work for up to ``us`` time. This is
|
||||||
useful to call in a main loop to ensure the GC can do its work. To
|
useful to call in a main loop to ensure the GC can do its work. To
|
||||||
bind all GC activity to a ``GC_step`` call, deactivate the GC with
|
bind all GC activity to a ``GC_step`` call, deactivate the GC with
|
||||||
``GC_disable`` at program startup. Notice that you may ask GC to not
|
``GC_disable`` at program startup. If ``strongAdvice`` is set to ``true``,
|
||||||
scan stack and registers for references via ``ignoreStackAndRegisters``
|
GC will be forced to perform collection cycle. Otherwise, GC may decide not
|
||||||
parameter. This may reduce the step time depending on the stack depth,
|
to do anything, if there is not much garbage to collect.
|
||||||
but use it only when you are sure that neither the stack nor the registers
|
You may also specify the current stack size via ``stackSize`` parameter.
|
||||||
contain unique references to objects that must be preserved.
|
It can improve performance, when you know that there are no unique Nim
|
||||||
|
references below certain point on the stack. Make sure the size you specify
|
||||||
|
is greater than the potential worst case size.
|
||||||
|
|
||||||
These procs provide a "best effort" realtime guarantee; in particular the
|
These procs provide a "best effort" realtime guarantee; in particular the
|
||||||
cycle collector is not aware of deadlines yet. Deactivate it to get more
|
cycle collector is not aware of deadlines yet. Deactivate it to get more
|
||||||
|
|
|
||||||
|
|
@ -905,19 +905,19 @@ proc unmarkStackAndRegisters(gch: var GcHeap) =
|
||||||
#sysAssert c.typ != nil, "unmarkStackAndRegisters 2"
|
#sysAssert c.typ != nil, "unmarkStackAndRegisters 2"
|
||||||
gch.decStack.len = 0
|
gch.decStack.len = 0
|
||||||
|
|
||||||
proc collectCTBody(gch: var GcHeap, ignoreStackAndRegisters = false) =
|
proc collectCTBody(gch: var GcHeap) =
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
let t0 = getticks()
|
let t0 = getticks()
|
||||||
sysAssert(allocInv(gch.region), "collectCT: begin")
|
sysAssert(allocInv(gch.region), "collectCT: begin")
|
||||||
|
|
||||||
|
when not defined(nimCoroutines):
|
||||||
|
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
|
||||||
sysAssert(gch.decStack.len == 0, "collectCT")
|
sysAssert(gch.decStack.len == 0, "collectCT")
|
||||||
prepareForInteriorPointerChecking(gch.region)
|
prepareForInteriorPointerChecking(gch.region)
|
||||||
if not ignoreStackAndRegisters:
|
markStackAndRegisters(gch)
|
||||||
when not defined(nimCoroutines):
|
markThreadStacks(gch)
|
||||||
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
|
gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len)
|
||||||
markStackAndRegisters(gch)
|
inc(gch.stat.stackScans)
|
||||||
markThreadStacks(gch)
|
|
||||||
gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len)
|
|
||||||
inc(gch.stat.stackScans)
|
|
||||||
if collectZCT(gch):
|
if collectZCT(gch):
|
||||||
when cycleGC:
|
when cycleGC:
|
||||||
if getOccupiedMem(gch.region) >= gch.cycleThreshold or alwaysCycleGC:
|
if getOccupiedMem(gch.region) >= gch.cycleThreshold or alwaysCycleGC:
|
||||||
|
|
@ -927,8 +927,7 @@ proc collectCTBody(gch: var GcHeap, ignoreStackAndRegisters = false) =
|
||||||
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)
|
||||||
if not ignoreStackAndRegisters:
|
unmarkStackAndRegisters(gch)
|
||||||
unmarkStackAndRegisters(gch)
|
|
||||||
sysAssert(allocInv(gch.region), "collectCT: end")
|
sysAssert(allocInv(gch.region), "collectCT: end")
|
||||||
|
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
|
|
@ -972,17 +971,28 @@ when withRealTime:
|
||||||
proc GC_setMaxPause*(MaxPauseInUs: int) =
|
proc GC_setMaxPause*(MaxPauseInUs: int) =
|
||||||
gch.maxPause = MaxPauseInUs.toNano
|
gch.maxPause = MaxPauseInUs.toNano
|
||||||
|
|
||||||
proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool, ignoreStackAndRegisters: bool) =
|
proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool) =
|
||||||
acquire(gch)
|
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, ignoreStackAndRegisters)
|
collectCTBody(gch)
|
||||||
release(gch)
|
release(gch)
|
||||||
|
|
||||||
proc GC_step*(us: int, strongAdvice, ignoreStackAndRegisters = false) =
|
proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
|
||||||
GC_step(gch, us, strongAdvice, ignoreStackAndRegisters)
|
var stackTop {.volatile.}: pointer
|
||||||
|
let prevStackBottom = gch.stackBottom
|
||||||
|
if stackSize >= 0:
|
||||||
|
stackTop = addr(stackTop)
|
||||||
|
when stackIncreases:
|
||||||
|
gch.stackBottom = cast[pointer](
|
||||||
|
cast[ByteAddress](stackTop) - sizeof(pointer) * 6 - stackSize)
|
||||||
|
else:
|
||||||
|
gch.stackBottom = cast[pointer](
|
||||||
|
cast[ByteAddress](stackTop) + sizeof(pointer) * 6 + stackSize)
|
||||||
|
GC_step(gch, us, strongAdvice)
|
||||||
|
gch.stackBottom = prevStackBottom
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
proc GC_disable() =
|
proc GC_disable() =
|
||||||
|
|
|
||||||
|
|
@ -894,18 +894,18 @@ proc unmarkStackAndRegisters(gch: var GcHeap) =
|
||||||
decRef(d[i])
|
decRef(d[i])
|
||||||
gch.decStack.len = 0
|
gch.decStack.len = 0
|
||||||
|
|
||||||
proc collectCTBody(gch: var GcHeap, ignoreStackAndRegisters = false) =
|
proc collectCTBody(gch: var GcHeap) =
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
let t0 = getticks()
|
let t0 = getticks()
|
||||||
sysAssert(allocInv(gch.region), "collectCT: begin")
|
sysAssert(allocInv(gch.region), "collectCT: begin")
|
||||||
|
|
||||||
|
when not defined(nimCoroutines):
|
||||||
|
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
|
||||||
sysAssert(gch.decStack.len == 0, "collectCT")
|
sysAssert(gch.decStack.len == 0, "collectCT")
|
||||||
prepareForInteriorPointerChecking(gch.region)
|
prepareForInteriorPointerChecking(gch.region)
|
||||||
if not ignoreStackAndRegisters:
|
markStackAndRegisters(gch)
|
||||||
when not defined(nimCoroutines):
|
gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len)
|
||||||
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
|
inc(gch.stat.stackScans)
|
||||||
markStackAndRegisters(gch)
|
|
||||||
gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len)
|
|
||||||
inc(gch.stat.stackScans)
|
|
||||||
if collectZCT(gch):
|
if collectZCT(gch):
|
||||||
when cycleGC:
|
when cycleGC:
|
||||||
if getOccupiedMem(gch.region) >= gch.cycleThreshold or alwaysCycleGC:
|
if getOccupiedMem(gch.region) >= gch.cycleThreshold or alwaysCycleGC:
|
||||||
|
|
@ -914,8 +914,7 @@ proc collectCTBody(gch: var GcHeap, ignoreStackAndRegisters = false) =
|
||||||
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)
|
||||||
if not ignoreStackAndRegisters:
|
unmarkStackAndRegisters(gch)
|
||||||
unmarkStackAndRegisters(gch)
|
|
||||||
sysAssert(allocInv(gch.region), "collectCT: end")
|
sysAssert(allocInv(gch.region), "collectCT: end")
|
||||||
|
|
||||||
when withRealTime:
|
when withRealTime:
|
||||||
|
|
@ -950,15 +949,26 @@ when withRealTime:
|
||||||
proc GC_setMaxPause*(MaxPauseInUs: int) =
|
proc GC_setMaxPause*(MaxPauseInUs: int) =
|
||||||
gch.maxPause = MaxPauseInUs.toNano
|
gch.maxPause = MaxPauseInUs.toNano
|
||||||
|
|
||||||
proc GC_step(gch: var GcHeap, us: int, strongAdvice, ignoreStackAndRegisters: bool) =
|
proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool) =
|
||||||
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, ignoreStackAndRegisters)
|
collectCTBody(gch)
|
||||||
|
|
||||||
proc GC_step*(us: int, strongAdvice, ignoreStackAndRegisters = false) =
|
proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
|
||||||
GC_step(gch, us, strongAdvice, ignoreStackAndRegisters)
|
var stackTop {.volatile.}: pointer
|
||||||
|
let prevStackBottom = gch.stackBottom
|
||||||
|
if stackSize >= 0:
|
||||||
|
stackTop = addr(stackTop)
|
||||||
|
when stackIncreases:
|
||||||
|
gch.stackBottom = cast[pointer](
|
||||||
|
cast[ByteAddress](stackTop) - sizeof(pointer) * 6 - stackSize)
|
||||||
|
else:
|
||||||
|
gch.stackBottom = cast[pointer](
|
||||||
|
cast[ByteAddress](stackTop) + sizeof(pointer) * 6 + stackSize)
|
||||||
|
GC_step(gch, us, strongAdvice)
|
||||||
|
gch.stackBottom = prevStackBottom
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
proc GC_disable() =
|
proc GC_disable() =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue