summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-01-31 16:34:39 +0100
committerAraq <rumpf_a@web.de>2013-01-31 16:34:39 +0100
commit2a2b6307578e481b125d5315893044f4dea81039 (patch)
tree08d053d851b185761c542bebc87a874919fb8306
parentd9d98512e043c1bed44da7f81025046def325a26 (diff)
downloadNim-2a2b6307578e481b125d5315893044f4dea81039.tar.gz
cleaner GC switching
-rwxr-xr-xcompiler/ccgexprs.nim10
-rwxr-xr-xcompiler/ccgtypes.nim2
-rwxr-xr-xcompiler/commands.nim28
-rwxr-xr-xcompiler/options.nim12
-rwxr-xr-xdoc/advopt.txt2
-rw-r--r--tests/specials.nim1
-rwxr-xr-xtodo.txt2
7 files changed, 32 insertions, 25 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 20636f122..c6efaa7a0 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -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)
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 5a9427a7b..281b4ee14 100755
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -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)
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 910a8bca5..878d838b6 100755
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -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)
diff --git a/compiler/options.nim b/compiler/options.nim
index 54ebc5486..6381ced41 100755
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -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"
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 52c2c8636..f0816ad5d 100755
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -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
diff --git a/tests/specials.nim b/tests/specials.nim
index 08013ea7d..dd420b4b3 100644
--- a/tests/specials.nim
+++ b/tests/specials.nim
@@ -126,6 +126,7 @@ proc runGcTests(r: var TResults, options: string) =
   test "gctest"
   test "gcleak3"
   test "weakrefs"
+  test "cycleleak"
 
 # ------------------------- threading tests -----------------------------------
 
diff --git a/todo.txt b/todo.txt
index bac951e8b..972a61f4e 100755
--- a/todo.txt
+++ b/todo.txt
@@ -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