--gc:destructors improvements (#12626)

* do not cache the noDestructors transformation
* liftdestructor: improvements
* undo bugfix
This commit is contained in:
Andreas Rumpf 2019-11-09 13:21:55 +01:00 • committed by GitHub
commit 82e0765fc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 14 deletions

View file

@ -327,6 +327,14 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
createTypeBoundOps(c.g, c.c, t, body.info) createTypeBoundOps(c.g, c.c, t, body.info)
# recursions are tricky, so we might need to forward the generated
# operation here:
var t = t
if t.assignment == nil or t.destructor == nil:
let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
let canon = c.g.canonTypes.getOrDefault(h)
if canon != nil: t = canon
case c.kind case c.kind
of attachedAsgn, attachedDeepCopy: of attachedAsgn, attachedDeepCopy:
doAssert t.assignment != nil doAssert t.assignment != nil
@ -682,24 +690,23 @@ template inst(field, t) =
else: else:
localError(g.config, info, "unresolved generic parameter") localError(g.config, info, "unresolved generic parameter")
proc isTrival(s: PSym): bool {.inline.} = s == nil or s.ast[bodyPos].len == 0 proc isTrival(s: PSym): bool {.inline.} =
s == nil or (s.ast != nil and s.ast[bodyPos].len == 0)
proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) = proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) =
## In the semantic pass this is called in strategic places ## In the semantic pass this is called in strategic places
## to ensure we lift assignment, destructors and moves properly. ## to ensure we lift assignment, destructors and moves properly.
## The later 'injectdestructors' pass depends on it. ## The later 'injectdestructors' pass depends on it.
if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.skipTypes({tyAlias}).flags != {}: return if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.flags != {}: return
incl orig.flags, tfCheckedForDestructor incl orig.flags, tfCheckedForDestructor
let h = sighashes.hashType(orig, {CoType, CoConsiderOwned, CoDistinct}) let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
let h = sighashes.hashType(skipped, {CoType, CoConsiderOwned, CoDistinct})
var canon = g.canonTypes.getOrDefault(h) var canon = g.canonTypes.getOrDefault(h)
var overwrite = false
if canon == nil: if canon == nil:
let typ = orig.skipTypes({tyGenericInst, tyAlias, tySink}) g.canonTypes[h] = skipped
g.canonTypes[h] = typ canon = skipped
canon = typ
if canon != orig:
overwrite = true
# multiple cases are to distinguish here: # multiple cases are to distinguish here:
# 1. we don't know yet if 'typ' has a nontrival destructor. # 1. we don't know yet if 'typ' has a nontrival destructor.
@ -714,9 +721,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
discard produceSym(g, c, canon, k, info) discard produceSym(g, c, canon, k, info)
else: else:
inst(canon.attachedOps[k], canon) inst(canon.attachedOps[k], canon)
if canon != orig:
if overwrite:
for k in attachedDestructor..attachedSink:
orig.attachedOps[k] = canon.attachedOps[k] orig.attachedOps[k] = canon.attachedOps[k]
if not isTrival(orig.destructor): if not isTrival(orig.destructor):

View file

@ -1137,8 +1137,7 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;
incl(result.flags, nfTransf) incl(result.flags, nfTransf)
let cache = cache or prc.typ.callConv == ccInline if cache or prc.typ.callConv == ccInline:
if cache:
# genProc for inline procs will be called multiple times from different modules, # genProc for inline procs will be called multiple times from different modules,
# it is important to transform exactly once to get sym ids and locations right # it is important to transform exactly once to get sym ids and locations right
prc.transformedBody = result prc.transformedBody = result