cleaner GC switching

This commit is contained in:
Araq
2013-01-31 16:34:39 +01:00
parent d9d98512e0
commit 2a2b630757
7 changed files with 32 additions and 25 deletions

View File

@@ -164,7 +164,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
else: result = OnUnknown
proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if dest.s == OnStack or optRefcGC notin gGlobalOptions:
if dest.s == OnStack or not usesNativeGC():
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
if needToKeepAlive in flags: keepAlive(p, dest)
elif dest.s == OnHeap:
@@ -204,7 +204,7 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# (for objects, etc.):
if needToCopy notin flags or
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
if dest.s == OnStack or optRefcGC notin gGlobalOptions:
if dest.s == OnStack or not usesNativeGC():
linefmt(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
addrLoc(dest), addrLoc(src), rdLoc(dest))
@@ -237,7 +237,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needToCopy notin flags:
genRefAssign(p, dest, src, flags)
else:
if dest.s == OnStack or optRefcGC notin gGlobalOptions:
if dest.s == OnStack or not usesNativeGC():
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc)
if needToKeepAlive in flags: keepAlive(p, dest)
elif dest.s == OnHeap:
@@ -954,7 +954,7 @@ proc genNew(p: BProc, e: PNode) =
let args = [getTypeDesc(p.module, reftype),
genTypeInfo(p.module, refType),
sizeExpr]
if a.s == OnHeap and optRefcGc in gGlobalOptions:
if a.s == OnHeap and usesNativeGC():
# use newObjRC1 as an optimization; and we don't need 'keepAlive' either
if canFormAcycle(a.t):
linefmt(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc)
@@ -974,7 +974,7 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
genTypeInfo(p.module, seqType), length]
var call: TLoc
initLoc(call, locExpr, dest.t, OnHeap)
if dest.s == OnHeap and optRefcGc in gGlobalOptions:
if dest.s == OnHeap and usesNativeGC():
linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", dest.rdLoc)
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)

View File

@@ -938,7 +938,7 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
genTupleInfo(m, fakeClosureType(t.owner), result)
of tySequence, tyRef:
genTypeInfoAux(m, t, result)
if optRefcGC in gGlobalOptions:
if usesNativeGC():
let markerProc = genTraverseProc(m, t, tiNew)
appf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
of tyPtr, tyRange: genTypeInfoAux(m, t, result)

View File

@@ -135,15 +135,16 @@ proc processCompile(filename: string) =
extccomp.addExternalFileToCompile(found)
extccomp.addFileToLink(completeCFilePath(trunc, false))
proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
case switch.normalize
of "gc":
of "gc":
case arg.normalize
of "boehm": result = contains(gGlobalOptions, optBoehmGC)
of "refc": result = contains(gGlobalOptions, optRefcGC)
of "none": result = gGlobalOptions * {optBoehmGC, optRefcGC} == {}
of "boehm": result = gSelectedGC == gcBoehm
of "refc": result = gSelectedGC == gcRefc
of "v2": result = gSelectedGC == gcV2
of "none": result = gSelectedGC == gcNone
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
of "opt":
of "opt":
case arg.normalize
of "speed": result = contains(gOptions, optOptimizeSpeed)
of "size": result = contains(gOptions, optOptimizeSize)
@@ -269,15 +270,14 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
expectArg(switch, arg, pass, info)
case arg.normalize
of "boehm":
incl(gGlobalOptions, optBoehmGC)
excl(gGlobalOptions, optRefcGC)
gSelectedGC = gcBoehm
DefineSymbol("boehmgc")
of "refc":
excl(gGlobalOptions, optBoehmGC)
incl(gGlobalOptions, optRefcGC)
of "none":
excl(gGlobalOptions, optRefcGC)
excl(gGlobalOptions, optBoehmGC)
of "refc":
gSelectedGC = gcRefc
of "v2":
gSelectedGC = gcV2
of "none":
gSelectedGC = gcNone
defineSymbol("nogc")
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
of "warnings", "w": ProcessOnOffSwitch({optWarns}, arg, pass, info)

View File

@@ -34,7 +34,7 @@ type # please make sure we have under 32 options
TOptions* = set[TOption]
TGlobalOption* = enum # **keep binary compatible**
gloptNone, optForceFullMake, optBoehmGC, optRefcGC, optDeadCodeElim,
gloptNone, optForceFullMake, optDeadCodeElim,
optListCmd, optCompileOnly, optNoLinking,
optSafeCode, # only allow safe code
optCDebug, # turn on debugging information
@@ -80,8 +80,10 @@ type # please make sure we have under 32 options
cmdInteractive, # start interactive session
cmdRun # run the project via TCC backend
TStringSeq* = seq[string]
TGCMode* = enum # the selected GC
gcNone, gcBoehm, gcRefc, gcV2 #
const
const
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck}
@@ -90,12 +92,13 @@ var
optBoundsCheck, optOverflowCheck, optAssert, optWarns,
optHints, optStackTrace, optLineTrace,
optPatterns}
gGlobalOptions*: TGlobalOptions = {optRefcGC, optThreadAnalysis}
gGlobalOptions*: TGlobalOptions = {optThreadAnalysis}
gExitcode*: int8
gCmd*: TCommands = cmdNone # the command
gSelectedGC* = gcRefc # the selected GC
searchPaths*, lazyPaths*: TLinkedList
outFile*: string = ""
headerFile*: string = ""
gCmd*: TCommands = cmdNone # the command
gVerbosity*: int # how verbose the compiler is
gNumberOfProcessors*: int # number of processors
gWholeProject*: bool # for 'doc2': output any dependency
@@ -104,6 +107,7 @@ var
gListFullPaths*: bool
proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc
const
genSubDir* = "nimcache"

View File

@@ -64,7 +64,7 @@ Advanced options:
--skipUserCfg do not read the user's configuration file
--skipParentCfg do not read the parent dirs' configuration files
--skipProjCfg do not read the project's configuration file
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
--gc:refc|v2|boehm|none use Nimrod's native GC|V2|Boehm GC|no GC
--index:on|off turn index file generation on|off
--putenv:key=value set an environment variable
--babelPath:PATH add a path for Babel support

View File

@@ -126,6 +126,7 @@ proc runGcTests(r: var TResults, options: string) =
test "gctest"
test "gcleak3"
test "weakrefs"
test "cycleleak"
# ------------------------- threading tests -----------------------------------

View File

@@ -46,6 +46,8 @@ Concurrency
an ``injectLoop`` pragma
- 'writes: []' effect; track reads/writes for shared types
- use the effect system for static deadlock prevention and race detection
- introduce 'noaddr' pragma to prevent taking the address of a location; this
is very handy to prevent aliasing of global data
version 0.9.XX