ARC: ported the GC tests over to --gc:arc
This commit is contained in:
parent
879801c639
commit
72237e2bcf
14 changed files with 79 additions and 29 deletions
|
|
@ -60,6 +60,7 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
|
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
|
||||||
temp.typ = skipTypes(value.typ, abstractInst)
|
temp.typ = skipTypes(value.typ, abstractInst)
|
||||||
incl(temp.flags, sfFromGeneric)
|
incl(temp.flags, sfFromGeneric)
|
||||||
|
incl(temp.flags, sfCursor)
|
||||||
|
|
||||||
var v = newNodeI(nkVarSection, value.info)
|
var v = newNodeI(nkVarSection, value.info)
|
||||||
let tempAsNode = newSymNode(temp)
|
let tempAsNode = newSymNode(temp)
|
||||||
|
|
|
||||||
|
|
@ -759,6 +759,7 @@ proc track(tracked: PEffects, n: PNode) =
|
||||||
# check required for 'nim check':
|
# check required for 'nim check':
|
||||||
if n[1].typ.len > 0:
|
if n[1].typ.len > 0:
|
||||||
createTypeBoundOps(tracked, n[1].typ.lastSon, n.info)
|
createTypeBoundOps(tracked, n[1].typ.lastSon, n.info)
|
||||||
|
createTypeBoundOps(tracked, n[1].typ, n.info)
|
||||||
for i in 0 ..< safeLen(n):
|
for i in 0 ..< safeLen(n):
|
||||||
track(tracked, n.sons[i])
|
track(tracked, n.sons[i])
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
|
|
|
||||||
|
|
@ -886,6 +886,10 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||||
t.flags.incl tfHasOwned
|
t.flags.incl tfHasOwned
|
||||||
t.rawAddSonNoPropagationOfTypeFlags result
|
t.rawAddSonNoPropagationOfTypeFlags result
|
||||||
result = t
|
result = t
|
||||||
|
#if result.kind == tyRef and c.config.selectedGC == gcDestructors:
|
||||||
|
# result.flags.incl tfHasAsgn
|
||||||
|
# XXX Something like this is a good idea but it should be done
|
||||||
|
# in sempass2!
|
||||||
|
|
||||||
proc findEnforcedStaticType(t: PType): PType =
|
proc findEnforcedStaticType(t: PType): PType =
|
||||||
# This handles types such as `static[T] and Foo`,
|
# This handles types such as `static[T] and Foo`,
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,18 @@ proc GC_ref*[T](x: ref T) =
|
||||||
## New runtime only supports this operation for 'ref T'.
|
## New runtime only supports this operation for 'ref T'.
|
||||||
if x != nil: nimIncRef(cast[pointer](x))
|
if x != nil: nimIncRef(cast[pointer](x))
|
||||||
|
|
||||||
|
template GC_fullCollect* =
|
||||||
|
## Forces a full garbage collection pass. With ``--gc:arc`` a nop.
|
||||||
|
discard
|
||||||
|
|
||||||
|
template setupForeignThreadGc* =
|
||||||
|
## With ``--gc:arc`` a nop.
|
||||||
|
discard
|
||||||
|
|
||||||
|
template tearDownForeignThreadGc* =
|
||||||
|
## With ``--gc:arc`` a nop.
|
||||||
|
discard
|
||||||
|
|
||||||
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerRtl, inl.} =
|
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerRtl, inl.} =
|
||||||
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
proc strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,7 @@ const ThisIsSystem = true
|
||||||
proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
||||||
## Leaked implementation detail. Do not use.
|
## Leaked implementation detail. Do not use.
|
||||||
|
|
||||||
|
when not defined(gcDestructors):
|
||||||
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
|
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
|
||||||
magic: "NewFinalize", noSideEffect.}
|
magic: "NewFinalize", noSideEffect.}
|
||||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||||
|
|
|
||||||
|
|
@ -304,3 +304,12 @@ proc `$`*(x: uint64): string {.noSideEffect, raises: [].} =
|
||||||
let half = i div 2
|
let half = i div 2
|
||||||
# Reverse
|
# Reverse
|
||||||
for t in 0 .. half-1: swap(result[t], result[i-t-1])
|
for t in 0 .. half-1: swap(result[t], result[i-t-1])
|
||||||
|
|
||||||
|
when defined(gcDestructors):
|
||||||
|
proc GC_getStatistics*(): string =
|
||||||
|
result = "[GC] total memory: "
|
||||||
|
result.addInt getTotalMem()
|
||||||
|
result.add "\n[GC] occupied memory: "
|
||||||
|
result.addInt getOccupiedMem()
|
||||||
|
result.add '\n'
|
||||||
|
#"[GC] cycle collections: " & $gch.stat.cycleCollections & "\n" &
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ const
|
||||||
"coroutines",
|
"coroutines",
|
||||||
"osproc",
|
"osproc",
|
||||||
"shouldfail",
|
"shouldfail",
|
||||||
"dir with space"
|
"dir with space",
|
||||||
|
"destructor"
|
||||||
]
|
]
|
||||||
|
|
||||||
proc isTestFile*(file: string): bool =
|
proc isTestFile*(file: string): bool =
|
||||||
|
|
@ -176,6 +177,11 @@ proc gcTests(r: var TResults, cat: Category, options: string) =
|
||||||
" -d:release", cat)
|
" -d:release", cat)
|
||||||
testSpec r, makeTest("tests/gc" / filename, options &
|
testSpec r, makeTest("tests/gc" / filename, options &
|
||||||
" -d:release -d:useRealtimeGC", cat)
|
" -d:release -d:useRealtimeGC", cat)
|
||||||
|
when filename != "gctest":
|
||||||
|
testSpec r, makeTest("tests/gc" / filename, options &
|
||||||
|
" --gc:arc", cat)
|
||||||
|
testSpec r, makeTest("tests/gc" / filename, options &
|
||||||
|
" --gc:arc -d:release", cat)
|
||||||
|
|
||||||
template testWithoutBoehm(filename: untyped) =
|
template testWithoutBoehm(filename: untyped) =
|
||||||
testWithoutMs filename
|
testWithoutMs filename
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ proc test(): auto =
|
||||||
var (a, b, _) = test()
|
var (a, b, _) = test()
|
||||||
|
|
||||||
doAssert assign_counter == 0
|
doAssert assign_counter == 0
|
||||||
doAssert sink_counter == 12 # + 3 because of the conservative tuple unpacking transformation
|
doAssert sink_counter == 9 # XXX this is still silly and needs to be investigated
|
||||||
|
|
||||||
# bug #11510
|
# bug #11510
|
||||||
proc main =
|
proc main =
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ discard """
|
||||||
disabled: "32bit"
|
disabled: "32bit"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from strutils import join
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TFoo* = object
|
TFoo* = object
|
||||||
id: int
|
id: int
|
||||||
|
|
@ -12,10 +10,20 @@ type
|
||||||
var foo_counter = 0
|
var foo_counter = 0
|
||||||
var alive_foos = newseq[int](0)
|
var alive_foos = newseq[int](0)
|
||||||
|
|
||||||
|
when defined(gcDestructors):
|
||||||
|
proc `=destroy`(some: var TFoo) =
|
||||||
|
alive_foos.del alive_foos.find(some.id)
|
||||||
|
`=destroy`(some.fn)
|
||||||
|
|
||||||
|
else:
|
||||||
proc free*(some: ref TFoo) =
|
proc free*(some: ref TFoo) =
|
||||||
#echo "Tfoo #", some.id, " freed"
|
#echo "Tfoo #", some.id, " freed"
|
||||||
alive_foos.del alive_foos.find(some.id)
|
alive_foos.del alive_foos.find(some.id)
|
||||||
|
|
||||||
proc newFoo*(): ref TFoo =
|
proc newFoo*(): ref TFoo =
|
||||||
|
when defined(gcDestructors):
|
||||||
|
new result
|
||||||
|
else:
|
||||||
new result, free
|
new result, free
|
||||||
|
|
||||||
result.id = foo_counter
|
result.id = foo_counter
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ type
|
||||||
PModule = ref Module
|
PModule = ref Module
|
||||||
|
|
||||||
Node = object
|
Node = object
|
||||||
owner*: PModule
|
owner* {.cursor.}: PModule
|
||||||
data*: array[0..200, char] # some fat to drain memory faster
|
data*: array[0..200, char] # some fat to drain memory faster
|
||||||
id: int
|
id: int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ discard """
|
||||||
outputsub: "no leak: "
|
outputsub: "no leak: "
|
||||||
"""
|
"""
|
||||||
|
|
||||||
when defined(GC_setMaxPause):
|
when declared(GC_setMaxPause):
|
||||||
GC_setMaxPause 2_000
|
GC_setMaxPause 2_000
|
||||||
|
|
||||||
type
|
type
|
||||||
TExpr = object {.inheritable.} ## abstract base class for an expression
|
TExpr {.inheritable.} = object ## abstract base class for an expression
|
||||||
PLiteral = ref TLiteral
|
PLiteral = ref TLiteral
|
||||||
TLiteral = object of TExpr
|
TLiteral = object of TExpr
|
||||||
x: int
|
x: int
|
||||||
|
|
@ -15,7 +15,7 @@ type
|
||||||
a, b: ref TExpr
|
a, b: ref TExpr
|
||||||
op2: string
|
op2: string
|
||||||
|
|
||||||
method eval(e: ref TExpr): int =
|
method eval(e: ref TExpr): int {.base.} =
|
||||||
# override this base method
|
# override this base method
|
||||||
quit "to override!"
|
quit "to override!"
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ proc newLit(x: int): ref TLiteral =
|
||||||
result.x = x
|
result.x = x
|
||||||
result.op1 = $getOccupiedMem()
|
result.op1 = $getOccupiedMem()
|
||||||
|
|
||||||
proc newPlus(a, b: ref TExpr): ref TPlusExpr =
|
proc newPlus(a, b: sink(ref TExpr)): ref TPlusExpr =
|
||||||
new(result)
|
new(result)
|
||||||
result.a = a
|
result.a = a
|
||||||
result.b = b
|
result.b = b
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ type
|
||||||
proc makePair: PCyclic =
|
proc makePair: PCyclic =
|
||||||
new(result)
|
new(result)
|
||||||
new(result.sibling)
|
new(result.sibling)
|
||||||
|
when not defined(gcDestructors):
|
||||||
result.sibling.sibling = result
|
result.sibling.sibling = result
|
||||||
|
|
||||||
proc loop =
|
proc loop =
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,14 @@ var
|
||||||
proc finalizer(x: StrongObject) =
|
proc finalizer(x: StrongObject) =
|
||||||
valid.excl(x.id)
|
valid.excl(x.id)
|
||||||
|
|
||||||
|
when defined(gcDestructors):
|
||||||
|
proc `=destroy`(x: var TMyObject) =
|
||||||
|
valid.excl(x.id)
|
||||||
|
|
||||||
proc create: StrongObject =
|
proc create: StrongObject =
|
||||||
|
when defined(gcDestructors):
|
||||||
|
new(result)
|
||||||
|
else:
|
||||||
new(result, finalizer)
|
new(result, finalizer)
|
||||||
result.id = gid
|
result.id = gid
|
||||||
valid.incl(gid)
|
valid.incl(gid)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue