diff options
Diffstat (limited to 'compiler/cgen.nim')
-rw-r--r-- | compiler/cgen.nim | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 910e675e1..6ccef5fde 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -72,6 +72,11 @@ proc isSimpleConst(typ: PType): bool = {tyTuple, tyObject, tyArray, tyArrayConstr, tySet, tySequence} and not (t.kind == tyProc and t.callConv == ccClosure) +proc useStringh(m: BModule) = + if not m.includesStringh: + m.includesStringh = true + discard lists.IncludeStr(m.headerFiles, "<string.h>") + proc useHeader(m: BModule, sym: PSym) = if lfHeader in sym.loc.Flags: assert(sym.annex != nil) @@ -284,6 +289,9 @@ proc genLineDir(p: BProc, t: PNode) = linefmt(p, cpsStmts, "nimln($1, $2);$n", line.toRope, t.info.quotedFilename) +proc postStmtActions(p: BProc) {.inline.} = + app(p.s(cpsStmts), p.module.injectStmt) + proc accessThreadLocalVar(p: BProc, s: PSym) proc emulatedThreadVars(): bool {.inline.} @@ -358,19 +366,24 @@ proc resetLoc(p: BProc, loc: var TLoc) = # field, so disabling this should be safe: genObjectInit(p, cpsStmts, loc.t, loc, true) else: + useStringh(p.module) linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", addrLoc(loc), rdLoc(loc)) # XXX: We can be extra clever here and call memset only # on the bytes following the m_type field? genObjectInit(p, cpsStmts, loc.t, loc, true) -proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) = +proc constructLoc(p: BProc, loc: TLoc, isTemp = false) = if not isComplexValueType(skipTypes(loc.t, abstractRange)): - linefmt(p, section, "$1 = 0;$n", rdLoc(loc)) + linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc)) else: - linefmt(p, section, "memset((void*)$1, 0, sizeof($2));$n", - addrLoc(loc), rdLoc(loc)) - genObjectInit(p, section, loc.t, loc, true) + if not isTemp or containsGarbageCollectedRef(loc.t): + # don't use memset for temporary values for performance if we can + # avoid it: + useStringh(p.module) + linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", + addrLoc(loc), rdLoc(loc)) + genObjectInit(p, cpsStmts, loc.t, loc, true) proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = if sfNoInit notin v.flags: @@ -396,7 +409,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) = result.t = getUniqueType(t) result.s = OnStack result.flags = {} - constructLoc(p, result) + constructLoc(p, result, isTemp=true) proc keepAlive(p: BProc, toKeepAlive: TLoc) = when false: @@ -418,6 +431,7 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) = if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)): linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(result), rdLoc(toKeepAlive)) else: + useStringh(p.module) linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)) @@ -933,9 +947,9 @@ proc genMainProc(m: BModule) = const CommonMainBody = "\tsystemDatInit();$n" & + "\tsystemInit();$n" & "$1" & "$2" & - "\tsystemInit();$n" & "$3" & "$4" PosixNimMain = @@ -1108,6 +1122,9 @@ proc newPostInitProc(m: BModule): BProc = # little hack so that unique temporaries are generated: result.labels = 200_000 +proc initProcOptions(m: BModule): TOptions = + if sfSystemModule in m.module.flags: gOptions-{optStackTrace} else: gOptions + proc rawNewModule(module: PSym, filename: string): BModule = new(result) InitLinkedList(result.headerFiles) @@ -1120,7 +1137,7 @@ proc rawNewModule(module: PSym, filename: string): BModule = result.module = module result.typeInfoMarker = initIntSet() result.initProc = newProc(nil, result) - result.initProc.options = gOptions + result.initProc.options = initProcOptions(result) result.preInitProc = newPreInitProc(result) result.postInitProc = newPostInitProc(result) initNodeTable(result.dataCache) @@ -1128,7 +1145,12 @@ proc rawNewModule(module: PSym, filename: string): BModule = result.forwardedProcs = @[] result.typeNodesName = getTempName() result.nimTypesName = getTempName() - result.PreventStackTrace = sfSystemModule in module.flags + # no line tracing for the init sections of the system module so that we + # don't generate a TFrame which can confuse the stack botton initialization: + if sfSystemModule in module.flags: + result.PreventStackTrace = true + excl(result.preInitProc.options, optStackTrace) + excl(result.postInitProc.options, optStackTrace) proc nullify[T](arr: var T) = for i in low(arr)..high(arr): @@ -1141,7 +1163,7 @@ proc resetModule*(m: var BModule) = m.declaredProtos = initIntSet() initIdTable(m.forwTypeCache) m.initProc = newProc(nil, m) - m.initProc.options = gOptions + m.initProc.options = initProcOptions(m) m.preInitProc = newPreInitProc(m) m.postInitProc = newPostInitProc(m) initNodeTable(m.dataCache) @@ -1231,7 +1253,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode = result = n if b == nil or passes.skipCodegen(n): return var m = BModule(b) - m.initProc.options = gOptions + m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) proc finishModule(m: BModule) = @@ -1318,7 +1340,7 @@ proc myClose(b: PPassContext, n: PNode): PNode = if b == nil or passes.skipCodegen(n): return var m = BModule(b) if n != nil: - m.initProc.options = gOptions + m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) # cached modules need to registered too: registerModuleToMain(m.module) |