diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-11-20 14:34:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-20 14:34:05 +0100 |
commit | 85ffcd80c05ae1bbf853121059c39a215a29ae54 (patch) | |
tree | 04d342d28caedab16c27aca10e3a3647c87944c3 | |
parent | a88004114d6bfbef31268c96f4d1fc871e70ab03 (diff) | |
download | Nim-85ffcd80c05ae1bbf853121059c39a215a29ae54.tar.gz |
more arc improvements (#12690)
* ARC: bugfix for =destroy for inherited objects * added code useful for debugging
-rw-r--r-- | compiler/lowerings.nim | 8 | ||||
-rw-r--r-- | compiler/sempass2.nim | 5 | ||||
-rw-r--r-- | lib/core/runtime_v2.nim | 7 | ||||
-rw-r--r-- | tests/destructor/tarc.nim (renamed from tests/destructor/tlists.nim) | 17 |
4 files changed, 32 insertions, 5 deletions
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index d372ac0c1..0922ab088 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -150,11 +150,18 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType s.typ = result result.sym = s +template fieldCheck {.dirty.} = + when false: + if tfCheckedForDestructor in obj.flags: + echo "missed field ", field.name.s + writeStackTrace() + proc rawAddField*(obj: PType; field: PSym) = assert field.kind == skField field.position = len(obj.n) addSon(obj.n, newSymNode(field)) propagateToOwner(obj, field.typ) + fieldCheck() proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode = # returns a[].field as a node @@ -208,6 +215,7 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) = propagateToOwner(obj, t) field.position = len(obj.n) addSon(obj.n, newSymNode(field)) + fieldCheck() proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} = result = lookupInRecord(obj.n, s.id) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ef0dcec00..00afb737d 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -855,6 +855,8 @@ proc track(tracked: PEffects, n: PNode) = if x.sons[0].kind == nkSym and sfDiscriminant in x.sons[0].sym.flags: addDiscriminantFact(tracked.guards, x) setLen(tracked.guards.s, oldFacts) + if tracked.owner.kind != skMacro: + createTypeBoundOps(tracked, n.typ, n.info) of nkPragmaBlock: let pragmaList = n.sons[0] let oldLocked = tracked.locked.len @@ -885,7 +887,8 @@ proc track(tracked: PEffects, n: PNode) = if n.len == 1: track(tracked, n.sons[0]) of nkBracket: for i in 0 ..< safeLen(n): track(tracked, n.sons[i]) - createTypeBoundOps(tracked, n.typ, n.info) + if tracked.owner.kind != skMacro: + createTypeBoundOps(tracked, n.typ, n.info) else: for i in 0 ..< safeLen(n): track(tracked, n.sons[i]) diff --git a/lib/core/runtime_v2.nim b/lib/core/runtime_v2.nim index 0d55ff4ac..3dd4a77c6 100644 --- a/lib/core/runtime_v2.nim +++ b/lib/core/runtime_v2.nim @@ -68,6 +68,7 @@ proc nimIncRef(p: pointer) {.compilerRtl, inl.} = atomicInc head(p).rc else: inc head(p).rc + #cprintf("[INCREF] %p\n", p) proc nimRawDispose(p: pointer) {.compilerRtl.} = when not defined(nimscript): @@ -113,13 +114,15 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} = if atomicLoadN(addr head(p).rc, ATOMIC_RELAXED) == 0: result = true else: - if atomicDec(head(p).rc) <= 0: - result = true + discard atomicDec(head(p).rc) else: if head(p).rc == 0: result = true + #cprintf("[DESTROY] %p\n", p) else: dec head(p).rc + # According to Lins it's correct to do nothing else here. + #cprintf("[DeCREF] %p\n", p) proc GC_unref*[T](x: ref T) = ## New runtime only supports this operation for 'ref T'. diff --git a/tests/destructor/tlists.nim b/tests/destructor/tarc.nim index f5786d936..5c78605d2 100644 --- a/tests/destructor/tlists.nim +++ b/tests/destructor/tarc.nim @@ -4,7 +4,7 @@ discard """ Success @["a", "b", "c"] 0''' - cmd: '''nim c --gc:destructors $file''' + cmd: '''nim c --gc:arc $file''' """ import os @@ -69,10 +69,23 @@ proc take3 = for x in infinite.take(3): discard + +type + A = ref object of RootObj + x: int + + B = ref object of A + more: string + +proc inheritanceBug(param: string) = + var s: (A, A) + s[0] = B(more: "a" & param) + s[1] = B(more: "a" & param) + let startMem = getOccupiedMem() take3() tlazyList() - +inheritanceBug("whatever") mkManyLeaks() tsimpleClosureIterator() tleakingNewStmt() |