mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-05 03:14:08 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ...
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user