mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-26 01:04:00 +00:00
adds an experimental mm:atomicArc switch (#21798)
This commit is contained in:
@@ -68,7 +68,7 @@ proc copyHalf[Key, Val](h, result: Node[Key, Val]) =
|
||||
result.links[j] = h.links[Mhalf + j]
|
||||
else:
|
||||
for j in 0..<Mhalf:
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
result.vals[j] = move h.vals[Mhalf + j]
|
||||
else:
|
||||
shallowCopy(result.vals[j], h.vals[Mhalf + j])
|
||||
@@ -91,7 +91,7 @@ proc insert[Key, Val](h: Node[Key, Val], key: Key, val: Val): Node[Key, Val] =
|
||||
if less(key, h.keys[j]): break
|
||||
inc j
|
||||
for i in countdown(h.entries, j+1):
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
h.vals[i] = move h.vals[i-1]
|
||||
else:
|
||||
shallowCopy(h.vals[i], h.vals[i-1])
|
||||
|
||||
@@ -269,7 +269,7 @@ proc withTmpIfNeeded(p: BProc, a: TLoc, needsTmp: bool): TLoc =
|
||||
# Bug https://github.com/status-im/nimbus-eth2/issues/1549
|
||||
# Aliasing is preferred over stack overflows.
|
||||
# Also don't regress for non ARC-builds, too risky.
|
||||
if needsTmp and a.lode.typ != nil and p.config.selectedGC in {gcArc, gcOrc} and
|
||||
if needsTmp and a.lode.typ != nil and p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc} and
|
||||
getSize(p.config, a.lode.typ) < 1024:
|
||||
getTemp(p, a.lode.typ, result, needsInit=false)
|
||||
genAssignment(p, result, a, {})
|
||||
|
||||
@@ -382,7 +382,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||
of tyArray:
|
||||
if containsGarbageCollectedRef(dest.t) and p.config.selectedGC notin {gcArc, gcOrc, gcHooks}:
|
||||
if containsGarbageCollectedRef(dest.t) and p.config.selectedGC notin {gcArc, gcAtomicArc, gcOrc, gcHooks}:
|
||||
genGenericAsgn(p, dest, src, flags)
|
||||
else:
|
||||
linefmt(p, cpsStmts,
|
||||
@@ -2403,7 +2403,7 @@ proc genSlice(p: BProc; e: PNode; d: var TLoc) =
|
||||
let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.lastSon,
|
||||
prepareForMutation = e[1].kind == nkHiddenDeref and
|
||||
e[1].typ.skipTypes(abstractInst).kind == tyString and
|
||||
p.config.selectedGC in {gcArc, gcOrc})
|
||||
p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc})
|
||||
if d.k == locNone: getTemp(p, e.typ, d)
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n", [rdLoc(d), x, y])
|
||||
when false:
|
||||
@@ -2585,7 +2585,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
let n = semparallel.liftParallel(p.module.g.graph, p.module.idgen, p.module.module, e)
|
||||
expr(p, n, d)
|
||||
of mDeepCopy:
|
||||
if p.config.selectedGC in {gcArc, gcOrc} and optEnableDeepCopy notin p.config.globalOptions:
|
||||
if p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc} and optEnableDeepCopy notin p.config.globalOptions:
|
||||
localError(p.config, e.info,
|
||||
"for --gc:arc|orc 'deepcopy' support has to be enabled with --deepcopy:on")
|
||||
|
||||
|
||||
@@ -1581,11 +1581,11 @@ proc genMainProc(m: BModule) =
|
||||
m.includeHeader("<libc/component.h>")
|
||||
|
||||
let initStackBottomCall =
|
||||
if m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcOrc}: "".rope
|
||||
if m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcAtomicArc, gcOrc}: "".rope
|
||||
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", [])
|
||||
inc(m.labels)
|
||||
|
||||
let isVolatile = if m.config.selectedGC notin {gcNone, gcArc, gcOrc}: "1" else: "0"
|
||||
let isVolatile = if m.config.selectedGC notin {gcNone, gcArc, gcAtomicArc, gcOrc}: "1" else: "0"
|
||||
appcg(m, m.s[cfsProcs], PreMainBody, [m.g.mainDatInit, m.g.otherModsInit, m.config.nimMainPrefix, posixCmdLine, isVolatile])
|
||||
|
||||
if m.config.target.targetOS == osWindows and
|
||||
@@ -1725,7 +1725,7 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
|
||||
if sfSystemModule in m.module.flags:
|
||||
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
|
||||
g.mainDatInit.add(ropecg(m, "\t#initThreadVarsEmulation();$N", []))
|
||||
if m.config.target.targetOS != osStandalone and m.config.selectedGC notin {gcNone, gcArc, gcOrc}:
|
||||
if m.config.target.targetOS != osStandalone and m.config.selectedGC notin {gcNone, gcArc, gcAtomicArc, gcOrc}:
|
||||
g.mainDatInit.add(ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []))
|
||||
|
||||
if m.s[cfsInitProc].len > 0:
|
||||
@@ -2177,7 +2177,7 @@ proc finalCodegenActions*(graph: ModuleGraph; m: BModule; n: PNode): PNode =
|
||||
cgsym(m, "rawWrite")
|
||||
|
||||
# raise dependencies on behalf of genMainProc
|
||||
if m.config.target.targetOS != osStandalone and m.config.selectedGC notin {gcNone, gcArc, gcOrc}:
|
||||
if m.config.target.targetOS != osStandalone and m.config.selectedGC notin {gcNone, gcArc, gcAtomicArc, gcOrc}:
|
||||
cgsym(m, "initStackBottomWith")
|
||||
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
|
||||
cgsym(m, "initThreadVarsEmulation")
|
||||
|
||||
@@ -238,7 +238,7 @@ proc processCompile(conf: ConfigRef; filename: string) =
|
||||
extccomp.addExternalFileToCompile(conf, found)
|
||||
|
||||
const
|
||||
errNoneBoehmRefcExpectedButXFound = "'arc', 'orc', 'markAndSweep', 'boehm', 'go', 'none', 'regions', or 'refc' expected, but '$1' found"
|
||||
errNoneBoehmRefcExpectedButXFound = "'arc', 'orc', 'atomicArc', 'markAndSweep', 'boehm', 'go', 'none', 'regions', or 'refc' expected, but '$1' found"
|
||||
errNoneSpeedOrSizeExpectedButXFound = "'none', 'speed' or 'size' expected, but '$1' found"
|
||||
errGuiConsoleOrLibExpectedButXFound = "'gui', 'console' or 'lib' expected, but '$1' found"
|
||||
errInvalidExceptionSystem = "'goto', 'setjmp', 'cpp' or 'quirky' expected, but '$1' found"
|
||||
@@ -262,6 +262,7 @@ proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo
|
||||
of "go": result = conf.selectedGC == gcGo
|
||||
of "none": result = conf.selectedGC == gcNone
|
||||
of "stack", "regions": result = conf.selectedGC == gcRegions
|
||||
of "atomicarc": result = conf.selectedGC == gcAtomicArc
|
||||
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
|
||||
of "opt":
|
||||
case arg.normalize
|
||||
@@ -516,14 +517,7 @@ proc initOrcDefines*(conf: ConfigRef) =
|
||||
if conf.exc == excNone and conf.backend != backendCpp:
|
||||
conf.exc = excGoto
|
||||
|
||||
proc registerArcOrc(pass: TCmdLinePass, conf: ConfigRef, isOrc: bool) =
|
||||
if isOrc:
|
||||
conf.selectedGC = gcOrc
|
||||
defineSymbol(conf.symbols, "gcorc")
|
||||
else:
|
||||
conf.selectedGC = gcArc
|
||||
defineSymbol(conf.symbols, "gcarc")
|
||||
|
||||
proc registerArcOrc(pass: TCmdLinePass, conf: ConfigRef) =
|
||||
defineSymbol(conf.symbols, "gcdestructors")
|
||||
incl conf.globalOptions, optSeqDestructors
|
||||
incl conf.globalOptions, optTinyRtti
|
||||
@@ -562,9 +556,17 @@ proc processMemoryManagementOption(switch, arg: string, pass: TCmdLinePass,
|
||||
conf.selectedGC = gcMarkAndSweep
|
||||
defineSymbol(conf.symbols, "gcmarkandsweep")
|
||||
of "destructors", "arc":
|
||||
registerArcOrc(pass, conf, false)
|
||||
conf.selectedGC = gcArc
|
||||
defineSymbol(conf.symbols, "gcarc")
|
||||
registerArcOrc(pass, conf)
|
||||
of "orc":
|
||||
registerArcOrc(pass, conf, true)
|
||||
conf.selectedGC = gcOrc
|
||||
defineSymbol(conf.symbols, "gcorc")
|
||||
registerArcOrc(pass, conf)
|
||||
of "atomicarc":
|
||||
conf.selectedGC = gcAtomicArc
|
||||
defineSymbol(conf.symbols, "gcatomicarc")
|
||||
registerArcOrc(pass, conf)
|
||||
of "hooks":
|
||||
conf.selectedGC = gcHooks
|
||||
defineSymbol(conf.symbols, "gchooks")
|
||||
|
||||
@@ -493,7 +493,7 @@ proc constructCfg*(s: PSym; body: PNode; root: PSym): ControlFlowGraph =
|
||||
gen(c, body)
|
||||
if root.kind == skResult:
|
||||
genImplicitReturn(c)
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
result = c.code # will move
|
||||
else:
|
||||
shallowCopy(result, c.code)
|
||||
|
||||
@@ -66,7 +66,7 @@ proc hasDestructor(c: Con; t: PType): bool {.inline.} =
|
||||
result = ast.hasDestructor(t)
|
||||
when toDebug.len > 0:
|
||||
# for more effective debugging
|
||||
if not result and c.graph.config.selectedGC in {gcArc, gcOrc}:
|
||||
if not result and c.graph.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
assert(not containsGarbageCollectedRef(t))
|
||||
|
||||
proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode =
|
||||
@@ -452,7 +452,7 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode =
|
||||
("passing '$1' to a sink parameter introduces an implicit copy; " &
|
||||
"if possible, rearrange your program's control flow to prevent it") % $n)
|
||||
else:
|
||||
if c.graph.config.selectedGC in {gcArc, gcOrc}:
|
||||
if c.graph.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
assert(not containsManagedMemory(n.typ))
|
||||
if n.typ.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}:
|
||||
localError(c.graph.config, n.info, "cannot create an implicit openArray copy to be passed to a sink parameter")
|
||||
@@ -495,7 +495,7 @@ proc ensureDestruction(arg, orig: PNode; c: var Con; s: var Scope): PNode =
|
||||
result = arg
|
||||
|
||||
proc cycleCheck(n: PNode; c: var Con) =
|
||||
if c.graph.config.selectedGC != gcArc: return
|
||||
if c.graph.config.selectedGC notin {gcArc, gcAtomicArc}: return
|
||||
var value = n[1]
|
||||
if value.kind == nkClosure:
|
||||
value = value[1]
|
||||
@@ -838,7 +838,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
|
||||
|
||||
if n[0].kind == nkSym and n[0].sym.magic in {mNew, mNewFinalize}:
|
||||
result[0] = copyTree(n[0])
|
||||
if c.graph.config.selectedGC in {gcHooks, gcArc, gcOrc}:
|
||||
if c.graph.config.selectedGC in {gcHooks, gcArc, gcAtomicArc, gcOrc}:
|
||||
let destroyOld = c.genDestroy(result[1])
|
||||
result = newTree(nkStmtList, destroyOld, result)
|
||||
else:
|
||||
|
||||
@@ -159,7 +159,7 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool)
|
||||
let f = n.sym
|
||||
let b = if c.kind == attachedTrace: y else: y.dotField(f)
|
||||
if (sfCursor in f.flags and f.typ.skipTypes(abstractInst).kind in {tyRef, tyProc} and
|
||||
c.g.config.selectedGC in {gcArc, gcOrc, gcHooks}) or
|
||||
c.g.config.selectedGC in {gcArc, gcAtomicArc, gcOrc, gcHooks}) or
|
||||
enforceDefaultOp:
|
||||
defaultOp(c, f.typ, body, x.dotField(f), b)
|
||||
else:
|
||||
@@ -827,7 +827,7 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
call[1] = y
|
||||
body.add newAsgnStmt(x, call)
|
||||
elif (optOwnedRefs in c.g.config.globalOptions and
|
||||
optRefCheck in c.g.config.options) or c.g.config.selectedGC in {gcArc, gcOrc}:
|
||||
optRefCheck in c.g.config.options) or c.g.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}:
|
||||
let xx = genBuiltin(c, mAccessEnv, "accessEnv", x)
|
||||
xx.typ = getSysType(c.g, c.info, tyPointer)
|
||||
case c.kind
|
||||
@@ -879,7 +879,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
tyPtr, tyUncheckedArray, tyVar, tyLent:
|
||||
defaultOp(c, t, body, x, y)
|
||||
of tyRef:
|
||||
if c.g.config.selectedGC in {gcArc, gcOrc}:
|
||||
if c.g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
atomicRefOp(c, t, body, x, y)
|
||||
elif (optOwnedRefs in c.g.config.globalOptions and
|
||||
optRefCheck in c.g.config.options):
|
||||
@@ -888,7 +888,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
defaultOp(c, t, body, x, y)
|
||||
of tyProc:
|
||||
if t.callConv == ccClosure:
|
||||
if c.g.config.selectedGC in {gcArc, gcOrc}:
|
||||
if c.g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
atomicClosureOp(c, t, body, x, y)
|
||||
else:
|
||||
closureOp(c, t, body, x, y)
|
||||
@@ -1039,7 +1039,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
result.ast[bodyPos].add newAsgnStmt(d, src)
|
||||
else:
|
||||
var tk: TTypeKind
|
||||
if g.config.selectedGC in {gcArc, gcOrc, gcHooks}:
|
||||
if g.config.selectedGC in {gcArc, gcOrc, gcHooks, gcAtomicArc}:
|
||||
tk = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}).kind
|
||||
else:
|
||||
tk = tyNone # no special casing for strings and seqs
|
||||
|
||||
@@ -226,7 +226,7 @@ proc setDirtyFile*(conf: ConfigRef; fileIdx: FileIndex; filename: AbsoluteFile)
|
||||
|
||||
proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
|
||||
assert fileIdx.int32 >= 0
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
conf.m.fileInfos[fileIdx.int32].hash = hash
|
||||
else:
|
||||
shallowCopy(conf.m.fileInfos[fileIdx.int32].hash, hash)
|
||||
@@ -234,7 +234,7 @@ proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
|
||||
|
||||
proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||
assert fileIdx.int32 >= 0
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
result = conf.m.fileInfos[fileIdx.int32].hash
|
||||
else:
|
||||
shallowCopy(result, conf.m.fileInfos[fileIdx.int32].hash)
|
||||
|
||||
@@ -22,7 +22,7 @@ proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent
|
||||
let last = first+identLen(line, first)-1
|
||||
if cmpIgnoreStyle(line[first..last], oldSym.s) == 0:
|
||||
var x = line.substr(0, first-1) & newSym.s & line.substr(last+1)
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1] = move x
|
||||
else:
|
||||
system.shallowCopy(conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1], x)
|
||||
@@ -38,7 +38,7 @@ proc replaceComment*(conf: ConfigRef; info: TLineInfo) =
|
||||
if line[first] != '#': inc first
|
||||
|
||||
var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1] = move x
|
||||
else:
|
||||
system.shallowCopy(conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1], x)
|
||||
|
||||
@@ -184,6 +184,7 @@ type
|
||||
gcRegions = "regions"
|
||||
gcArc = "arc"
|
||||
gcOrc = "orc"
|
||||
gcAtomicArc = "atomicArc"
|
||||
gcMarkAndSweep = "markAndSweep"
|
||||
gcHooks = "hooks"
|
||||
gcRefc = "refc"
|
||||
|
||||
@@ -535,7 +535,7 @@ proc processCompile(c: PContext, n: PNode) =
|
||||
n[i] = c.semConstExpr(c, n[i])
|
||||
case n[i].kind
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
result = n[i].strVal
|
||||
else:
|
||||
shallowCopy(result, n[i].strVal)
|
||||
|
||||
@@ -227,7 +227,7 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
|
||||
if optOwnedRefs in oldGlobalOptions:
|
||||
conf.globalOptions.incl {optTinyRtti, optOwnedRefs, optSeqDestructors}
|
||||
defineSymbol(conf.symbols, "nimv2")
|
||||
if conf.selectedGC in {gcArc, gcOrc}:
|
||||
if conf.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
conf.globalOptions.incl {optTinyRtti, optSeqDestructors}
|
||||
defineSymbol(conf.symbols, "nimv2")
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ proc isCastable(c: PContext; dst, src: PType, info: TLineInfo): bool =
|
||||
if skipTypes(dst, abstractInst).kind == tyBuiltInTypeClass:
|
||||
return false
|
||||
let conf = c.config
|
||||
if conf.selectedGC in {gcArc, gcOrc}:
|
||||
if conf.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
let d = skipTypes(dst, abstractInst)
|
||||
let s = skipTypes(src, abstractInst)
|
||||
if d.kind == tyRef and s.kind == tyRef and s[0].isFinal != d[0].isFinal:
|
||||
|
||||
@@ -1480,7 +1480,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
|
||||
let param = params[i].sym
|
||||
let typ = param.typ
|
||||
if isSinkTypeForParam(typ) or
|
||||
(t.config.selectedGC in {gcArc, gcOrc} and
|
||||
(t.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
|
||||
(isClosure(typ.skipTypes(abstractInst)) or param.id in t.escapingParams)):
|
||||
createTypeBoundOps(t, typ, param.info)
|
||||
if isOutParam(typ) and param.id notin t.init:
|
||||
|
||||
@@ -968,7 +968,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||
t.rawAddSonNoPropagationOfTypeFlags result
|
||||
result = t
|
||||
else: discard
|
||||
if result.kind == tyRef and c.config.selectedGC in {gcArc, gcOrc}:
|
||||
if result.kind == tyRef and c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
result.flags.incl tfHasAsgn
|
||||
|
||||
proc findEnforcedStaticType(t: PType): PType =
|
||||
|
||||
@@ -37,7 +37,7 @@ proc spawnResult*(t: PType; inParallel: bool): TSpawnResult =
|
||||
else: srFlowVar
|
||||
|
||||
proc flowVarKind(c: ConfigRef, t: PType): TFlowVarKind =
|
||||
if c.selectedGC in {gcArc, gcOrc}: fvBlob
|
||||
if c.selectedGC in {gcArc, gcOrc, gcAtomicArc}: fvBlob
|
||||
elif t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC
|
||||
elif containsGarbageCollectedRef(t): fvInvalid
|
||||
else: fvBlob
|
||||
@@ -66,7 +66,7 @@ proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; idgen: IdGenerator;
|
||||
vpart[2] = if varInit.isNil: v else: vpart[1]
|
||||
varSection.add vpart
|
||||
if varInit != nil:
|
||||
if g.config.selectedGC in {gcArc, gcOrc}:
|
||||
if g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}:
|
||||
# inject destructors pass will do its own analysis
|
||||
varInit.add newFastMoveStmt(g, newSymNode(result), v)
|
||||
else:
|
||||
|
||||
@@ -121,7 +121,7 @@ template decodeBx(k: untyped) {.dirty.} =
|
||||
ensureKind(k)
|
||||
|
||||
template move(a, b: untyped) {.dirty.} =
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
a = move b
|
||||
else:
|
||||
system.shallowCopy(a, b)
|
||||
@@ -550,7 +550,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
# Used to keep track of where the execution is resumed.
|
||||
var savedPC = -1
|
||||
var savedFrame: PStackFrame
|
||||
when defined(gcArc) or defined(gcOrc):
|
||||
when defined(gcArc) or defined(gcOrc) or defined(gcAtomicArc):
|
||||
template updateRegsAlias = discard
|
||||
template regs: untyped = tos.slots
|
||||
else:
|
||||
|
||||
@@ -57,6 +57,21 @@ elif defined(nimArcIds):
|
||||
|
||||
const traceId = -1
|
||||
|
||||
when defined(gcAtomicArc) and hasThreadSupport:
|
||||
template decrement(cell: Cell): untyped =
|
||||
discard atomicDec(cell.rc, rcIncrement)
|
||||
template increment(cell: Cell): untyped =
|
||||
discard atomicInc(cell.rc, rcIncrement)
|
||||
template count(x: Cell): untyped =
|
||||
atomicLoadN(x.rc.addr, ATOMIC_ACQUIRE) shr rcShift
|
||||
else:
|
||||
template decrement(cell: Cell): untyped =
|
||||
dec(cell.rc, rcIncrement)
|
||||
template increment(cell: Cell): untyped =
|
||||
inc(cell.rc, rcIncrement)
|
||||
template count(x: Cell): untyped =
|
||||
x.rc shr rcShift
|
||||
|
||||
proc nimNewObj(size, alignment: int): pointer {.compilerRtl.} =
|
||||
let hdrSize = align(sizeof(RefHeader), alignment)
|
||||
let s = size + hdrSize
|
||||
@@ -69,7 +84,7 @@ proc nimNewObj(size, alignment: int): pointer {.compilerRtl.} =
|
||||
atomicInc gRefId
|
||||
if head(result).refId == traceId:
|
||||
writeStackTrace()
|
||||
cfprintf(cstderr, "[nimNewObj] %p %ld\n", result, head(result).rc shr rcShift)
|
||||
cfprintf(cstderr, "[nimNewObj] %p %ld\n", result, head(result).count)
|
||||
when traceCollector:
|
||||
cprintf("[Allocated] %p result: %p\n", result -! sizeof(RefHeader), result)
|
||||
|
||||
@@ -90,21 +105,21 @@ proc nimNewObjUninit(size, alignment: int): pointer {.compilerRtl.} =
|
||||
atomicInc gRefId
|
||||
if head(result).refId == traceId:
|
||||
writeStackTrace()
|
||||
cfprintf(cstderr, "[nimNewObjUninit] %p %ld\n", result, head(result).rc shr rcShift)
|
||||
cfprintf(cstderr, "[nimNewObjUninit] %p %ld\n", result, head(result).count)
|
||||
|
||||
when traceCollector:
|
||||
cprintf("[Allocated] %p result: %p\n", result -! sizeof(RefHeader), result)
|
||||
|
||||
proc nimDecWeakRef(p: pointer) {.compilerRtl, inl.} =
|
||||
dec head(p).rc, rcIncrement
|
||||
decrement head(p)
|
||||
|
||||
proc nimIncRef(p: pointer) {.compilerRtl, inl.} =
|
||||
when defined(nimArcDebug):
|
||||
if head(p).refId == traceId:
|
||||
writeStackTrace()
|
||||
cfprintf(cstderr, "[IncRef] %p %ld\n", p, head(p).rc shr rcShift)
|
||||
cfprintf(cstderr, "[IncRef] %p %ld\n", p, head(p).count)
|
||||
|
||||
inc head(p).rc, rcIncrement
|
||||
increment head(p)
|
||||
when traceCollector:
|
||||
cprintf("[INCREF] %p\n", head(p))
|
||||
|
||||
@@ -173,17 +188,17 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} =
|
||||
when defined(nimArcDebug):
|
||||
if cell.refId == traceId:
|
||||
writeStackTrace()
|
||||
cfprintf(cstderr, "[DecRef] %p %ld\n", p, cell.rc shr rcShift)
|
||||
cfprintf(cstderr, "[DecRef] %p %ld\n", p, cell.count)
|
||||
|
||||
if (cell.rc and not rcMask) == 0:
|
||||
if cell.count == 0:
|
||||
result = true
|
||||
when traceCollector:
|
||||
cprintf("[ABOUT TO DESTROY] %p\n", cell)
|
||||
else:
|
||||
dec cell.rc, rcIncrement
|
||||
decrement cell
|
||||
# According to Lins it's correct to do nothing else here.
|
||||
when traceCollector:
|
||||
cprintf("[DeCREF] %p\n", cell)
|
||||
cprintf("[DECREF] %p\n", cell)
|
||||
|
||||
proc nimDupRef(dest: ptr pointer, src: pointer) {.compilerRtl, inl.} =
|
||||
dest[] = src
|
||||
|
||||
Reference in New Issue
Block a user