cleaner GC switching
This commit is contained in:
parent
d9d98512e0
commit
2a2b630757
7 changed files with 32 additions and 25 deletions
|
|
@ -164,7 +164,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
|
||||||
else: result = OnUnknown
|
else: result = OnUnknown
|
||||||
|
|
||||||
proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
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))
|
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||||
if needToKeepAlive in flags: keepAlive(p, dest)
|
if needToKeepAlive in flags: keepAlive(p, dest)
|
||||||
elif dest.s == OnHeap:
|
elif dest.s == OnHeap:
|
||||||
|
|
@ -204,7 +204,7 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
# (for objects, etc.):
|
# (for objects, etc.):
|
||||||
if needToCopy notin flags or
|
if needToCopy notin flags or
|
||||||
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
|
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,
|
linefmt(p, cpsStmts,
|
||||||
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
|
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
|
||||||
addrLoc(dest), addrLoc(src), rdLoc(dest))
|
addrLoc(dest), addrLoc(src), rdLoc(dest))
|
||||||
|
|
@ -237,7 +237,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
if needToCopy notin flags:
|
if needToCopy notin flags:
|
||||||
genRefAssign(p, dest, src, flags)
|
genRefAssign(p, dest, src, flags)
|
||||||
else:
|
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)
|
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc)
|
||||||
if needToKeepAlive in flags: keepAlive(p, dest)
|
if needToKeepAlive in flags: keepAlive(p, dest)
|
||||||
elif dest.s == OnHeap:
|
elif dest.s == OnHeap:
|
||||||
|
|
@ -954,7 +954,7 @@ proc genNew(p: BProc, e: PNode) =
|
||||||
let args = [getTypeDesc(p.module, reftype),
|
let args = [getTypeDesc(p.module, reftype),
|
||||||
genTypeInfo(p.module, refType),
|
genTypeInfo(p.module, refType),
|
||||||
sizeExpr]
|
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
|
# use newObjRC1 as an optimization; and we don't need 'keepAlive' either
|
||||||
if canFormAcycle(a.t):
|
if canFormAcycle(a.t):
|
||||||
linefmt(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc)
|
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]
|
genTypeInfo(p.module, seqType), length]
|
||||||
var call: TLoc
|
var call: TLoc
|
||||||
initLoc(call, locExpr, dest.t, OnHeap)
|
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)
|
linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", dest.rdLoc)
|
||||||
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
|
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
|
linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
|
||||||
|
|
|
||||||
|
|
@ -938,7 +938,7 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
|
||||||
genTupleInfo(m, fakeClosureType(t.owner), result)
|
genTupleInfo(m, fakeClosureType(t.owner), result)
|
||||||
of tySequence, tyRef:
|
of tySequence, tyRef:
|
||||||
genTypeInfoAux(m, t, result)
|
genTypeInfoAux(m, t, result)
|
||||||
if optRefcGC in gGlobalOptions:
|
if usesNativeGC():
|
||||||
let markerProc = genTraverseProc(m, t, tiNew)
|
let markerProc = genTraverseProc(m, t, tiNew)
|
||||||
appf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
|
appf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
|
||||||
of tyPtr, tyRange: genTypeInfoAux(m, t, result)
|
of tyPtr, tyRange: genTypeInfoAux(m, t, result)
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,10 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
|
||||||
case switch.normalize
|
case switch.normalize
|
||||||
of "gc":
|
of "gc":
|
||||||
case arg.normalize
|
case arg.normalize
|
||||||
of "boehm": result = contains(gGlobalOptions, optBoehmGC)
|
of "boehm": result = gSelectedGC == gcBoehm
|
||||||
of "refc": result = contains(gGlobalOptions, optRefcGC)
|
of "refc": result = gSelectedGC == gcRefc
|
||||||
of "none": result = gGlobalOptions * {optBoehmGC, optRefcGC} == {}
|
of "v2": result = gSelectedGC == gcV2
|
||||||
|
of "none": result = gSelectedGC == gcNone
|
||||||
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
|
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
|
||||||
of "opt":
|
of "opt":
|
||||||
case arg.normalize
|
case arg.normalize
|
||||||
|
|
@ -269,15 +270,14 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
|
||||||
expectArg(switch, arg, pass, info)
|
expectArg(switch, arg, pass, info)
|
||||||
case arg.normalize
|
case arg.normalize
|
||||||
of "boehm":
|
of "boehm":
|
||||||
incl(gGlobalOptions, optBoehmGC)
|
gSelectedGC = gcBoehm
|
||||||
excl(gGlobalOptions, optRefcGC)
|
|
||||||
DefineSymbol("boehmgc")
|
DefineSymbol("boehmgc")
|
||||||
of "refc":
|
of "refc":
|
||||||
excl(gGlobalOptions, optBoehmGC)
|
gSelectedGC = gcRefc
|
||||||
incl(gGlobalOptions, optRefcGC)
|
of "v2":
|
||||||
|
gSelectedGC = gcV2
|
||||||
of "none":
|
of "none":
|
||||||
excl(gGlobalOptions, optRefcGC)
|
gSelectedGC = gcNone
|
||||||
excl(gGlobalOptions, optBoehmGC)
|
|
||||||
defineSymbol("nogc")
|
defineSymbol("nogc")
|
||||||
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
|
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
|
||||||
of "warnings", "w": ProcessOnOffSwitch({optWarns}, arg, pass, info)
|
of "warnings", "w": ProcessOnOffSwitch({optWarns}, arg, pass, info)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type # please make sure we have under 32 options
|
||||||
|
|
||||||
TOptions* = set[TOption]
|
TOptions* = set[TOption]
|
||||||
TGlobalOption* = enum # **keep binary compatible**
|
TGlobalOption* = enum # **keep binary compatible**
|
||||||
gloptNone, optForceFullMake, optBoehmGC, optRefcGC, optDeadCodeElim,
|
gloptNone, optForceFullMake, optDeadCodeElim,
|
||||||
optListCmd, optCompileOnly, optNoLinking,
|
optListCmd, optCompileOnly, optNoLinking,
|
||||||
optSafeCode, # only allow safe code
|
optSafeCode, # only allow safe code
|
||||||
optCDebug, # turn on debugging information
|
optCDebug, # turn on debugging information
|
||||||
|
|
@ -80,6 +80,8 @@ type # please make sure we have under 32 options
|
||||||
cmdInteractive, # start interactive session
|
cmdInteractive, # start interactive session
|
||||||
cmdRun # run the project via TCC backend
|
cmdRun # run the project via TCC backend
|
||||||
TStringSeq* = seq[string]
|
TStringSeq* = seq[string]
|
||||||
|
TGCMode* = enum # the selected GC
|
||||||
|
gcNone, gcBoehm, gcRefc, gcV2 #
|
||||||
|
|
||||||
const
|
const
|
||||||
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
|
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
|
||||||
|
|
@ -90,12 +92,13 @@ var
|
||||||
optBoundsCheck, optOverflowCheck, optAssert, optWarns,
|
optBoundsCheck, optOverflowCheck, optAssert, optWarns,
|
||||||
optHints, optStackTrace, optLineTrace,
|
optHints, optStackTrace, optLineTrace,
|
||||||
optPatterns}
|
optPatterns}
|
||||||
gGlobalOptions*: TGlobalOptions = {optRefcGC, optThreadAnalysis}
|
gGlobalOptions*: TGlobalOptions = {optThreadAnalysis}
|
||||||
gExitcode*: int8
|
gExitcode*: int8
|
||||||
|
gCmd*: TCommands = cmdNone # the command
|
||||||
|
gSelectedGC* = gcRefc # the selected GC
|
||||||
searchPaths*, lazyPaths*: TLinkedList
|
searchPaths*, lazyPaths*: TLinkedList
|
||||||
outFile*: string = ""
|
outFile*: string = ""
|
||||||
headerFile*: string = ""
|
headerFile*: string = ""
|
||||||
gCmd*: TCommands = cmdNone # the command
|
|
||||||
gVerbosity*: int # how verbose the compiler is
|
gVerbosity*: int # how verbose the compiler is
|
||||||
gNumberOfProcessors*: int # number of processors
|
gNumberOfProcessors*: int # number of processors
|
||||||
gWholeProject*: bool # for 'doc2': output any dependency
|
gWholeProject*: bool # for 'doc2': output any dependency
|
||||||
|
|
@ -104,6 +107,7 @@ var
|
||||||
gListFullPaths*: bool
|
gListFullPaths*: bool
|
||||||
|
|
||||||
proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
|
proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools}
|
||||||
|
proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc
|
||||||
|
|
||||||
const
|
const
|
||||||
genSubDir* = "nimcache"
|
genSubDir* = "nimcache"
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ Advanced options:
|
||||||
--skipUserCfg do not read the user's configuration file
|
--skipUserCfg do not read the user's configuration file
|
||||||
--skipParentCfg do not read the parent dirs' configuration files
|
--skipParentCfg do not read the parent dirs' configuration files
|
||||||
--skipProjCfg do not read the project's configuration file
|
--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
|
--index:on|off turn index file generation on|off
|
||||||
--putenv:key=value set an environment variable
|
--putenv:key=value set an environment variable
|
||||||
--babelPath:PATH add a path for Babel support
|
--babelPath:PATH add a path for Babel support
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ proc runGcTests(r: var TResults, options: string) =
|
||||||
test "gctest"
|
test "gctest"
|
||||||
test "gcleak3"
|
test "gcleak3"
|
||||||
test "weakrefs"
|
test "weakrefs"
|
||||||
|
test "cycleleak"
|
||||||
|
|
||||||
# ------------------------- threading tests -----------------------------------
|
# ------------------------- threading tests -----------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -46,6 +46,8 @@ Concurrency
|
||||||
an ``injectLoop`` pragma
|
an ``injectLoop`` pragma
|
||||||
- 'writes: []' effect; track reads/writes for shared types
|
- 'writes: []' effect; track reads/writes for shared types
|
||||||
- use the effect system for static deadlock prevention and race detection
|
- 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
|
version 0.9.XX
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue