From 15734009ca9077cfc8c4139b8258b2db2d7492dd Mon Sep 17 00:00:00 2001 From: Reimer Behrends Date: Wed, 23 Jul 2014 03:20:50 +0200 Subject: More robust implementation for finding the beginning of the stack. This patch inserts an extra stack frame above the function that calls the actual Nimrod code and ensures that a reference to this frame is stored as the stack bottom. --- compiler/cgen.nim | 25 +++++++++++++++++-------- lib/system.nim | 6 ++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index e2f3b5ab0..d7a9d3c9d 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -954,8 +954,7 @@ proc genMainProc(m: BModule) = "\tsystemInit();$N" & "$1" & "$2" & - "$3" & - "$4" + "$3" MainProcs = "\tNimMain();$N" @@ -963,10 +962,19 @@ proc genMainProc(m: BModule) = MainProcsWithResult = MainProcs & "\treturn nim_program_result;$N" + # The use of a volatile function pointer to call NimMainInner + # prevents inlining of the NimMainInner function and dependent + # functions, which might otherwise merge their stack frames. NimMainBody = - "N_CDECL(void, NimMain)(void) {$N" & + "N_CDECL(void, NimMainInner)(void) {$N" & "\tPreMain();$N" & "$1" & + "}$N$N" & + "N_CDECL(void, NimMain)(void) {$N" & + "\tvoid (*volatile inner)();$N" & + "\tinner = NimMainInner;$N" & + "$2" & + "\t(*inner)();$N" & "}$N$N" PosixNimMain = @@ -1034,14 +1042,15 @@ proc genMainProc(m: BModule) = if optEndb in gOptions: gBreakpoints.app(m.genFilenames) - let initStackBottomCall = if emulatedThreadVars() or - platform.targetOS == osStandalone: "".toRope - else: ropecg(m, "\t#initStackBottom();$N") + let initStackBottomCall = + if emulatedThreadVars() or + platform.targetOS == osStandalone: "".toRope + else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") inc(m.labels) appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N$N", [ - mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit]) + mainDatInit, gBreakpoints, otherModsInit]) - appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)]) + appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)]) if optNoMain notin gGlobalOptions: appcg(m, m.s[cfsProcs], otherMain, []) diff --git a/lib/system.nim b/lib/system.nim index 753205777..361e94462 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2115,6 +2115,12 @@ when not defined(JS): #and not defined(NimrodVM): locals = addr(locals) setStackBottom(locals) + proc initStackBottomWith(locals: pointer) {.inline, compilerproc.} = + # We need to keep initStackBottom around for now to avoid + # bootstrapping problems. + when defined(setStackBottom): + setStackBottom(locals) + var strDesc: TNimType -- cgit 1.4.1-2-gfad0 h=devel&id=fc47c0edc76d1d8460fa0d1b384b97b7f2c92934'>plain) (tree)
1
2
3
4
5
6
7
8
9
10