mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 19:52:36 +00:00
ARC: ported the GC tests over to --gc:arc
This commit is contained in:
@@ -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)
|
||||
temp.typ = skipTypes(value.typ, abstractInst)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
incl(temp.flags, sfCursor)
|
||||
|
||||
var v = newNodeI(nkVarSection, value.info)
|
||||
let tempAsNode = newSymNode(temp)
|
||||
|
||||
@@ -759,6 +759,7 @@ proc track(tracked: PEffects, n: PNode) =
|
||||
# check required for 'nim check':
|
||||
if n[1].typ.len > 0:
|
||||
createTypeBoundOps(tracked, n[1].typ.lastSon, n.info)
|
||||
createTypeBoundOps(tracked, n[1].typ, n.info)
|
||||
for i in 0 ..< safeLen(n):
|
||||
track(tracked, n.sons[i])
|
||||
of nkDotExpr:
|
||||
|
||||
@@ -886,6 +886,10 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||
t.flags.incl tfHasOwned
|
||||
t.rawAddSonNoPropagationOfTypeFlags result
|
||||
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 =
|
||||
# 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'.
|
||||
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 strstr(s, sub: cstring): cstring {.header: "<string.h>", importc.}
|
||||
|
||||
|
||||
@@ -250,18 +250,19 @@ const ThisIsSystem = true
|
||||
proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
||||
## Leaked implementation detail. Do not use.
|
||||
|
||||
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
|
||||
magic: "NewFinalize", noSideEffect.}
|
||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||
## reference to it in ``a``.
|
||||
##
|
||||
## When the garbage collector frees the object, `finalizer` is called.
|
||||
## The `finalizer` may not keep a reference to the
|
||||
## object pointed to by `x`. The `finalizer` cannot prevent the GC from
|
||||
## freeing the object.
|
||||
##
|
||||
## **Note**: The `finalizer` refers to the type `T`, not to the object!
|
||||
## This means that for each object of type `T` the finalizer will be called!
|
||||
when not defined(gcDestructors):
|
||||
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
|
||||
magic: "NewFinalize", noSideEffect.}
|
||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||
## reference to it in ``a``.
|
||||
##
|
||||
## When the garbage collector frees the object, `finalizer` is called.
|
||||
## The `finalizer` may not keep a reference to the
|
||||
## object pointed to by `x`. The `finalizer` cannot prevent the GC from
|
||||
## freeing the object.
|
||||
##
|
||||
## **Note**: The `finalizer` refers to the type `T`, not to the object!
|
||||
## This means that for each object of type `T` the finalizer will be called!
|
||||
|
||||
when defined(nimV2):
|
||||
proc reset*[T](obj: var T) {.magic: "Destroy", noSideEffect.}
|
||||
|
||||
@@ -304,3 +304,12 @@ proc `$`*(x: uint64): string {.noSideEffect, raises: [].} =
|
||||
let half = i div 2
|
||||
# Reverse
|
||||
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",
|
||||
"osproc",
|
||||
"shouldfail",
|
||||
"dir with space"
|
||||
"dir with space",
|
||||
"destructor"
|
||||
]
|
||||
|
||||
proc isTestFile*(file: string): bool =
|
||||
@@ -176,6 +177,11 @@ proc gcTests(r: var TResults, cat: Category, options: string) =
|
||||
" -d:release", cat)
|
||||
testSpec r, makeTest("tests/gc" / filename, options &
|
||||
" -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) =
|
||||
testWithoutMs filename
|
||||
|
||||
@@ -28,7 +28,7 @@ proc test(): auto =
|
||||
var (a, b, _) = test()
|
||||
|
||||
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
|
||||
proc main =
|
||||
|
||||
@@ -3,20 +3,28 @@ discard """
|
||||
disabled: "32bit"
|
||||
"""
|
||||
|
||||
from strutils import join
|
||||
|
||||
type
|
||||
TFoo * = object
|
||||
TFoo* = object
|
||||
id: int
|
||||
fn: proc(){.closure.}
|
||||
var foo_counter = 0
|
||||
var alive_foos = newseq[int](0)
|
||||
|
||||
proc free*(some: ref TFoo) =
|
||||
#echo "Tfoo #", some.id, " freed"
|
||||
alive_foos.del alive_foos.find(some.id)
|
||||
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) =
|
||||
#echo "Tfoo #", some.id, " freed"
|
||||
alive_foos.del alive_foos.find(some.id)
|
||||
|
||||
proc newFoo*(): ref TFoo =
|
||||
new result, free
|
||||
when defined(gcDestructors):
|
||||
new result
|
||||
else:
|
||||
new result, free
|
||||
|
||||
result.id = foo_counter
|
||||
alive_foos.add result.id
|
||||
|
||||
@@ -10,7 +10,7 @@ type
|
||||
PModule = ref Module
|
||||
|
||||
Node = object
|
||||
owner*: PModule
|
||||
owner* {.cursor.}: PModule
|
||||
data*: array[0..200, char] # some fat to drain memory faster
|
||||
id: int
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ when defined(allow_print):
|
||||
else:
|
||||
const print = false
|
||||
|
||||
proc myResult3*(i:int):X {.exportc.} =
|
||||
proc myResult3*(i:int): X {.exportc.} =
|
||||
if print: echo "3"
|
||||
new(result)
|
||||
if print: echo "3-2"
|
||||
|
||||
@@ -2,11 +2,11 @@ discard """
|
||||
outputsub: "no leak: "
|
||||
"""
|
||||
|
||||
when defined(GC_setMaxPause):
|
||||
when declared(GC_setMaxPause):
|
||||
GC_setMaxPause 2_000
|
||||
|
||||
type
|
||||
TExpr = object {.inheritable.} ## abstract base class for an expression
|
||||
TExpr {.inheritable.} = object ## abstract base class for an expression
|
||||
PLiteral = ref TLiteral
|
||||
TLiteral = object of TExpr
|
||||
x: int
|
||||
@@ -15,7 +15,7 @@ type
|
||||
a, b: ref TExpr
|
||||
op2: string
|
||||
|
||||
method eval(e: ref TExpr): int =
|
||||
method eval(e: ref TExpr): int {.base.} =
|
||||
# override this base method
|
||||
quit "to override!"
|
||||
|
||||
@@ -30,7 +30,7 @@ proc newLit(x: int): ref TLiteral =
|
||||
result.x = x
|
||||
result.op1 = $getOccupiedMem()
|
||||
|
||||
proc newPlus(a, b: ref TExpr): ref TPlusExpr =
|
||||
proc newPlus(a, b: sink(ref TExpr)): ref TPlusExpr =
|
||||
new(result)
|
||||
result.a = a
|
||||
result.b = b
|
||||
|
||||
@@ -12,7 +12,8 @@ type
|
||||
proc makePair: PCyclic =
|
||||
new(result)
|
||||
new(result.sibling)
|
||||
result.sibling.sibling = result
|
||||
when not defined(gcDestructors):
|
||||
result.sibling.sibling = result
|
||||
|
||||
proc loop =
|
||||
for i in 0..10000:
|
||||
|
||||
@@ -19,8 +19,15 @@ var
|
||||
proc finalizer(x: StrongObject) =
|
||||
valid.excl(x.id)
|
||||
|
||||
when defined(gcDestructors):
|
||||
proc `=destroy`(x: var TMyObject) =
|
||||
valid.excl(x.id)
|
||||
|
||||
proc create: StrongObject =
|
||||
new(result, finalizer)
|
||||
when defined(gcDestructors):
|
||||
new(result)
|
||||
else:
|
||||
new(result, finalizer)
|
||||
result.id = gid
|
||||
valid.incl(gid)
|
||||
inc gid
|
||||
|
||||
Reference in New Issue
Block a user