--gc:destructors now means Nim uses pure refcounting (#12557)

This commit is contained in:
Andreas Rumpf 2019-10-30 16:15:17 +01:00 • committed by GitHub
commit 1746da2d9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 123 additions and 35 deletions

View file

@ -1206,7 +1206,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
if sizeExpr.isNil: if sizeExpr.isNil:
sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)] sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)]
if optOwnedRefs in p.config.globalOptions: if optTinyRtti in p.config.globalOptions:
b.r = ropecg(p.module, "($1) #nimNewObj($2)", b.r = ropecg(p.module, "($1) #nimNewObj($2)",
[getTypeDesc(p.module, typ), sizeExpr]) [getTypeDesc(p.module, typ), sizeExpr])
genAssignment(p, a, b, {}) genAssignment(p, a, b, {})

View file

@ -16,7 +16,7 @@ const
# above X strings a hash-switch for strings is generated # above X strings a hash-switch for strings is generated
proc getTraverseProc(p: BProc, v: PSym): Rope = proc getTraverseProc(p: BProc, v: PSym): Rope =
if p.config.selectedGC in {gcMarkAndSweep, gcDestructors, gcV2, gcRefc} and if p.config.selectedGC in {gcMarkAndSweep, gcHooks, gcV2, gcRefc} and
optOwnedRefs notin p.config.globalOptions and optOwnedRefs notin p.config.globalOptions and
containsGarbageCollectedRef(v.loc.t): containsGarbageCollectedRef(v.loc.t):
# we register a specialized marked proc here; this has the advantage # we register a specialized marked proc here; this has the advantage

View file

@ -230,6 +230,7 @@ proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo
of "markandsweep": result = conf.selectedGC == gcMarkAndSweep of "markandsweep": result = conf.selectedGC == gcMarkAndSweep
of "generational": result = false of "generational": result = false
of "destructors": result = conf.selectedGC == gcDestructors of "destructors": result = conf.selectedGC == gcDestructors
of "hooks": result = conf.selectedGC == gcHooks
of "go": result = conf.selectedGC == gcGo of "go": result = conf.selectedGC == gcGo
of "none": result = conf.selectedGC == gcNone of "none": result = conf.selectedGC == gcNone
of "stack", "regions": result = conf.selectedGC == gcRegions of "stack", "regions": result = conf.selectedGC == gcRegions
@ -453,6 +454,17 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf.selectedGC = gcDestructors conf.selectedGC = gcDestructors
defineSymbol(conf.symbols, "gcdestructors") defineSymbol(conf.symbols, "gcdestructors")
incl conf.globalOptions, optSeqDestructors incl conf.globalOptions, optSeqDestructors
incl conf.globalOptions, optTinyRtti
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimV2")
of "hooks":
conf.selectedGC = gcHooks
defineSymbol(conf.symbols, "gchooks")
incl conf.globalOptions, optSeqDestructors
processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info)
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
of "go": of "go":
conf.selectedGC = gcGo conf.selectedGC = gcGo
defineSymbol(conf.symbols, "gogc") defineSymbol(conf.symbols, "gogc")
@ -460,7 +472,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf.selectedGC = gcNone conf.selectedGC = gcNone
defineSymbol(conf.symbols, "nogc") defineSymbol(conf.symbols, "nogc")
of "stack", "regions": of "stack", "regions":
conf.selectedGC= gcRegions conf.selectedGC = gcRegions
defineSymbol(conf.symbols, "gcregions") defineSymbol(conf.symbols, "gcregions")
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg) else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
of "warnings", "w": of "warnings", "w":
@ -509,7 +521,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
undefSymbol(conf.symbols, "useNimRtl") undefSymbol(conf.symbols, "useNimRtl")
of "oldnewlines": of "oldnewlines":
case arg.normalize case arg.normalize
of "","on": of "", "on":
conf.oldNewlines = true conf.oldNewlines = true
defineSymbol(conf.symbols, "nimOldNewlines") defineSymbol(conf.symbols, "nimOldNewlines")
of "off": of "off":
@ -763,9 +775,10 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
incl(conf.globalOptions, optOwnedRefs) incl(conf.globalOptions, optOwnedRefs)
incl(conf.globalOptions, optSeqDestructors) incl(conf.globalOptions, optSeqDestructors)
defineSymbol(conf.symbols, "nimV2") defineSymbol(conf.symbols, "nimV2")
conf.selectedGC = gcDestructors conf.selectedGC = gcHooks
defineSymbol(conf.symbols, "gcdestructors") defineSymbol(conf.symbols, "gchooks")
defineSymbol(conf.symbols, "nimSeqsV2") defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimOwnedEnabled")
of "seqsv2": of "seqsv2":
processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info) processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info)
if pass in {passCmd2, passPP}: if pass in {passCmd2, passPP}:

View file

@ -344,7 +344,8 @@ proc createUpField(c: var DetectionPass; dest, dep: PSym; info: TLineInfo) =
# with cycles properly, so it's better to produce a weak ref (=ptr) here. # with cycles properly, so it's better to produce a weak ref (=ptr) here.
# This seems to be generally correct but since it's a bit risky it's disabled # This seems to be generally correct but since it's a bit risky it's disabled
# for now. # for now.
let fieldType = if isDefined(c.graph.config, "nimCycleBreaker"): let fieldType = if isDefined(c.graph.config, "nimCycleBreaker") or
c.graph.config.selectedGC == gcDestructors:
c.getEnvTypeForOwnerUp(dep, info) #getHiddenParam(dep).typ c.getEnvTypeForOwnerUp(dep, info) #getHiddenParam(dep).typ
else: else:
c.getEnvTypeForOwner(dep, info) c.getEnvTypeForOwner(dep, info)

View file

@ -359,6 +359,58 @@ proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
of attachedDestructor: of attachedDestructor:
body.add genBuiltin(c.g, mDestroy, "destroy", x) body.add genBuiltin(c.g, mDestroy, "destroy", x)
proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
var actions = newNodeI(nkStmtList, c.info)
let elemType = t.lastSon
if isFinal(elemType):
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x)
else:
addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(x, nkDerefExpr))
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, x)
let cond = callCodegenProc(c.g, "nimDecRefIsLast", c.info, x)
cond.typ = getSysType(c.g, x.info, tyBool)
case c.kind
of attachedSink:
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedAsgn:
body.add genIf(c, y, callCodegenProc(c.g, "nimIncRef", c.info, y))
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
body.add genIf(c, cond, actions)
of attachedDeepCopy: assert(false, "cannot happen")
proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
## Closures are really like refs except they always use a virtual destructor
## and we need to do the refcounting only on the ref field which we call 'xenv':
let xenv = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
xenv.typ = getSysType(c.g, c.info, tyPointer)
var actions = newNodeI(nkStmtList, c.info)
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, xenv)
let cond = callCodegenProc(c.g, "nimDecRefIsLast", c.info, xenv)
cond.typ = getSysType(c.g, x.info, tyBool)
case c.kind
of attachedSink:
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedAsgn:
let yenv = genBuiltin(c.g, mAccessEnv, "accessEnv", y)
yenv.typ = getSysType(c.g, c.info, tyPointer)
body.add genIf(c, yenv, callCodegenProc(c.g, "nimIncRef", c.info, yenv))
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
body.add genIf(c, cond, actions)
of attachedDeepCopy: assert(false, "cannot happen")
proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
case c.kind case c.kind
of attachedSink: of attachedSink:
@ -367,7 +419,7 @@ proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
body.add genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x)) body.add genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x))
body.add newAsgnStmt(x, y) body.add newAsgnStmt(x, y)
of attachedAsgn: of attachedAsgn:
body.add genIf(c, y, callCodegenProc(c.g, "nimIncWeakRef", c.info, y)) body.add genIf(c, y, callCodegenProc(c.g, "nimIncRef", c.info, y))
body.add genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x)) body.add genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x))
body.add newAsgnStmt(x, y) body.add newAsgnStmt(x, y)
of attachedDestructor: of attachedDestructor:
@ -411,8 +463,8 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
call.sons[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy)) call.sons[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy))
call.sons[1] = y call.sons[1] = y
body.add newAsgnStmt(x, call) body.add newAsgnStmt(x, call)
elif optOwnedRefs in c.g.config.globalOptions and elif (optOwnedRefs in c.g.config.globalOptions and
optRefCheck in c.g.config.options: optRefCheck in c.g.config.options) or c.g.config.selectedGC == gcDestructors:
let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x) let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
xx.typ = getSysType(c.g, c.info, tyPointer) xx.typ = getSysType(c.g, c.info, tyPointer)
case c.kind case c.kind
@ -424,7 +476,7 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
of attachedAsgn: of attachedAsgn:
let yy = genBuiltin(c.g, mAccessEnv, "accessEnv", y) let yy = genBuiltin(c.g, mAccessEnv, "accessEnv", y)
yy.typ = getSysType(c.g, c.info, tyPointer) yy.typ = getSysType(c.g, c.info, tyPointer)
body.add genIf(c, yy, callCodegenProc(c.g, "nimIncWeakRef", c.info, yy)) body.add genIf(c, yy, callCodegenProc(c.g, "nimIncRef", c.info, yy))
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx)) body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
body.add newAsgnStmt(x, y) body.add newAsgnStmt(x, y)
of attachedDestructor: of attachedDestructor:
@ -439,7 +491,6 @@ proc ownedClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x) let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
xx.typ = getSysType(c.g, c.info, tyPointer) xx.typ = getSysType(c.g, c.info, tyPointer)
var actions = newNodeI(nkStmtList, c.info) var actions = newNodeI(nkStmtList, c.info)
let elemType = t.lastSon
#discard addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(xx)) #discard addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(xx))
actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, xx) actions.add callCodegenProc(c.g, "nimDestroyAndDispose", c.info, xx)
case c.kind case c.kind
@ -457,14 +508,19 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
tyPtr, tyOpt, tyUncheckedArray: tyPtr, tyOpt, tyUncheckedArray:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tyRef: of tyRef:
if optOwnedRefs in c.g.config.globalOptions and if c.g.config.selectedGC == gcDestructors:
optRefCheck in c.g.config.options: atomicRefOp(c, t, body, x, y)
elif (optOwnedRefs in c.g.config.globalOptions and
optRefCheck in c.g.config.options):
weakrefOp(c, t, body, x, y) weakrefOp(c, t, body, x, y)
else: else:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tyProc: of tyProc:
if t.callConv == ccClosure: if t.callConv == ccClosure:
closureOp(c, t, body, x, y) if c.g.config.selectedGC == gcDestructors:
atomicClosureOp(c, t, body, x, y)
else:
closureOp(c, t, body, x, y)
else: else:
defaultOp(c, t, body, x, y) defaultOp(c, t, body, x, y)
of tyOwned: of tyOwned:
@ -532,7 +588,8 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
tyGenericInst, tyStatic, tyAlias, tySink: tyGenericInst, tyStatic, tyAlias, tySink:
fillBody(c, lastSon(t), body, x, y) fillBody(c, lastSon(t), body, x, y)
proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; info: TLineInfo): PSym = proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType;
kind: TTypeAttachedOp; info: TLineInfo): PSym =
assert typ.kind == tyDistinct assert typ.kind == tyDistinct
let baseType = typ[0] let baseType = typ[0]
if baseType.attachedOps[kind] == nil: if baseType.attachedOps[kind] == nil:
@ -571,7 +628,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
typ.attachedOps[kind] = result typ.attachedOps[kind] = result
var tk: TTypeKind var tk: TTypeKind
if g.config.selectedGC == gcDestructors: if g.config.selectedGC in {gcDestructors, gcHooks}:
tk = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}).kind tk = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}).kind
else: else:
tk = tyNone # no special casing for strings and seqs tk = tyNone # no special casing for strings and seqs

View file

@ -116,6 +116,7 @@ type
TStringSeq* = seq[string] TStringSeq* = seq[string]
TGCMode* = enum # the selected GC TGCMode* = enum # the selected GC
gcUnselected, gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors, gcUnselected, gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors,
gcHooks,
gcRefc, gcV2, gcGo gcRefc, gcV2, gcGo
# gcRefc and the GCs that follow it use a write barrier, # gcRefc and the GCs that follow it use a write barrier,
# as far as usesWriteBarrier() is concerned # as far as usesWriteBarrier() is concerned

View file

@ -57,13 +57,13 @@ proc nimNewObj(size: int): pointer {.compilerRtl.} =
else: else:
inc allocs inc allocs
proc nimDecWeakRef(p: pointer) {.compilerRtl.} = proc nimDecWeakRef(p: pointer) {.compilerRtl, inl.} =
when hasThreadSupport: when hasThreadSupport:
atomicDec head(p).rc atomicDec head(p).rc
else: else:
dec head(p).rc dec head(p).rc
proc nimIncWeakRef(p: pointer) {.compilerRtl.} = proc nimIncRef(p: pointer) {.compilerRtl, inl.} =
when hasThreadSupport: when hasThreadSupport:
atomicInc head(p).rc atomicInc head(p).rc
else: else:
@ -106,11 +106,25 @@ proc nimDestroyAndDispose(p: pointer) {.compilerRtl.} =
cstderr.rawWrite "has destructor!\n" cstderr.rawWrite "has destructor!\n"
nimRawDispose(p) nimRawDispose(p)
proc isObj(obj: PNimType, subclass: cstring): bool {.compilerproc.} = proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} =
if p != nil:
when hasThreadSupport:
if atomicLoadN(addr head(p).rc, ATOMIC_RELAXED) == 0:
result = true
else:
if atomicDec(head(p).rc) <= 0:
result = true
else:
if head(p).rc == 0:
result = true
else:
dec head(p).rc
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.}
result = strstr(obj.name, subclass) != nil result = strstr(obj.name, subclass) != nil
proc chckObj(obj: PNimType, subclass: cstring) {.compilerproc.} = proc chckObj(obj: PNimType, subclass: cstring) {.compilerRtl.} =
# checks if obj is of type subclass: # checks if obj is of type subclass:
if not isObj(obj, subclass): sysFatal(ObjectConversionError, "invalid object conversion") if not isObj(obj, subclass): sysFatal(ObjectConversionError, "invalid object conversion")

View file

@ -1722,12 +1722,12 @@ template `isnot`*(x, y: untyped): untyped = not (x is y)
## assert 42 isnot float ## assert 42 isnot float
## assert @[1, 2] isnot enum ## assert @[1, 2] isnot enum
when (defined(nimV2) and not defined(nimscript)) or defined(nimFixedOwned): when (defined(nimOwnedEnabled) and not defined(nimscript)) or defined(nimFixedOwned):
type owned*[T]{.magic: "BuiltinType".} ## type constructor to mark a ref/ptr or a closure as `owned`. type owned*[T]{.magic: "BuiltinType".} ## type constructor to mark a ref/ptr or a closure as `owned`.
else: else:
template owned*(t: typedesc): typedesc = t template owned*(t: typedesc): typedesc = t
when defined(nimV2) and not defined(nimscript): when defined(nimOwnedEnabled) and not defined(nimscript):
proc new*[T](a: var owned(ref T)) {.magic: "New", noSideEffect.} proc new*[T](a: var owned(ref T)) {.magic: "New", 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)
## reference to it in ``a``. ## reference to it in ``a``.
@ -3237,6 +3237,8 @@ proc `<`*[T: tuple](x, y: T): bool =
# ----------------- GC interface --------------------------------------------- # ----------------- GC interface ---------------------------------------------
const
usesDestructors = defined(gcDestructors) or defined(gcHooks)
when not defined(nimscript) and hasAlloc: when not defined(nimscript) and hasAlloc:
type type
@ -3246,7 +3248,7 @@ when not defined(nimscript) and hasAlloc:
gcOptimizeTime, ## optimize for speed gcOptimizeTime, ## optimize for speed
gcOptimizeSpace ## optimize for memory footprint gcOptimizeSpace ## optimize for memory footprint
when not defined(JS) and not defined(gcDestructors): when not defined(JS) and not usesDestructors:
proc GC_disable*() {.rtl, inl, benign.} proc GC_disable*() {.rtl, inl, benign.}
## Disables the GC. If called `n` times, `n` calls to `GC_enable` ## Disables the GC. If called `n` times, `n` calls to `GC_enable`
## are needed to reactivate the GC. ## are needed to reactivate the GC.
@ -3602,7 +3604,7 @@ when not defined(JS): #and not defined(nimscript):
{.push stack_trace: off, profiler:off.} {.push stack_trace: off, profiler:off.}
when hasAlloc: when hasAlloc:
when not defined(gcRegions) and not defined(gcDestructors): when not defined(gcRegions) and not usesDestructors:
proc initGC() {.gcsafe.} proc initGC() {.gcsafe.}
proc initStackBottom() {.inline, compilerproc.} = proc initStackBottom() {.inline, compilerproc.} =
@ -3620,7 +3622,7 @@ when not defined(JS): #and not defined(nimscript):
when declared(nimGC_setStackBottom): when declared(nimGC_setStackBottom):
nimGC_setStackBottom(locals) nimGC_setStackBottom(locals)
when not defined(gcDestructors): when not usesDestructors:
{.push profiler: off.} {.push profiler: off.}
var var
strDesc = TNimType(size: sizeof(string), kind: tyString, flags: {ntfAcyclic}) strDesc = TNimType(size: sizeof(string), kind: tyString, flags: {ntfAcyclic})
@ -3792,10 +3794,10 @@ when not defined(JS): #and not defined(nimscript):
when hasAlloc: include "system/strmantle" when hasAlloc: include "system/strmantle"
when hasThreadSupport: when hasThreadSupport:
when hostOS != "standalone" and not defined(gcDestructors): include "system/channels" when hostOS != "standalone" and not usesDestructors: include "system/channels"
when not defined(nimscript) and hasAlloc: when not defined(nimscript) and hasAlloc:
when not defined(gcDestructors): when not usesDestructors:
include "system/assign" include "system/assign"
when not defined(nimV2): when not defined(nimV2):
include "system/repr" include "system/repr"
@ -4396,7 +4398,7 @@ proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} =
discard discard
when hasAlloc and not defined(nimscript) and not defined(JS) and when hasAlloc and not defined(nimscript) and not defined(JS) and
not defined(gcDestructors): not usesDestructors:
# XXX how to implement 'deepCopy' is an open problem. # XXX how to implement 'deepCopy' is an open problem.
proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: "DeepCopy".} = proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: "DeepCopy".} =
## Performs a deep copy of `y` and copies it into `x`. ## Performs a deep copy of `y` and copies it into `x`.

View file

@ -87,7 +87,7 @@ type
ntfEnumHole = 2 # enum has holes and thus `$` for them needs the slow ntfEnumHole = 2 # enum has holes and thus `$` for them needs the slow
# version # version
TNimType {.compilerproc.} = object TNimType {.compilerproc.} = object
when defined(gcDestructors): when defined(gcHooks):
head*: pointer head*: pointer
size*: int size*: int
kind: TNimKind kind: TNimKind
@ -103,7 +103,7 @@ type
instances: int # count the number of instances instances: int # count the number of instances
sizes: int # sizes of all instances in bytes sizes: int # sizes of all instances in bytes
when defined(gcDestructors): when defined(gcHooks):
type type
PNimType* = ptr TNimType PNimType* = ptr TNimType
else: else:

View file

@ -507,10 +507,10 @@ else:
elif defined(gcRegions): elif defined(gcRegions):
# XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here # XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here
include "system/gc_regions" include "system/gc_regions"
elif defined(nimV2) or defined(gcDestructors): elif defined(nimV2) or usesDestructors:
var allocator {.rtlThreadVar.}: MemRegion var allocator {.rtlThreadVar.}: MemRegion
instantiateForRegion(allocator) instantiateForRegion(allocator)
when defined(gcDestructors): when defined(gcHooks):
include "system/gc_hooks" include "system/gc_hooks"
elif defined(gcMarkAndSweep): elif defined(gcMarkAndSweep):
# XXX use 'compileOption' here # XXX use 'compileOption' here

View file

@ -226,7 +226,7 @@ when not defined(useNimRtl):
cl: var ReprClosure) = cl: var ReprClosure) =
# we know that p is not nil here: # we know that p is not nil here:
when declared(CellSet): when declared(CellSet):
when defined(boehmGC) or defined(gogc) or defined(nogc) or defined(gcDestructors): when defined(boehmGC) or defined(gogc) or defined(nogc) or usesDestructors:
var cell = cast[PCell](p) var cell = cast[PCell](p)
else: else:
var cell = usrToCell(p) var cell = usrToCell(p)

View file

@ -148,7 +148,7 @@ else:
proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) = proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) =
when defined(boehmgc): when defined(boehmgc):
boehmGC_call_with_stack_base(threadProcWrapDispatch[TArg], thrd) boehmGC_call_with_stack_base(threadProcWrapDispatch[TArg], thrd)
elif not defined(nogc) and not defined(gogc) and not defined(gcRegions) and not defined(gcDestructors): elif not defined(nogc) and not defined(gogc) and not defined(gcRegions) and not usesDestructors:
var p {.volatile.}: proc(a: ptr Thread[TArg]) {.nimcall, gcsafe.} = var p {.volatile.}: proc(a: ptr Thread[TArg]) {.nimcall, gcsafe.} =
threadProcWrapDispatch[TArg] threadProcWrapDispatch[TArg]
# init the GC for refc/markandsweep # init the GC for refc/markandsweep