gc:destructors progress
This commit is contained in:
parent
ab48d7901e
commit
ad82e65387
7 changed files with 31 additions and 79 deletions
|
|
@ -2028,7 +2028,7 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
|
||||||
resetLoc(p, a)
|
resetLoc(p, a)
|
||||||
|
|
||||||
proc genDestroy(p: BProc; n: PNode) =
|
proc genDestroy(p: BProc; n: PNode) =
|
||||||
if optNimV2 in p.config.globalOptions:
|
if p.config.selectedGC == gcDestructors:
|
||||||
let arg = n[1].skipAddr
|
let arg = n[1].skipAddr
|
||||||
let t = arg.typ.skipTypes(abstractInst)
|
let t = arg.typ.skipTypes(abstractInst)
|
||||||
case t.kind
|
case t.kind
|
||||||
|
|
|
||||||
|
|
@ -437,30 +437,31 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
processOnOffSwitchG(conf, {optWholeProject}, arg, pass, info)
|
processOnOffSwitchG(conf, {optWholeProject}, arg, pass, info)
|
||||||
of "gc":
|
of "gc":
|
||||||
expectArg(conf, switch, arg, pass, info)
|
expectArg(conf, switch, arg, pass, info)
|
||||||
case arg.normalize
|
if pass in {passCmd2, passPP}:
|
||||||
of "boehm":
|
case arg.normalize
|
||||||
conf.selectedGC = gcBoehm
|
of "boehm":
|
||||||
defineSymbol(conf.symbols, "boehmgc")
|
conf.selectedGC = gcBoehm
|
||||||
of "refc":
|
defineSymbol(conf.symbols, "boehmgc")
|
||||||
conf.selectedGC = gcRefc
|
of "refc":
|
||||||
of "v2":
|
conf.selectedGC = gcRefc
|
||||||
message(conf, info, warnDeprecated, "--gc:v2 is deprecated; using default gc")
|
of "v2":
|
||||||
of "markandsweep":
|
message(conf, info, warnDeprecated, "--gc:v2 is deprecated; using default gc")
|
||||||
conf.selectedGC = gcMarkAndSweep
|
of "markandsweep":
|
||||||
defineSymbol(conf.symbols, "gcmarkandsweep")
|
conf.selectedGC = gcMarkAndSweep
|
||||||
of "destructors":
|
defineSymbol(conf.symbols, "gcmarkandsweep")
|
||||||
conf.selectedGC = gcDestructors
|
of "destructors":
|
||||||
defineSymbol(conf.symbols, "gcdestructors")
|
conf.selectedGC = gcDestructors
|
||||||
of "go":
|
defineSymbol(conf.symbols, "gcdestructors")
|
||||||
conf.selectedGC = gcGo
|
of "go":
|
||||||
defineSymbol(conf.symbols, "gogc")
|
conf.selectedGC = gcGo
|
||||||
of "none":
|
defineSymbol(conf.symbols, "gogc")
|
||||||
conf.selectedGC = gcNone
|
of "none":
|
||||||
defineSymbol(conf.symbols, "nogc")
|
conf.selectedGC = gcNone
|
||||||
of "stack", "regions":
|
defineSymbol(conf.symbols, "nogc")
|
||||||
conf.selectedGC= gcRegions
|
of "stack", "regions":
|
||||||
defineSymbol(conf.symbols, "gcregions")
|
conf.selectedGC= gcRegions
|
||||||
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
|
defineSymbol(conf.symbols, "gcregions")
|
||||||
|
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
|
||||||
of "warnings", "w":
|
of "warnings", "w":
|
||||||
if processOnOffSwitchOrList(conf, {optWarns}, arg, pass, info): listWarnings(conf)
|
if processOnOffSwitchOrList(conf, {optWarns}, arg, pass, info): listWarnings(conf)
|
||||||
of "warning": processSpecificNote(arg, wWarning, pass, info, switch, conf)
|
of "warning": processSpecificNote(arg, wWarning, pass, info, switch, conf)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ proc newDeepCopyCall(op: PSym; x, y: PNode): PNode =
|
||||||
result = newAsgnStmt(x, newOpCall(op, y))
|
result = newAsgnStmt(x, newOpCall(op, y))
|
||||||
|
|
||||||
proc useNoGc(c: TLiftCtx; t: PType): bool {.inline.} =
|
proc useNoGc(c: TLiftCtx; t: PType): bool {.inline.} =
|
||||||
result = optNimV2 in c.g.config.globalOptions and
|
result = c.g.config.selectedGC == gcDestructors and
|
||||||
({tfHasGCedMem, tfHasOwned} * t.flags != {} or t.isGCedMem)
|
({tfHasGCedMem, tfHasOwned} * t.flags != {} or t.isGCedMem)
|
||||||
|
|
||||||
proc instantiateGeneric(c: var TLiftCtx; op: PSym; t, typeInst: PType): PSym =
|
proc instantiateGeneric(c: var TLiftCtx; op: PSym; t, typeInst: PType): PSym =
|
||||||
|
|
@ -563,7 +563,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 optNimV2 in g.config.globalOptions:
|
if g.config.selectedGC == gcDestructors:
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1653,7 +1653,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
of mSet: result = semSet(c, n, prev)
|
of mSet: result = semSet(c, n, prev)
|
||||||
of mOrdinal: result = semOrdinal(c, n, prev)
|
of mOrdinal: result = semOrdinal(c, n, prev)
|
||||||
of mSeq:
|
of mSeq:
|
||||||
if c.config.selectedGC == gcDestructors and optNimV2 notin c.config.globalOptions:
|
if false: # c.config.selectedGC == gcDestructors and optNimV2 notin c.config.globalOptions:
|
||||||
let s = c.graph.sysTypes[tySequence]
|
let s = c.graph.sysTypes[tySequence]
|
||||||
assert s != nil
|
assert s != nil
|
||||||
assert prev == nil
|
assert prev == nil
|
||||||
|
|
|
||||||
|
|
@ -9,20 +9,6 @@
|
||||||
|
|
||||||
## Default new string implementation used by Nim's core.
|
## Default new string implementation used by Nim's core.
|
||||||
|
|
||||||
when false:
|
|
||||||
# these are to be implemented or changed in the code generator.
|
|
||||||
|
|
||||||
#proc rawNewStringNoInit(space: int): NimString {.compilerproc.}
|
|
||||||
# seems to be unused.
|
|
||||||
proc copyDeepString(src: NimString): NimString {.inline.}
|
|
||||||
# ----------------- sequences ----------------------------------------------
|
|
||||||
|
|
||||||
proc incrSeqV3(s: PGenericSeq, typ: PNimType): PGenericSeq {.compilerproc.}
|
|
||||||
proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
|
||||||
compilerRtl.}
|
|
||||||
proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.}
|
|
||||||
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.}
|
|
||||||
|
|
||||||
import allocators
|
import allocators
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -45,41 +31,6 @@ template frees(s) =
|
||||||
if not isLiteral(s):
|
if not isLiteral(s):
|
||||||
s.p.allocator.dealloc(s.p.allocator, s.p, contentSize(s.p.cap))
|
s.p.allocator.dealloc(s.p.allocator, s.p, contentSize(s.p.cap))
|
||||||
|
|
||||||
when not defined(nimV2):
|
|
||||||
proc `=destroy`(s: var string) =
|
|
||||||
var a = cast[ptr NimStringV2](addr s)
|
|
||||||
frees(a)
|
|
||||||
a.len = 0
|
|
||||||
a.p = nil
|
|
||||||
|
|
||||||
proc `=sink`(x: var string, y: string) =
|
|
||||||
var a = cast[ptr NimStringV2](addr x)
|
|
||||||
var b = cast[ptr NimStringV2](unsafeAddr y)
|
|
||||||
# we hope this is optimized away for not yet alive objects:
|
|
||||||
if unlikely(a.p == b.p): return
|
|
||||||
frees(a)
|
|
||||||
a.len = b.len
|
|
||||||
a.p = b.p
|
|
||||||
|
|
||||||
proc `=`(x: var string, y: string) =
|
|
||||||
var a = cast[ptr NimStringV2](addr x)
|
|
||||||
var b = cast[ptr NimStringV2](unsafeAddr y)
|
|
||||||
if unlikely(a.p == b.p): return
|
|
||||||
frees(a)
|
|
||||||
a.len = b.len
|
|
||||||
if isLiteral(b):
|
|
||||||
# we can shallow copy literals:
|
|
||||||
a.p = b.p
|
|
||||||
else:
|
|
||||||
let allocator = if a.p != nil and a.p.allocator != nil: a.p.allocator else: getLocalAllocator()
|
|
||||||
# we have to allocate the 'cap' here, consider
|
|
||||||
# 'let y = newStringOfCap(); var x = y'
|
|
||||||
# on the other hand... These get turned into moves now.
|
|
||||||
a.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(b.len)))
|
|
||||||
a.p.allocator = allocator
|
|
||||||
a.p.cap = b.len
|
|
||||||
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
|
|
||||||
|
|
||||||
proc resize(old: int): int {.inline.} =
|
proc resize(old: int): int {.inline.} =
|
||||||
if old <= 0: result = 4
|
if old <= 0: result = 4
|
||||||
elif old < 65536: result = old * 2
|
elif old < 65536: result = old * 2
|
||||||
|
|
|
||||||
|
|
@ -2093,7 +2093,7 @@ when not defined(JS) and not defined(nimscript) and hostOS != "standalone":
|
||||||
when not defined(JS) and not defined(nimscript) and hasAlloc and not defined(gcDestructors):
|
when not defined(JS) and not defined(nimscript) and hasAlloc and not defined(gcDestructors):
|
||||||
proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}
|
proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.}
|
||||||
|
|
||||||
when not defined(gcDestructors):
|
when not defined(gcDestructors) or defined(nimscript):
|
||||||
proc add*[T](x: var seq[T], y: T) {.magic: "AppendSeqElem", noSideEffect.}
|
proc add*[T](x: var seq[T], y: T) {.magic: "AppendSeqElem", noSideEffect.}
|
||||||
## Generic proc for adding a data item `y` to a container `x`.
|
## Generic proc for adding a data item `y` to a container `x`.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -511,7 +511,7 @@ when not defined(useNimRtl):
|
||||||
gch.tracing = true
|
gch.tracing = true
|
||||||
|
|
||||||
proc GC_fullCollect() =
|
proc GC_fullCollect() =
|
||||||
var oldThreshold = gch.cycleThreshold
|
let oldThreshold = gch.cycleThreshold
|
||||||
gch.cycleThreshold = 0 # forces cycle collection
|
gch.cycleThreshold = 0 # forces cycle collection
|
||||||
collectCT(gch, 0)
|
collectCT(gch, 0)
|
||||||
gch.cycleThreshold = oldThreshold
|
gch.cycleThreshold = oldThreshold
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue