cycle breaker (#13593)
* cycle breaking as an alternative to cycle detection
This commit is contained in:
parent
705e283fef
commit
35fb38629f
10 changed files with 298 additions and 41 deletions
|
|
@ -1606,10 +1606,33 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
|||
a.storage)
|
||||
gcUsage(p.config, e)
|
||||
|
||||
proc rdMType(p: BProc; a: TLoc; nilCheck: var Rope): Rope =
|
||||
result = rdLoc(a)
|
||||
var t = skipTypes(a.t, abstractInst)
|
||||
while t.kind in {tyVar, tyLent, tyPtr, tyRef}:
|
||||
if t.kind notin {tyVar, tyLent}: nilCheck = result
|
||||
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
|
||||
result = "(*$1)" % [result]
|
||||
t = skipTypes(t.lastSon, abstractInst)
|
||||
discard getTypeDesc(p.module, t)
|
||||
if not p.module.compileToCpp:
|
||||
while t.kind == tyObject and t[0] != nil:
|
||||
result.add(".Sup")
|
||||
t = skipTypes(t[0], skipPtrs)
|
||||
result.add ".m_type"
|
||||
|
||||
proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) =
|
||||
discard cgsym(p.module, "TNimType")
|
||||
let t = e[1].typ
|
||||
putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info))
|
||||
if isFinal(t) or e[0].sym.name.s != "getDynamicTypeInfo":
|
||||
# ordinary static type information
|
||||
putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info))
|
||||
else:
|
||||
var a: TLoc
|
||||
initLocExpr(p, e[1], a)
|
||||
var nilCheck = Rope(nil)
|
||||
# use the dynamic type stored at offset 0:
|
||||
putIntoDest(p, d, e, rdMType(p, a, nilCheck))
|
||||
|
||||
template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
|
||||
var a: TLoc
|
||||
|
|
@ -2113,21 +2136,6 @@ proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
|
|||
n[0] = newSymNode(toStrProc)
|
||||
expr(p, n, d)
|
||||
|
||||
proc rdMType(p: BProc; a: TLoc; nilCheck: var Rope): Rope =
|
||||
result = rdLoc(a)
|
||||
var t = skipTypes(a.t, abstractInst)
|
||||
while t.kind in {tyVar, tyLent, tyPtr, tyRef}:
|
||||
if t.kind notin {tyVar, tyLent}: nilCheck = result
|
||||
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
|
||||
result = "(*$1)" % [result]
|
||||
t = skipTypes(t.lastSon, abstractInst)
|
||||
discard getTypeDesc(p.module, t)
|
||||
if not p.module.compileToCpp:
|
||||
while t.kind == tyObject and t[0] != nil:
|
||||
result.add(".Sup")
|
||||
t = skipTypes(t[0], skipPtrs)
|
||||
result.add ".m_type"
|
||||
|
||||
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
case op
|
||||
of mOr, mAnd: genAndOr(p, e, d, op)
|
||||
|
|
|
|||
|
|
@ -1291,6 +1291,11 @@ proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp): Rope =
|
|||
genProc(m, theProc)
|
||||
result = theProc.loc.r
|
||||
else:
|
||||
if op == attachedTrace and m.config.selectedGC == gcOrc and
|
||||
containsGarbageCollectedRef(t):
|
||||
when false:
|
||||
# re-enable this check
|
||||
internalError(m.config, info, "no attached trace proc found")
|
||||
result = rope("NIM_NIL")
|
||||
|
||||
proc genTypeInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo) =
|
||||
|
|
|
|||
|
|
@ -484,10 +484,10 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
if isFinal(elemType):
|
||||
let typInfo = genBuiltin(c.g, mGetTypeInfo, "getTypeInfo", newNodeIT(nkType, x.info, elemType))
|
||||
typInfo.typ = getSysType(c.g, c.info, tyPointer)
|
||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, x, typInfo, y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x), typInfo, y)
|
||||
else:
|
||||
# If the ref is polymorphic we have to account for this
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, x, y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x), y)
|
||||
of attachedDispose:
|
||||
# this is crucial! dispose is like =destroy but we don't follow refs
|
||||
# as that is dealt within the cycle collector.
|
||||
|
|
@ -530,7 +530,7 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
body.add genIf(c, cond, actions)
|
||||
of attachedDeepCopy: assert(false, "cannot happen")
|
||||
of attachedTrace:
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, xenv, y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv), y)
|
||||
of attachedDispose:
|
||||
# this is crucial! dispose is like =destroy but we don't follow refs
|
||||
# as that is dealt within the cycle collector.
|
||||
|
|
@ -778,7 +778,6 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
|||
# register this operation already:
|
||||
typ.attachedOps[kind] = result
|
||||
|
||||
|
||||
if kind == attachedSink and typ.attachedOps[attachedDestructor] != nil and
|
||||
sfOverriden in typ.attachedOps[attachedDestructor].flags:
|
||||
## compiler can use a combination of `=destroy` and memCopy for sink op
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ type
|
|||
warnUnusedImportX,
|
||||
warnInheritFromException,
|
||||
warnEachIdentIsTuple,
|
||||
warnProveInit, warnProveField, warnProveIndex,
|
||||
warnProveInit, warnProveField, warnProveIndex,
|
||||
warnStaticIndexCheck, warnGcUnsafe, warnGcUnsafe2,
|
||||
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
|
||||
warnInconsistentSpacing, warnCaseTransition, warnCycleCreated, warnUser,
|
||||
|
|
|
|||
|
|
@ -696,8 +696,16 @@ proc checkRange(c: PEffects; value: PNode; typ: PType) =
|
|||
checkLe(c, value, highBound)
|
||||
|
||||
proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
|
||||
if typ == nil: return
|
||||
let realType = typ.skipTypes(abstractInst)
|
||||
when false:
|
||||
# XXX fix this in liftdestructors instead
|
||||
if realType.kind == tyRef and
|
||||
optSeqDestructors in tracked.config.globalOptions:
|
||||
createTypeBoundOps(tracked.graph, tracked.c, realType.lastSon, info)
|
||||
|
||||
createTypeBoundOps(tracked.graph, tracked.c, typ, info)
|
||||
if (typ != nil and tfHasAsgn in typ.flags) or
|
||||
if (tfHasAsgn in typ.flags) or
|
||||
optSeqDestructors in tracked.config.globalOptions:
|
||||
tracked.owner.flags.incl sfInjectDestructors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue