gc:destructors progress

This commit is contained in:
Araq 2019-09-01 23:28:26 +02:00
commit ad82e65387
7 changed files with 31 additions and 79 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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`.
## ##

View file

@ -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