diff options
-rwxr-xr-x | compiler/cgen.nim | 11 | ||||
-rwxr-xr-x | lib/system/gc.nim | 2 | ||||
-rw-r--r-- | tests/gc/gcleak4.nim | 13 | ||||
-rwxr-xr-x | todo.txt | 3 |
4 files changed, 20 insertions, 9 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 9044b8f26..e437cbb66 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -792,11 +792,11 @@ proc getFileHeader(cfilenoext: string): PRope = proc genMainProc(m: BModule) = const CommonMainBody = - "#initStackBottom();$n" & + "$1" & "\tnim__datInit();$n" & "\tsystemInit();$n" & - "$1" & - "$2" + "$2" & + "$3" PosixNimMain = "int cmdCount;$n" & "char** cmdLine;$n" & @@ -845,8 +845,11 @@ proc genMainProc(m: BModule) = nimMain = PosixNimMain otherMain = PosixCMain if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint") + + let initStackBottomCall = if emulatedThreadVars(): "".toRope + else: ropecg(m, "\t#initStackBottom();$n") inc(m.labels) - appcg(m, m.s[cfsProcs], nimMain, [ + appcg(m, m.s[cfsProcs], nimMain, [initStackBottomCall, gBreakpoints, mainModInit, toRope(m.labels)]) if optNoMain notin gGlobalOptions: appcg(m, m.s[cfsProcs], otherMain, []) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index d2f756cd7..1c6caeb77 100755 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -632,6 +632,7 @@ else: const stackIncreases = false when not defined(useNimRtl): + {.push stack_trace: off.} proc setStackBottom(theStackBottom: pointer) = #c_fprintf(c_stdout, "stack bottom: %p;\n", theStackBottom) # the first init must be the one that defines the stack bottom: @@ -644,6 +645,7 @@ when not defined(useNimRtl): gch.stackBottom = cast[pointer](min(a, b)) else: gch.stackBottom = cast[pointer](max(a, b)) + {.pop.} proc stackSize(): int {.noinline.} = var stackTop {.volatile.}: pointer diff --git a/tests/gc/gcleak4.nim b/tests/gc/gcleak4.nim index 13a82c7f4..bd7bded28 100644 --- a/tests/gc/gcleak4.nim +++ b/tests/gc/gcleak4.nim @@ -10,8 +10,10 @@ type PLiteral = ref TLiteral TLiteral = object of TExpr x: int + op1: string TPlusExpr = object of TExpr a, b: ref TExpr + op2: string method eval(e: ref TExpr): int = # override this base method @@ -27,16 +29,21 @@ proc newLit(x: int): ref TLiteral = new(result) {.watchpoint: result.} result.x = x + result.op1 = $getOccupiedMem() proc newPlus(a, b: ref TExpr): ref TPlusExpr = new(result) {.watchpoint: result.} result.a = a result.b = b + result.op2 = $getOccupiedMem() for i in 0..100_000: - if eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) != 7: - quit "error: wrong result" - if getOccupiedMem() > 3000_000: quit("still a leak!") + var s: array[0..11, ref TExpr] + for j in 0..high(s): + s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4)) + if eval(s[j]) != j+6: + quit "error: wrong result" + if getOccupiedMem() > 500_000: quit("still a leak!") echo "no leak: ", getOccupiedMem() diff --git a/todo.txt b/todo.txt index d3b485782..9b9755664 100755 --- a/todo.txt +++ b/todo.txt @@ -2,8 +2,6 @@ version 0.9.0 ============= Debug GC session: -- bug: stress testing basic method example (eval example) - without ``-d:release`` leaks memory? - test sequence of closures; especially that the GC does not leak for those! New pragmas: @@ -14,6 +12,7 @@ New pragmas: - make templates hygienic by default: try to gensym() everything in the 'block' of a template; find a better solution for gensym instead of `*ident` - ``=`` should be overloadable; requires specialization for ``=`` +- optimize genericAssign in the code generator - fix remaining closure bugs: - make toplevel but in a scope vars local; make procs there inner procs - fix evals.nim with closures |