summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2009-05-11 17:34:48 +0200
committerAndreas Rumpf <rumpf_a@web.de>2009-05-11 17:34:48 +0200
commite90ec5a461894fe311fa43661ce3900f84496efe (patch)
tree616dc3bd20ba12cc7b3f82e426861188eb5e80db
parenta74f4ff6af34bbc1649cc6c18f36ccf0a26a2508 (diff)
downloadNim-e90ec5a461894fe311fa43661ce3900f84496efe.tar.gz
workaround bug #374441
-rw-r--r--lib/gc.nim71
-rw-r--r--nim/ccgexprs.pas52
-rw-r--r--nim/cgen.pas8
-rw-r--r--rod/nimrod.cfg4
-rw-r--r--todo.txt2
5 files changed, 59 insertions, 78 deletions
diff --git a/lib/gc.nim b/lib/gc.nim
index 1c353b559..f91b8843e 100644
--- a/lib/gc.nim
+++ b/lib/gc.nim
@@ -103,9 +103,7 @@ proc extGetCellType(c: pointer): PNimType {.compilerproc.} =
   result = usrToCell(c).typ
 
 proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
-  result = int(usrToCell(p).refcount)
-  if result > 0: result = result shr rcShift
-  else: result = 0
+  result = int(usrToCell(p).refcount) shr rcShift
 
 proc GC_disable() = inc(recGcLock)
 proc GC_enable() =
@@ -488,11 +486,12 @@ proc stackSize(): int {.noinline.} =
   result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
 
 when defined(sparc): # For SPARC architecture.
-
   proc isOnStack(p: pointer): bool =
-    var
-      stackTop: array[0..1, pointer]
-    result = p >= addr(stackTop[0]) and p <= stackBottom
+    var stackTop: array [0..1, pointer]
+    var b = cast[TAddress](stackBottom)
+    var a = cast[TAddress](addr(stackTop[0]))
+    var x = cast[TAddress](p)
+    result = x >=% a and x <=% b
 
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
     when defined(sparcv9):
@@ -518,11 +517,12 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
   # ---------------------------------------------------------------------------
   # Generic code for architectures where addresses increase as the stack grows.
   # ---------------------------------------------------------------------------
-
   proc isOnStack(p: pointer): bool =
-    var
-      stackTop: array[0..1, pointer]
-    result = p <= addr(stackTop[0]) and p >= stackBottom
+    var stackTop: array [0..1, pointer]
+    var a = cast[TAddress](stackBottom)
+    var b = cast[TAddress](addr(stackTop[0]))
+    var x = cast[TAddress](p)
+    result = x >=% a and x <=% b
 
   var
     jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
@@ -530,45 +530,38 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
       # in a platform independant way
 
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
-    var
-      max = stackBottom
-      registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
-      sp: PPointer        # Used to traverse the stack and registers assuming
-                          # that `setjmp' will save registers in the C stack.
-    if c_setjmp(registers) == 0: # To fill the C stack with registers.
-      sp = cast[ppointer](cast[TAddress](addr(registers)) +%
-             jmpbufSize -% sizeof(pointer))
+    var registers: C_JmpBuf
+    if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
+      var max = cast[TAddress](stackBottom)
+      var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
       # sp will traverse the JMP_BUF as well (jmp_buf size is added,
       # otherwise sp would be below the registers structure).
-      while sp >= max:
-        gcMark(sp^)
-        sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
+      while sp >=% max:
+        gcMark(cast[ppointer](sp)^)
+        sp = sp -% sizeof(pointer)
 
 else:
   # ---------------------------------------------------------------------------
   # Generic code for architectures where addresses decrease as the stack grows.
   # ---------------------------------------------------------------------------
   proc isOnStack(p: pointer): bool =
-    var
-      stackTop: array [0..1, pointer]
-    result = p >= addr(stackTop[0]) and p <= stackBottom
-
-  var
-    jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
-      # a little hack to get the size of a TJmpBuf in the generated C code
-      # in a platform independant way
+    var stackTop: array [0..1, pointer]
+    var b = cast[TAddress](stackBottom)
+    var a = cast[TAddress](addr(stackTop[0]))
+    var x = cast[TAddress](p)
+    result = x >=% a and x <=% b
 
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
-    var
-      max = stackBottom
-      registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
-      sp: PPointer        # Used to traverse the stack and registers assuming
-                          # that 'setjmp' will save registers in the C stack.
+    # We use a jmp_buf buffer that is in the C stack.
+    # Used to traverse the stack and registers assuming
+    # that 'setjmp' will save registers in the C stack.
+    var registers: C_JmpBuf
     if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
-      sp = cast[ppointer](addr(registers))
-      while sp <= max:
-        gcMark(sp^)
-        sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
+      var max = cast[TAddress](stackBottom)
+      var sp = cast[TAddress](addr(registers))
+      while sp <=% max:
+        gcMark(cast[ppointer](sp)^)
+        sp = sp +% sizeof(pointer)
 
 # ----------------------------------------------------------------------------
 # end of non-portable code
diff --git a/nim/ccgexprs.pas b/nim/ccgexprs.pas
index bd0c520d2..0bb7183e4 100644
--- a/nim/ccgexprs.pas
+++ b/nim/ccgexprs.pas
@@ -1108,8 +1108,7 @@ procedure genStrConcat(p: BProc; e: PNode; var d: TLoc);
 //    asgn(s, tmp0);
 //  }
 var
-  tmp: TLoc;
-  a: array of TLoc;
+  a, tmp: TLoc;
   appends, lens: PRope;
   L, i: int;
 begin
@@ -1118,25 +1117,21 @@ begin
   L := 0;
   appends := nil;
   lens := nil;
-{@ignore}
-  setLength(a, sonsLen(e)-1);
-{@emit
-  newSeq(a, sonsLen(e)-1); }
   for i := 0 to sonsLen(e)-2 do begin
     // compute the length expression:
-    initLocExpr(p, e.sons[i+1], a[i]);
+    initLocExpr(p, e.sons[i+1], a);
     if skipVarGenericRange(e.sons[i+1].Typ).kind = tyChar then begin
       Inc(L);
       useMagic(p.module, 'appendChar');
-      appf(appends, 'appendChar($1, $2);$n', [tmp.r, rdLoc(a[i])])
+      appf(appends, 'appendChar($1, $2);$n', [tmp.r, rdLoc(a)])
     end
     else begin
       if e.sons[i+1].kind in [nkStrLit..nkTripleStrLit] then  // string literal?
         Inc(L, length(e.sons[i+1].strVal))
       else
-        appf(lens, '$1->Sup.len + ', [rdLoc(a[i])]);
+        appf(lens, '$1->Sup.len + ', [rdLoc(a)]);
       useMagic(p.module, 'appendString');
-      appf(appends, 'appendString($1, $2);$n', [tmp.r, rdLoc(a[i])])
+      appf(appends, 'appendString($1, $2);$n', [tmp.r, rdLoc(a)])
     end
   end;
   appf(p.s[cpsStmts], '$1 = rawNewString($2$3);$n',
@@ -1161,7 +1156,7 @@ procedure genStrAppend(p: BProc; e: PNode; var d: TLoc);
 //    appendChar(s, 'z');
 //  }
 var
-  a: array of TLoc;
+  a, dest: TLoc;
   L, i: int;
   appends, lens: PRope;
 begin
@@ -1170,32 +1165,28 @@ begin
   L := 0;
   appends := nil;
   lens := nil;
-{@ignore}
-  setLength(a, sonsLen(e)-1);
-{@emit
-  newSeq(a, sonsLen(e)-1); }
-  expr(p, e.sons[1], a[0]);
+  initLocExpr(p, e.sons[1], dest);
   for i := 0 to sonsLen(e)-3 do begin
     // compute the length expression:
-    initLocExpr(p, e.sons[i+2], a[i+1]);
+    initLocExpr(p, e.sons[i+2], a);
     if skipVarGenericRange(e.sons[i+2].Typ).kind = tyChar then begin
       Inc(L);
       useMagic(p.module, 'appendChar');
       appf(appends, 'appendChar($1, $2);$n',
-        [rdLoc(a[0]), rdLoc(a[i+1])])
+        [rdLoc(dest), rdLoc(a)])
     end
     else begin
       if e.sons[i+2].kind in [nkStrLit..nkTripleStrLit] then  // string literal?
         Inc(L, length(e.sons[i+2].strVal))
       else
-        appf(lens, '$1->Sup.len + ', [rdLoc(a[i+1])]);
+        appf(lens, '$1->Sup.len + ', [rdLoc(a)]);
       useMagic(p.module, 'appendString');
       appf(appends, 'appendString($1, $2);$n',
-        [rdLoc(a[0]), rdLoc(a[i+1])])
+        [rdLoc(dest), rdLoc(a)])
     end
   end;
   appf(p.s[cpsStmts], '$1 = resizeString($1, $2$3);$n',
-    [rdLoc(a[0]), lens, toRope(L)]);
+    [rdLoc(dest), lens, toRope(L)]);
   app(p.s[cpsStmts], appends);
 end;
 
@@ -1548,8 +1539,7 @@ end;
 
 procedure genInOp(p: BProc; e: PNode; var d: TLoc);
 var
-  a, b: TLoc;
-  c: array of TLoc;  // Generate code for the 'in' operator
+  a, b, x, y: TLoc;
   len, i: int;
 begin
   if (e.sons[1].Kind = nkCurly) and fewCmps(e.sons[1]) then begin
@@ -1559,22 +1549,18 @@ begin
     initLoc(b, locExpr, e.typ, OnUnknown);
     b.r := toRope('('+'');
     len := sonsLen(e.sons[1]);
-    {@emit c := @[];}
     for i := 0 to len-1 do begin
       if e.sons[1].sons[i].Kind = nkRange then begin
-        setLength(c, length(c)+2);
-        InitLocExpr(p, e.sons[1].sons[i].sons[0], c[high(c)-1]);
-        InitLocExpr(p, e.sons[1].sons[i].sons[1], c[high(c)]);
+        InitLocExpr(p, e.sons[1].sons[i].sons[0], x);
+        InitLocExpr(p, e.sons[1].sons[i].sons[1], y);
         appf(b.r, '$1 >= $2 && $1 <= $3',
-          [rdCharLoc(a), rdCharLoc(c[high(c)-1]), rdCharLoc(c[high(c)])])
+          [rdCharLoc(a), rdCharLoc(x), rdCharLoc(y)])
       end
       else begin
-        setLength(c, length(c)+1);
-        InitLocExpr(p, e.sons[1].sons[i], c[high(c)]);
-        appf(b.r, '$1 == $2', [rdCharLoc(a), rdCharLoc(c[high(c)])])
+        InitLocExpr(p, e.sons[1].sons[i], x);
+        appf(b.r, '$1 == $2', [rdCharLoc(a), rdCharLoc(x)])
       end;
-      if i < len - 1 then
-        app(b.r, ' || ')
+      if i < len - 1 then app(b.r, ' || ')
     end;
     app(b.r, ')'+'');
     putIntoDest(p, d, e.typ, b.r);
diff --git a/nim/cgen.pas b/nim/cgen.pas
index df8431a30..ed12d3d8e 100644
--- a/nim/cgen.pas
+++ b/nim/cgen.pas
@@ -801,18 +801,18 @@ begin
   if optCompileOnly in gGlobalOptions then
     result := ropeff(
       '/* Generated by the Nimrod Compiler v$1 */$n' +
-      '/*   (c) 2008 Andreas Rumpf */$n',
+      '/*   (c) 2009 Andreas Rumpf */$n',
       '; Generated by the Nimrod Compiler v$1$n' +
-      ';   (c) 2008 Andreas Rumpf$n',
+      ';   (c) 2009 Andreas Rumpf$n',
       [toRope(versionAsString)])
   else
     result := ropeff(
       '/* Generated by the Nimrod Compiler v$1 */$n' +
-      '/*   (c) 2008 Andreas Rumpf */$n' +
+      '/*   (c) 2009 Andreas Rumpf */$n' +
       '/* Compiled for: $2, $3, $4 */$n' +
       '/* Command for C compiler:$n   $5 */$n',
       '; Generated by the Nimrod Compiler v$1$n' +
-      ';   (c) 2008 Andreas Rumpf$n' +
+      ';   (c) 2009 Andreas Rumpf$n' +
       '; Compiled for: $2, $3, $4$n' +
       '; Command for C compiler:$n   $5$n',
       [toRope(versionAsString), toRope(platform.OS[targetOS].name),
diff --git a/rod/nimrod.cfg b/rod/nimrod.cfg
index d0293a5dd..51b675525 100644
--- a/rod/nimrod.cfg
+++ b/rod/nimrod.cfg
@@ -5,7 +5,7 @@
 @if llvm_gcc or gcc:
   # GCC, LLVM and Visual C++ have a problem to optimize some modules.
   # This is really strange.
-  cgen.speed = "-O0"
+  # cgen.speed = "-O0"
 @elif vcc:
-  cgen.speed = ""
+  # cgen.speed = ""
 @end
diff --git a/todo.txt b/todo.txt
index 66c4762f6..0e80d4e49 100644
--- a/todo.txt
+++ b/todo.txt
@@ -11,6 +11,8 @@ Plan
 Bugs
 ----
 
+- BUG: seq[TLoc] in C code generator always failed --> probably some reference
+  counting is wrong; try to reproduce this in the GC test
 - BUG: returning an array does not work --> see md5.nim module
 - BUG: if not nodeOfDegree(g, 1) >= 0: inc(counter)
 - BUG: the parser allows empty object case branches