diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-05-08 22:25:47 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-08 16:25:47 +0200 |
commit | 4533e894ad0e113c6057d336290d2c903383e406 (patch) | |
tree | 97847fbd50f69bef551d09bf52e31bfd82bfad79 | |
parent | ebdff1c7d36683c13b7b692e7d2f16aa3b13027f (diff) | |
download | Nim-4533e894ad0e113c6057d336290d2c903383e406.tar.gz |
adds an experimental `mm:atomicArc` switch (#21798)
-rw-r--r-- | compiler/btrees.nim | 4 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 2 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 6 | ||||
-rw-r--r-- | compiler/cgen.nim | 8 | ||||
-rw-r--r-- | compiler/commands.nim | 24 | ||||
-rw-r--r-- | compiler/dfa.nim | 2 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 8 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 10 | ||||
-rw-r--r-- | compiler/msgs.nim | 4 | ||||
-rw-r--r-- | compiler/nimfix/prettybase.nim | 4 | ||||
-rw-r--r-- | compiler/options.nim | 1 | ||||
-rw-r--r-- | compiler/pragmas.nim | 2 | ||||
-rw-r--r-- | compiler/scriptconfig.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 2 | ||||
-rw-r--r-- | compiler/sempass2.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 2 | ||||
-rw-r--r-- | compiler/spawn.nim | 4 | ||||
-rw-r--r-- | compiler/vm.nim | 4 | ||||
-rw-r--r-- | lib/system/arc.nim | 33 |
19 files changed, 71 insertions, 53 deletions
diff --git a/compiler/btrees.nim b/compiler/btrees.nim index c79442249..92f07f6b0 100644 --- a/compiler/btrees.nim +++ b/compiler/btrees.nim @@ -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]) diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 65c814fb9..b55c89c1d 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -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, {}) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index e351e95b0..66f92f12e 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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") diff --git a/compiler/cgen.nim b/compiler/cgen.nim index a57654239..65f8040f5 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -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") diff --git a/compiler/commands.nim b/compiler/commands.nim index c31476b45..93a36e714 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -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") diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 61a921ba0..d145e31c3 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -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) diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index d9a2da5a0..ab0fa02d9 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -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: diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 3a997af82..34ab3cc8e 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -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 diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 8e391f2fb..05ace315e 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -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) diff --git a/compiler/nimfix/prettybase.nim b/compiler/nimfix/prettybase.nim index 78c24bae3..b5a7ba42b 100644 --- a/compiler/nimfix/prettybase.nim +++ b/compiler/nimfix/prettybase.nim @@ -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) diff --git a/compiler/options.nim b/compiler/options.nim index da9c9cbbb..a9f1e7542 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -184,6 +184,7 @@ type gcRegions = "regions" gcArc = "arc" gcOrc = "orc" + gcAtomicArc = "atomicArc" gcMarkAndSweep = "markAndSweep" gcHooks = "hooks" gcRefc = "refc" diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 10d77a17e..31414063a 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -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) diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 27ea94aae..21b0eb195 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -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") diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index a01466868..4dd7840f1 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index baa37a45f..7024c99fe 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -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: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 750ab2216..f4b284f7e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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 = diff --git a/compiler/spawn.nim b/compiler/spawn.nim index add36759d..7423fdfaa 100644 --- a/compiler/spawn.nim +++ b/compiler/spawn.nim @@ -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: diff --git a/compiler/vm.nim b/compiler/vm.nim index dbb02cffa..ba3677cf1 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -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: diff --git a/lib/system/arc.nim b/lib/system/arc.nim index 55c4c412a..acb07174b 100644 --- a/lib/system/arc.nim +++ b/lib/system/arc.nim @@ -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 |