workaround bug #374441
This commit is contained in:
parent
a74f4ff6af
commit
e90ec5a461
5 changed files with 59 additions and 78 deletions
71
lib/gc.nim
71
lib/gc.nim
|
|
@ -103,9 +103,7 @@ proc extGetCellType(c: pointer): PNimType {.compilerproc.} =
|
||||||
result = usrToCell(c).typ
|
result = usrToCell(c).typ
|
||||||
|
|
||||||
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
|
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
|
||||||
result = int(usrToCell(p).refcount)
|
result = int(usrToCell(p).refcount) shr rcShift
|
||||||
if result > 0: result = result shr rcShift
|
|
||||||
else: result = 0
|
|
||||||
|
|
||||||
proc GC_disable() = inc(recGcLock)
|
proc GC_disable() = inc(recGcLock)
|
||||||
proc GC_enable() =
|
proc GC_enable() =
|
||||||
|
|
@ -488,11 +486,12 @@ proc stackSize(): int {.noinline.} =
|
||||||
result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
|
result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
|
||||||
|
|
||||||
when defined(sparc): # For SPARC architecture.
|
when defined(sparc): # For SPARC architecture.
|
||||||
|
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var
|
var stackTop: array [0..1, pointer]
|
||||||
stackTop: array[0..1, pointer]
|
var b = cast[TAddress](stackBottom)
|
||||||
result = p >= addr(stackTop[0]) and p <= 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.} =
|
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||||
when defined(sparcv9):
|
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.
|
# Generic code for architectures where addresses increase as the stack grows.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var
|
var stackTop: array [0..1, pointer]
|
||||||
stackTop: array[0..1, pointer]
|
var a = cast[TAddress](stackBottom)
|
||||||
result = p <= addr(stackTop[0]) and p >= stackBottom
|
var b = cast[TAddress](addr(stackTop[0]))
|
||||||
|
var x = cast[TAddress](p)
|
||||||
|
result = x >=% a and x <=% b
|
||||||
|
|
||||||
var
|
var
|
||||||
jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
|
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
|
# in a platform independant way
|
||||||
|
|
||||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||||
var
|
var registers: C_JmpBuf
|
||||||
max = stackBottom
|
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
var max = cast[TAddress](stackBottom)
|
||||||
sp: PPointer # Used to traverse the stack and registers assuming
|
var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
|
||||||
# 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))
|
|
||||||
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
||||||
# otherwise sp would be below the registers structure).
|
# otherwise sp would be below the registers structure).
|
||||||
while sp >= max:
|
while sp >=% max:
|
||||||
gcMark(sp^)
|
gcMark(cast[ppointer](sp)^)
|
||||||
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
|
sp = sp -% sizeof(pointer)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Generic code for architectures where addresses decrease as the stack grows.
|
# Generic code for architectures where addresses decrease as the stack grows.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var
|
var stackTop: array [0..1, pointer]
|
||||||
stackTop: array [0..1, pointer]
|
var b = cast[TAddress](stackBottom)
|
||||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
var a = cast[TAddress](addr(stackTop[0]))
|
||||||
|
var x = cast[TAddress](p)
|
||||||
var
|
result = x >=% a and x <=% b
|
||||||
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
|
|
||||||
|
|
||||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||||
var
|
# We use a jmp_buf buffer that is in the C stack.
|
||||||
max = stackBottom
|
# Used to traverse the stack and registers assuming
|
||||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
# that 'setjmp' will save registers in the C stack.
|
||||||
sp: PPointer # Used to traverse the stack and registers assuming
|
var registers: C_JmpBuf
|
||||||
# that 'setjmp' will save registers in the C stack.
|
|
||||||
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||||
sp = cast[ppointer](addr(registers))
|
var max = cast[TAddress](stackBottom)
|
||||||
while sp <= max:
|
var sp = cast[TAddress](addr(registers))
|
||||||
gcMark(sp^)
|
while sp <=% max:
|
||||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
gcMark(cast[ppointer](sp)^)
|
||||||
|
sp = sp +% sizeof(pointer)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# end of non-portable code
|
# end of non-portable code
|
||||||
|
|
|
||||||
|
|
@ -1108,8 +1108,7 @@ procedure genStrConcat(p: BProc; e: PNode; var d: TLoc);
|
||||||
// asgn(s, tmp0);
|
// asgn(s, tmp0);
|
||||||
// }
|
// }
|
||||||
var
|
var
|
||||||
tmp: TLoc;
|
a, tmp: TLoc;
|
||||||
a: array of TLoc;
|
|
||||||
appends, lens: PRope;
|
appends, lens: PRope;
|
||||||
L, i: int;
|
L, i: int;
|
||||||
begin
|
begin
|
||||||
|
|
@ -1118,25 +1117,21 @@ begin
|
||||||
L := 0;
|
L := 0;
|
||||||
appends := nil;
|
appends := nil;
|
||||||
lens := nil;
|
lens := nil;
|
||||||
{@ignore}
|
|
||||||
setLength(a, sonsLen(e)-1);
|
|
||||||
{@emit
|
|
||||||
newSeq(a, sonsLen(e)-1); }
|
|
||||||
for i := 0 to sonsLen(e)-2 do begin
|
for i := 0 to sonsLen(e)-2 do begin
|
||||||
// compute the length expression:
|
// 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
|
if skipVarGenericRange(e.sons[i+1].Typ).kind = tyChar then begin
|
||||||
Inc(L);
|
Inc(L);
|
||||||
useMagic(p.module, 'appendChar');
|
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
|
end
|
||||||
else begin
|
else begin
|
||||||
if e.sons[i+1].kind in [nkStrLit..nkTripleStrLit] then // string literal?
|
if e.sons[i+1].kind in [nkStrLit..nkTripleStrLit] then // string literal?
|
||||||
Inc(L, length(e.sons[i+1].strVal))
|
Inc(L, length(e.sons[i+1].strVal))
|
||||||
else
|
else
|
||||||
appf(lens, '$1->Sup.len + ', [rdLoc(a[i])]);
|
appf(lens, '$1->Sup.len + ', [rdLoc(a)]);
|
||||||
useMagic(p.module, 'appendString');
|
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
|
||||||
end;
|
end;
|
||||||
appf(p.s[cpsStmts], '$1 = rawNewString($2$3);$n',
|
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');
|
// appendChar(s, 'z');
|
||||||
// }
|
// }
|
||||||
var
|
var
|
||||||
a: array of TLoc;
|
a, dest: TLoc;
|
||||||
L, i: int;
|
L, i: int;
|
||||||
appends, lens: PRope;
|
appends, lens: PRope;
|
||||||
begin
|
begin
|
||||||
|
|
@ -1170,32 +1165,28 @@ begin
|
||||||
L := 0;
|
L := 0;
|
||||||
appends := nil;
|
appends := nil;
|
||||||
lens := nil;
|
lens := nil;
|
||||||
{@ignore}
|
initLocExpr(p, e.sons[1], dest);
|
||||||
setLength(a, sonsLen(e)-1);
|
|
||||||
{@emit
|
|
||||||
newSeq(a, sonsLen(e)-1); }
|
|
||||||
expr(p, e.sons[1], a[0]);
|
|
||||||
for i := 0 to sonsLen(e)-3 do begin
|
for i := 0 to sonsLen(e)-3 do begin
|
||||||
// compute the length expression:
|
// 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
|
if skipVarGenericRange(e.sons[i+2].Typ).kind = tyChar then begin
|
||||||
Inc(L);
|
Inc(L);
|
||||||
useMagic(p.module, 'appendChar');
|
useMagic(p.module, 'appendChar');
|
||||||
appf(appends, 'appendChar($1, $2);$n',
|
appf(appends, 'appendChar($1, $2);$n',
|
||||||
[rdLoc(a[0]), rdLoc(a[i+1])])
|
[rdLoc(dest), rdLoc(a)])
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if e.sons[i+2].kind in [nkStrLit..nkTripleStrLit] then // string literal?
|
if e.sons[i+2].kind in [nkStrLit..nkTripleStrLit] then // string literal?
|
||||||
Inc(L, length(e.sons[i+2].strVal))
|
Inc(L, length(e.sons[i+2].strVal))
|
||||||
else
|
else
|
||||||
appf(lens, '$1->Sup.len + ', [rdLoc(a[i+1])]);
|
appf(lens, '$1->Sup.len + ', [rdLoc(a)]);
|
||||||
useMagic(p.module, 'appendString');
|
useMagic(p.module, 'appendString');
|
||||||
appf(appends, 'appendString($1, $2);$n',
|
appf(appends, 'appendString($1, $2);$n',
|
||||||
[rdLoc(a[0]), rdLoc(a[i+1])])
|
[rdLoc(dest), rdLoc(a)])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
appf(p.s[cpsStmts], '$1 = resizeString($1, $2$3);$n',
|
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);
|
app(p.s[cpsStmts], appends);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -1548,8 +1539,7 @@ end;
|
||||||
|
|
||||||
procedure genInOp(p: BProc; e: PNode; var d: TLoc);
|
procedure genInOp(p: BProc; e: PNode; var d: TLoc);
|
||||||
var
|
var
|
||||||
a, b: TLoc;
|
a, b, x, y: TLoc;
|
||||||
c: array of TLoc; // Generate code for the 'in' operator
|
|
||||||
len, i: int;
|
len, i: int;
|
||||||
begin
|
begin
|
||||||
if (e.sons[1].Kind = nkCurly) and fewCmps(e.sons[1]) then 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);
|
initLoc(b, locExpr, e.typ, OnUnknown);
|
||||||
b.r := toRope('('+'');
|
b.r := toRope('('+'');
|
||||||
len := sonsLen(e.sons[1]);
|
len := sonsLen(e.sons[1]);
|
||||||
{@emit c := @[];}
|
|
||||||
for i := 0 to len-1 do begin
|
for i := 0 to len-1 do begin
|
||||||
if e.sons[1].sons[i].Kind = nkRange then 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], x);
|
||||||
InitLocExpr(p, e.sons[1].sons[i].sons[0], c[high(c)-1]);
|
InitLocExpr(p, e.sons[1].sons[i].sons[1], y);
|
||||||
InitLocExpr(p, e.sons[1].sons[i].sons[1], c[high(c)]);
|
|
||||||
appf(b.r, '$1 >= $2 && $1 <= $3',
|
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
|
end
|
||||||
else begin
|
else begin
|
||||||
setLength(c, length(c)+1);
|
InitLocExpr(p, e.sons[1].sons[i], x);
|
||||||
InitLocExpr(p, e.sons[1].sons[i], c[high(c)]);
|
appf(b.r, '$1 == $2', [rdCharLoc(a), rdCharLoc(x)])
|
||||||
appf(b.r, '$1 == $2', [rdCharLoc(a), rdCharLoc(c[high(c)])])
|
|
||||||
end;
|
end;
|
||||||
if i < len - 1 then
|
if i < len - 1 then app(b.r, ' || ')
|
||||||
app(b.r, ' || ')
|
|
||||||
end;
|
end;
|
||||||
app(b.r, ')'+'');
|
app(b.r, ')'+'');
|
||||||
putIntoDest(p, d, e.typ, b.r);
|
putIntoDest(p, d, e.typ, b.r);
|
||||||
|
|
|
||||||
|
|
@ -801,18 +801,18 @@ begin
|
||||||
if optCompileOnly in gGlobalOptions then
|
if optCompileOnly in gGlobalOptions then
|
||||||
result := ropeff(
|
result := ropeff(
|
||||||
'/* Generated by the Nimrod Compiler v$1 */$n' +
|
'/* 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' +
|
'; Generated by the Nimrod Compiler v$1$n' +
|
||||||
'; (c) 2008 Andreas Rumpf$n',
|
'; (c) 2009 Andreas Rumpf$n',
|
||||||
[toRope(versionAsString)])
|
[toRope(versionAsString)])
|
||||||
else
|
else
|
||||||
result := ropeff(
|
result := ropeff(
|
||||||
'/* Generated by the Nimrod Compiler v$1 */$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' +
|
'/* Compiled for: $2, $3, $4 */$n' +
|
||||||
'/* Command for C compiler:$n $5 */$n',
|
'/* Command for C compiler:$n $5 */$n',
|
||||||
'; Generated by the Nimrod Compiler v$1$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' +
|
'; Compiled for: $2, $3, $4$n' +
|
||||||
'; Command for C compiler:$n $5$n',
|
'; Command for C compiler:$n $5$n',
|
||||||
[toRope(versionAsString), toRope(platform.OS[targetOS].name),
|
[toRope(versionAsString), toRope(platform.OS[targetOS].name),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
@if llvm_gcc or gcc:
|
@if llvm_gcc or gcc:
|
||||||
# GCC, LLVM and Visual C++ have a problem to optimize some modules.
|
# GCC, LLVM and Visual C++ have a problem to optimize some modules.
|
||||||
# This is really strange.
|
# This is really strange.
|
||||||
cgen.speed = "-O0"
|
# cgen.speed = "-O0"
|
||||||
@elif vcc:
|
@elif vcc:
|
||||||
cgen.speed = ""
|
# cgen.speed = ""
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -11,6 +11,8 @@ Plan
|
||||||
Bugs
|
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: returning an array does not work --> see md5.nim module
|
||||||
- BUG: if not nodeOfDegree(g, 1) >= 0: inc(counter)
|
- BUG: if not nodeOfDegree(g, 1) >= 0: inc(counter)
|
||||||
- BUG: the parser allows empty object case branches
|
- BUG: the parser allows empty object case branches
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue