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:
Andreas Rumpf 2021-07-07 09:39:01 +02:00 • committed by GitHub
commit 3eb3e6b9a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 205 additions and 81 deletions

View file

@ -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

View file

@ -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:

View file

@ -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)