ORC: progress (#18000)

* ORC: progress

* ORC: bugfix; don't follow acyclic data even if only at runtime the subtype is marked as acyclic

* progress

* minor style changes

(cherry picked from commit 3bc625aff1)
This commit is contained in:
Andreas Rumpf
2021-05-12 22:00:37 +02:00
committed by narimiran
parent cb22a99584
commit 9fc0955587
8 changed files with 34 additions and 17 deletions

View File

@@ -16,7 +16,7 @@ const
Mhalf = M div 2
type
Node[Key, Val] = ref object
Node[Key, Val] {.acyclic.} = ref object
entries: int
keys: array[M, Key]
case isInternal: bool

View File

@@ -1327,6 +1327,10 @@ proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp): Rope =
genProc(m, theProc)
result = theProc.loc.r
when false:
if not canFormAcycle(t) and op == attachedTrace:
echo "ayclic but has this =trace ", t, " ", theProc.ast
else:
when false:
if op == attachedTrace and m.config.selectedGC == gcOrc and
@@ -1352,9 +1356,12 @@ proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineIn
let traceImpl = genHook(m, t, info, attachedTrace)
let disposeImpl = genHook(m, t, info, attachedDispose)
addf(m.s[cfsTypeInit3], "$1.destructor = (void*)$2; $1.size = sizeof($3); $1.align = NIM_ALIGNOF($3); $1.name = $4;$n; $1.traceImpl = (void*)$5; $1.disposeImpl = (void*)$6;", [
var flags = 0
if not canFormAcycle(t): flags = flags or 1
addf(m.s[cfsTypeInit3], "$1.destructor = (void*)$2; $1.size = sizeof($3); $1.align = NIM_ALIGNOF($3); $1.name = $4;$n; $1.traceImpl = (void*)$5; $1.disposeImpl = (void*)$6; $1.flags = $7;", [
name, destroyImpl, getTypeDesc(m, t), typeName,
traceImpl, disposeImpl])
traceImpl, disposeImpl, rope(flags)])
if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions:
discard genTypeInfoV1(m, t, info)

View File

@@ -468,8 +468,9 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
forallElements(c, t, body, x, y)
body.add genBuiltin(c.g, mDestroy, "destroy", x)
of attachedTrace:
# follow all elements:
forallElements(c, t, body, x, y)
if canFormAcycle(t.elemType):
# follow all elements:
forallElements(c, t, body, x, y)
of attachedDispose:
forallElements(c, t, body, x, y)
body.add genBuiltin(c.g, mDestroy, "destroy", x)

View File

@@ -25,8 +25,8 @@ type
POptionEntry* = ref TOptionEntry
PProcCon* = ref TProcCon
TProcCon* = object # procedure context; also used for top-level
# statements
TProcCon* {.acyclic.} = object # procedure context; also used for top-level
# statements
owner*: PSym # the symbol this context belongs to
resultSym*: PSym # the result symbol (if we are in a proc)
selfSym*: PSym # the 'self' symbol (if available)

View File

@@ -365,13 +365,13 @@ proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
if tfAcyclic in t.flags: return
case t.kind
of tyTuple, tyObject, tyRef, tySequence, tyArray, tyOpenArray, tyVarargs:
if not containsOrIncl(marker, t.id):
if t.id == startId:
result = true
elif not containsOrIncl(marker, t.id):
for i in 0..<t.len:
result = canFormAcycleAux(marker, t[i], startId)
if result: return
if t.n != nil: result = canFormAcycleNode(marker, t.n, startId)
else:
result = t.id == startId
# Inheritance can introduce cyclic types, however this is not relevant
# as the type that is passed to 'new' is statically known!
# er but we use it also for the write barrier ...

View File

@@ -265,7 +265,7 @@ type
templInstCounter*: ref int # gives every template instantiation a unique ID, needed here for getAst
PStackFrame* = ref TStackFrame
TStackFrame* = object
TStackFrame* {.acyclic.} = object
prc*: PSym # current prc; proc that is evaluated
slots*: seq[TFullReg] # parameters passed to the proc + locals;
# parameters come first

View File

@@ -1754,6 +1754,7 @@ when not defined(js) and defined(nimV2):
traceImpl: pointer
disposeImpl: pointer
typeInfoV1: pointer # for backwards compat, usually nil
flags: int
PNimTypeV2 = ptr TNimTypeV2
when notJSnotNims and defined(nimSeqsV2):

View File

@@ -90,9 +90,21 @@ proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
nimRawDispose(p, desc.align)
template orcAssert(cond, msg) =
when logOrc:
if not cond:
cfprintf(cstderr, "[Bug!] %s\n", msg)
quit 1
when logOrc:
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
proc nimTraceRef(q: pointer; desc: PNimTypeV2; env: pointer) {.compilerRtl, inline.} =
let p = cast[ptr pointer](q)
if p[] != nil:
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)
@@ -102,12 +114,6 @@ proc nimTraceRefDyn(q: pointer; env: pointer) {.compilerRtl, inline.} =
var j = cast[ptr GcEnv](env)
j.traceStack.add(head p[], cast[ptr PNimTypeV2](p[])[])
template orcAssert(cond, msg) =
when logOrc:
if not cond:
cfprintf(cstderr, "[Bug!] %s\n", msg)
quit 1
var
roots {.threadvar.}: CellSeq
@@ -349,6 +355,8 @@ proc registerCycle(s: Cell; desc: PNimTypeV2) =
collectCycles()
#writeCell("[added root]", s)
orcAssert strstr(desc.name, "TType") == nil, "added a TType as a root!"
proc GC_runOrc* =
## Forces a cycle collection pass.
collectCycles()