first version of a simple mark&sweep GC; activate with --gc:markAndSweep

This commit is contained in:
Araq 2013-02-07 01:57:10 +01:00
commit ab6f793408
12 changed files with 834 additions and 89 deletions

View file

@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2012 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -15,6 +15,14 @@ const
stringCaseThreshold = 8
# above X strings a hash-switch for strings is generated
proc registerGcRoot(p: BProc, v: PSym) =
if gSelectedGc == gcMarkAndSweep and containsGarbageCollectedRef(v.loc.t):
# we register a specialized marked proc here; this has the advantage
# that it works out of the box for thread local storage then :-)
let prc = genTraverseProcForGlobal(p.module, v)
linefmt(p.module.initProc, cpsStmts,
"#nimRegisterGlobalMarker((void*)$1);$n", prc)
proc genVarTuple(p: BProc, n: PNode) =
var tup, field: TLoc
if n.kind != nkVarTuple: InternalError(n.info, "genVarTuple")
@ -28,6 +36,7 @@ proc genVarTuple(p: BProc, n: PNode) =
if sfGlobal in v.flags:
assignGlobalVar(p, v)
genObjectInit(p, cpsInit, v.typ, v.loc, true)
registerGcRoot(p, v)
else:
assignLocalVar(p, v)
initLocalVar(p, v, immediateAsgn=true)
@ -143,7 +152,7 @@ proc genSingleVar(p: BProc, a: PNode) =
# if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc)
if sfExportc in v.flags and generatedHeader != nil:
genVarPrototypeAux(generatedHeader, v)
registerGcRoot(p, v)
else:
assignLocalVar(p, v)
initLocalVar(p, v, immediateAsgn)

View file

@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2012 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -13,7 +13,7 @@
# included from cgen.nim
type
TTraversalClosure {.pure, final.} = object
TTraversalClosure = object
p: BProc
visitorFrmt: string
@ -127,3 +127,20 @@ proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope =
m.s[cfsProcs].app(generatedProc)
proc genTraverseProcForGlobal(m: BModule, s: PSym): PRope =
discard genTypeInfo(m, s.loc.t)
var c: TTraversalClosure
var p = newProc(nil, m)
result = getGlobalTempName()
c.visitorFrmt = "#nimGCvisit((void*)$1, 0);$n"
c.p = p
let header = ropef("N_NIMCALL(void, $1)()", result)
genTraverseProc(c, s.loc.r, s.loc.t)
let generatedProc = ropef("$1 {$n$2$3$4}$n",
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
m.s[cfsProcHeaders].appf("$1;$n", header)
m.s[cfsProcs].app(generatedProc)

View file

@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2012 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -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 usesNativeGC():
if gSelectedGC >= gcMarkAndSweep:
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

@ -139,10 +139,11 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
case switch.normalize
of "gc":
case arg.normalize
of "boehm": result = gSelectedGC == gcBoehm
of "refc": result = gSelectedGC == gcRefc
of "v2": result = gSelectedGC == gcV2
of "none": result = gSelectedGC == gcNone
of "boehm": result = gSelectedGC == gcBoehm
of "refc": result = gSelectedGC == gcRefc
of "v2": result = gSelectedGC == gcV2
of "markandsweep": result = gSelectedGC == gcMarkAndSweep
of "none": result = gSelectedGC == gcNone
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
of "opt":
case arg.normalize
@ -276,6 +277,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
gSelectedGC = gcRefc
of "v2":
gSelectedGC = gcV2
of "markandsweep":
gSelectedGC = gcMarkAndSweep
defineSymbol("gcmarkandsweep")
of "none":
gSelectedGC = gcNone
defineSymbol("nogc")

View file

@ -80,8 +80,8 @@ 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 #
TGCMode* = enum # the selected GC
gcNone, gcBoehm, gcMarkAndSweep, gcRefc, gcV2
const
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
@ -269,7 +269,6 @@ proc binaryStrSearch*(x: openarray[string], y: string): int =
return mid
result = - 1
# Can we keep this? I'm using it all the time
template nimdbg*: expr = c.module.fileIdx == gProjectMainIdx
template cnimdbg*: expr = p.module.module.fileIdx == gProjectMainIdx
template pnimdbg*: expr = p.lex.fileIdx == gProjectMainIdx