ORC: use =destroy instead of =dispose (#18440)
* ORC refactoring in preparation for further changes (=dispose must die) * ORC: embrace =destroy, avoid =dispose * ORC: no need for =dispose * closes #18421
This commit is contained in:
parent
d1447fe25d
commit
3eb3e6b9a3
10 changed files with 205 additions and 81 deletions
|
|
@ -10,20 +10,20 @@
|
|||
# Cell seqs for cyclebreaker and cyclicrefs_v2.
|
||||
|
||||
type
|
||||
CellTuple = (PT, PNimTypeV2)
|
||||
CellArray = ptr UncheckedArray[CellTuple]
|
||||
CellSeq = object
|
||||
CellTuple[T] = (T, PNimTypeV2)
|
||||
CellArray[T] = ptr UncheckedArray[CellTuple[T]]
|
||||
CellSeq[T] = object
|
||||
len, cap: int
|
||||
d: CellArray
|
||||
d: CellArray[T]
|
||||
|
||||
proc add(s: var CellSeq, c: PT; t: PNimTypeV2) {.inline.} =
|
||||
proc add[T](s: var CellSeq[T], c: T; t: PNimTypeV2) {.inline.} =
|
||||
if s.len >= s.cap:
|
||||
s.cap = s.cap * 3 div 2
|
||||
when compileOption("threads"):
|
||||
var d = cast[CellArray](allocShared(uint(s.cap * sizeof(CellTuple))))
|
||||
var d = cast[CellArray[T]](allocShared(uint(s.cap * sizeof(CellTuple[T]))))
|
||||
else:
|
||||
var d = cast[CellArray](alloc(s.cap * sizeof(CellTuple)))
|
||||
copyMem(d, s.d, s.len * sizeof(CellTuple))
|
||||
var d = cast[CellArray[T]](alloc(s.cap * sizeof(CellTuple[T])))
|
||||
copyMem(d, s.d, s.len * sizeof(CellTuple[T]))
|
||||
when compileOption("threads"):
|
||||
deallocShared(s.d)
|
||||
else:
|
||||
|
|
@ -33,15 +33,15 @@ proc add(s: var CellSeq, c: PT; t: PNimTypeV2) {.inline.} =
|
|||
s.d[s.len] = (c, t)
|
||||
inc(s.len)
|
||||
|
||||
proc init(s: var CellSeq, cap: int = 1024) =
|
||||
proc init[T](s: var CellSeq[T], cap: int = 1024) =
|
||||
s.len = 0
|
||||
s.cap = cap
|
||||
when compileOption("threads"):
|
||||
s.d = cast[CellArray](allocShared(uint(s.cap * sizeof(CellTuple))))
|
||||
s.d = cast[CellArray[T]](allocShared(uint(s.cap * sizeof(CellTuple[T]))))
|
||||
else:
|
||||
s.d = cast[CellArray](alloc(s.cap * sizeof(CellTuple)))
|
||||
s.d = cast[CellArray[T]](alloc(s.cap * sizeof(CellTuple[T])))
|
||||
|
||||
proc deinit(s: var CellSeq) =
|
||||
proc deinit[T](s: var CellSeq[T]) =
|
||||
if s.d != nil:
|
||||
when compileOption("threads"):
|
||||
deallocShared(s.d)
|
||||
|
|
@ -51,6 +51,6 @@ proc deinit(s: var CellSeq) =
|
|||
s.len = 0
|
||||
s.cap = 0
|
||||
|
||||
proc pop(s: var CellSeq): (PT, PNimTypeV2) =
|
||||
proc pop[T](s: var CellSeq[T]): (T, PNimTypeV2) =
|
||||
result = s.d[s.len-1]
|
||||
dec s.len
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ depth-first traversal suffices.
|
|||
|
||||
]#
|
||||
|
||||
type PT = ptr pointer
|
||||
include cellseqs_v2
|
||||
|
||||
const
|
||||
|
|
@ -78,7 +77,7 @@ proc nimMarkCyclic(p: pointer) {.compilerRtl, inl.} = discard
|
|||
|
||||
type
|
||||
GcEnv = object
|
||||
traceStack: CellSeq
|
||||
traceStack: CellSeq[ptr pointer]
|
||||
|
||||
proc trace(p: pointer; desc: PNimTypeV2; j: var GcEnv) {.inline.} =
|
||||
when false:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
# R.D. Lins / Information Processing Letters 109 (2008) 71–78
|
||||
#
|
||||
|
||||
type PT = Cell
|
||||
include cellseqs_v2
|
||||
|
||||
const
|
||||
|
|
@ -68,10 +67,10 @@ const
|
|||
|
||||
type
|
||||
GcEnv = object
|
||||
traceStack: CellSeq
|
||||
traceStack: CellSeq[ptr pointer]
|
||||
when useJumpStack:
|
||||
jumpStack: CellSeq # Lins' jump stack in order to speed up traversals
|
||||
toFree: CellSeq
|
||||
jumpStack: CellSeq[ptr pointer] # Lins' jump stack in order to speed up traversals
|
||||
toFree: CellSeq[Cell]
|
||||
freed, touched, edges, rcSum: int
|
||||
keepThreshold: bool
|
||||
|
||||
|
|
@ -92,13 +91,13 @@ proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
|
|||
|
||||
when logOrc: writeCell("free", s, desc)
|
||||
|
||||
if desc.disposeImpl != nil:
|
||||
cast[DisposeProc](desc.disposeImpl)(p)
|
||||
if desc.destructor != nil:
|
||||
cast[DestructorProc](desc.destructor)(p)
|
||||
|
||||
when false:
|
||||
cstderr.rawWrite desc.name
|
||||
cstderr.rawWrite " "
|
||||
if desc.disposeImpl == nil:
|
||||
if desc.destructor == nil:
|
||||
cstderr.rawWrite "lacks dispose"
|
||||
if desc.traceImpl != nil:
|
||||
cstderr.rawWrite ", but has trace\n"
|
||||
|
|
@ -125,16 +124,16 @@ proc nimTraceRef(q: pointer; desc: PNimTypeV2; env: pointer) {.compilerRtl, inli
|
|||
orcAssert strstr(desc.name, "TType") == nil, "following a TType but it's acyclic!"
|
||||
|
||||
var j = cast[ptr GcEnv](env)
|
||||
j.traceStack.add(head p[], desc)
|
||||
j.traceStack.add(p, desc)
|
||||
|
||||
proc nimTraceRefDyn(q: pointer; env: pointer) {.compilerRtl, inline.} =
|
||||
let p = cast[ptr pointer](q)
|
||||
if p[] != nil:
|
||||
var j = cast[ptr GcEnv](env)
|
||||
j.traceStack.add(head p[], cast[ptr PNimTypeV2](p[])[])
|
||||
j.traceStack.add(p, cast[ptr PNimTypeV2](p[])[])
|
||||
|
||||
var
|
||||
roots {.threadvar.}: CellSeq
|
||||
roots {.threadvar.}: CellSeq[Cell]
|
||||
|
||||
proc unregisterCycle(s: Cell) =
|
||||
# swap with the last element. O(1)
|
||||
|
|
@ -162,7 +161,8 @@ proc scanBlack(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
|
|||
trace(s, desc, j)
|
||||
when logOrc: writeCell("root still alive", s, desc)
|
||||
while j.traceStack.len > until:
|
||||
let (t, desc) = j.traceStack.pop()
|
||||
let (entry, desc) = j.traceStack.pop()
|
||||
let t = head entry[]
|
||||
inc t.rc, rcIncrement
|
||||
if t.color != colBlack:
|
||||
t.setColor colBlack
|
||||
|
|
@ -187,7 +187,8 @@ proc markGray(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
|
|||
orcAssert(j.traceStack.len == 0, "markGray: trace stack not empty")
|
||||
trace(s, desc, j)
|
||||
while j.traceStack.len > 0:
|
||||
let (t, desc) = j.traceStack.pop()
|
||||
let (entry, desc) = j.traceStack.pop()
|
||||
let t = head entry[]
|
||||
dec t.rc, rcIncrement
|
||||
inc j.edges
|
||||
when useJumpStack:
|
||||
|
|
@ -195,7 +196,7 @@ proc markGray(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
|
|||
t.rc = t.rc or jumpStackFlag
|
||||
when traceCollector:
|
||||
cprintf("[Now in jumpstack] %p %ld color %ld in jumpstack %ld\n", t, t.rc shr rcShift, t.color, t.rc and jumpStackFlag)
|
||||
j.jumpStack.add(t, desc)
|
||||
j.jumpStack.add(entry, desc)
|
||||
if t.color != colGray:
|
||||
t.setColor colGray
|
||||
inc j.touched
|
||||
|
|
@ -225,7 +226,8 @@ proc scan(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
|
|||
# that are still alive; we also need to mark what they
|
||||
# refer to as alive:
|
||||
while j.jumpStack.len > 0:
|
||||
let (t, desc) = j.jumpStack.pop
|
||||
let (entry, desc) = j.jumpStack.pop
|
||||
let t = head entry[]
|
||||
# not in jump stack anymore!
|
||||
t.rc = t.rc and not jumpStackFlag
|
||||
if t.color == colGray and (t.rc shr rcShift) >= 0:
|
||||
|
|
@ -239,7 +241,8 @@ proc scan(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
|
|||
s.setColor(colWhite)
|
||||
trace(s, desc, j)
|
||||
while j.traceStack.len > 0:
|
||||
let (t, desc) = j.traceStack.pop()
|
||||
let (entry, desc) = j.traceStack.pop()
|
||||
let t = head entry[]
|
||||
if t.color == colGray:
|
||||
if (t.rc shr rcShift) >= 0:
|
||||
scanBlack(t, desc, j)
|
||||
|
|
@ -249,7 +252,8 @@ proc scan(s: Cell; desc: PNimTypeV2; j: var GcEnv) =
|
|||
# that are still alive; we also need to mark what they
|
||||
# refer to as alive:
|
||||
while j.jumpStack.len > 0:
|
||||
let (t, desc) = j.jumpStack.pop
|
||||
let (entry, desc) = j.jumpStack.pop
|
||||
let t = head entry[]
|
||||
# not in jump stack anymore!
|
||||
t.rc = t.rc and not jumpStackFlag
|
||||
if t.color == colGray and (t.rc shr rcShift) >= 0:
|
||||
|
|
@ -285,7 +289,9 @@ proc collectColor(s: Cell; desc: PNimTypeV2; col: int; j: var GcEnv) =
|
|||
j.toFree.add(s, desc)
|
||||
trace(s, desc, j)
|
||||
while j.traceStack.len > 0:
|
||||
let (t, desc) = j.traceStack.pop()
|
||||
let (entry, desc) = j.traceStack.pop()
|
||||
let t = head entry[]
|
||||
entry[] = nil # ensure that the destructor does touch moribund objects!
|
||||
if t.color == col and t.rootIdx == 0:
|
||||
j.toFree.add(t, desc)
|
||||
t.setColor(colBlack)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue