diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 7c07b29952..affbdffd96 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -386,6 +386,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; var istr = rspaces(indent + 2) result = "{$N$1\"kind\": $2" % [istr, makeYamlString($n.kind)] + addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) if maxRecDepth != 0: case n.kind of nkCharLit..nkUInt64Lit: @@ -418,7 +419,6 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int; addf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i], indent + 4, maxRecDepth - 1, renderType)]) addf(result, "$N$1]", [istr]) - addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) addf(result, "$N$1}", [rspaces(indent)]) proc debug(n: PSym) = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 0825127537..0ca8e46fc8 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -184,24 +184,27 @@ proc freshLineInfo(p: BProc; info: TLineInfo): bool = result = true proc genLineDir(p: BProc, t: PNode) = - let info = t.info - #if t.kind in nkCallKinds+{nkStmtListExpr} and t.len > 1: t[1].info - #else: t.info - var line = info.safeLineNm + var tt = t + #while tt.kind in {nkStmtListExpr}+nkCallKinds: + # tt = tt.lastSon + if tt.kind in nkCallKinds and tt.len > 1: + tt = tt.sons[1] + let line = tt.info.safeLineNm + if optEmbedOrigSrc in gGlobalOptions: - add(p.s(cpsStmts), ~"//" & info.sourceLine & rnl) - genCLineDir(p.s(cpsStmts), info.toFullPath, line) + add(p.s(cpsStmts), ~"//" & tt.info.sourceLine & rnl) + genCLineDir(p.s(cpsStmts), tt.info.toFullPath, line) if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and (p.prc == nil or sfPure notin p.prc.flags): - if freshLineInfo(p, info): + if freshLineInfo(p, tt.info): linefmt(p, cpsStmts, "#endb($1, $2);$n", - line.rope, makeCString(toFilename(info))) + line.rope, makeCString(toFilename(tt.info))) elif ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and - (p.prc == nil or sfPure notin p.prc.flags) and info.fileIndex >= 0: - if freshLineInfo(p, info): + (p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex >= 0: + if freshLineInfo(p, tt.info): linefmt(p, cpsStmts, "nimln($1, $2);$n", - line.rope, info.quotedFilename) + line.rope, tt.info.quotedFilename) proc postStmtActions(p: BProc) {.inline.} = add(p.s(cpsStmts), p.module.injectStmt) diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 96ede44fdc..87745f7edf 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -104,6 +104,25 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode = var evalTemplateCounter* = 0 # to prevent endless recursion in templates instantiation +proc wrapInComesFrom*(info: TLineInfo; res: PNode): PNode = + when true: + result = res + result.info = info + if result.kind in {nkStmtList, nkStmtListExpr} and result.len > 0: + result.lastSon.info = info + when false: + # this hack is required to + var x = result + while x.kind == nkStmtListExpr: x = x.lastSon + if x.kind in nkCallKinds: + for i in 1.. 100: @@ -132,5 +151,5 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode = #if ctx.instLines: result.info = n.info for i in countup(0, safeLen(body) - 1): evalTemplateAux(body.sons[i], args, ctx, result) - + result = wrapInComesFrom(n.info, result) dec(evalTemplateCounter) diff --git a/compiler/sem.nim b/compiler/sem.nim index 7524d7388e..755abec5d5 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -369,6 +369,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, result = evalMacroCall(c.module, c.cache, n, nOrig, sym) if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, sym, flags) + result = wrapInComesFrom(nOrig.info, result) popInfoContext() proc forceBool(c: PContext, n: PNode): PNode = diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 0f1138e04b..39d84c0fa0 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -769,7 +769,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of nkCast: var a = getConstExpr(m, n.sons[1]) if a == nil: return - if n.typ.kind in NilableTypes: + if n.typ != nil and n.typ.kind in NilableTypes: # we allow compile-time 'cast' for pointer types: result = a result.typ = n.typ diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 16358b1a8a..a94579339c 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -172,7 +172,9 @@ proc sumGeneric(t: PType): int = inc result of tyGenericInvocation, tyTuple, tyProc: result += ord(t.kind == tyGenericInvocation) - for i in 0 .. create a new worker thread. # Measurements show that 100% and often even 90% is not reached even # if all my cores are busy. - if sysTotal == 0 or procTotal / sysTotal < 0.85: + if sysTotal == 0 or procTotal.float / sysTotal.float < 0.85: result = doCreateThread s.prevSysKernel = sysKernel s.prevSysUser = sysUser diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 3a8e8a1b69..5b0955132b 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -100,7 +100,8 @@ type freeChunksList: PBigChunk # XXX make this a datastructure with O(1) access chunkStarts: IntSet root, deleted, last, freeAvlNodes: PAvlNode - locked: bool # if locked, we cannot free pages. + locked, blockChunkSizeIncrease: bool # if locked, we cannot free pages. + nextChunkSize: int {.deprecated: [TLLChunk: LLChunk, TAvlNode: AvlNode, TMemRegion: MemRegion].} # shared: @@ -275,9 +276,25 @@ proc pageAddr(p: pointer): PChunk {.inline.} = #sysAssert(Contains(allocator.chunkStarts, pageIndex(result))) proc requestOsChunks(a: var MemRegion, size: int): PBigChunk = + if not a.blockChunkSizeIncrease: + a.nextChunkSize = + if a.currMem < 64 * 1024: PageSize*4 + else: a.nextChunkSize*2 + var size = size + + if size > a.nextChunkSize: + result = cast[PBigChunk](osAllocPages(size)) + else: + result = cast[PBigChunk](osTryAllocPages(a.nextChunkSize)) + if result == nil: + result = cast[PBigChunk](osAllocPages(size)) + a.blockChunkSizeIncrease = true + else: + size = a.nextChunkSize + incCurrMem(a, size) inc(a.freeMem, size) - result = cast[PBigChunk](osAllocPages(size)) + sysAssert((cast[ByteAddress](result) and PageMask) == 0, "requestOsChunks 1") #zeroMem(result, size) result.next = nil @@ -432,6 +449,9 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk = splitChunk(a, result, size) else: result = requestOsChunks(a, size) + # if we over allocated split the chunk: + if result.size > size: + splitChunk(a, result, size) result.prevSize = 0 # XXX why is this needed? result.used = true incl(a, a.chunkStarts, pageIndex(result)) diff --git a/tests/errmsgs/tdont_show_system.nim b/tests/errmsgs/tdont_show_system.nim new file mode 100644 index 0000000000..6963a8a3fe --- /dev/null +++ b/tests/errmsgs/tdont_show_system.nim @@ -0,0 +1,13 @@ +discard """ + errormsg: "value of type 'bool' has to be discarded" + line: 13 + file: "tdont_show_system.nim" +""" + +# bug #4308 + +#proc getGameTile: int = +# 1 > 0 + +# bug #4905 subsumes the problem of #4308: +true notin {false} diff --git a/tests/errmsgs/tproper_stacktrace.nim b/tests/errmsgs/tproper_stacktrace.nim new file mode 100644 index 0000000000..57e65fa6fb --- /dev/null +++ b/tests/errmsgs/tproper_stacktrace.nim @@ -0,0 +1,11 @@ +discard """ + outputsub: '''tproper_stacktrace.nim(7) tproper_stacktrace''' + exitcode: 1 +""" + +template fuzzy(x) = + echo x[] != 9 + +var p: ptr int +fuzzy p + diff --git a/tests/misc/tnot.nim b/tests/misc/tnot.nim index 8c75c6bc06..5c268981ef 100644 --- a/tests/misc/tnot.nim +++ b/tests/misc/tnot.nim @@ -1,6 +1,6 @@ discard """ - tfile: "tnot.nim" - tline: 14 + file: "tnot.nim" + line: 14 errormsg: "type mismatch" """ # BUG: following compiles, but should not: diff --git a/tests/system/tdeepcopy.nim b/tests/system/tdeepcopy.nim index 5a582425ab..f7a6e87fa4 100644 --- a/tests/system/tdeepcopy.nim +++ b/tests/system/tdeepcopy.nim @@ -1,6 +1,5 @@ discard """ output: "ok" - disabled: "true" """ import tables, lists diff --git a/tests/system/trealloc.nim b/tests/system/trealloc.nim new file mode 100644 index 0000000000..dc5f712d60 --- /dev/null +++ b/tests/system/trealloc.nim @@ -0,0 +1,21 @@ +discard """ + output: '''success''' +""" + +# bug #4818 + +# Test that this completes without OOM. + +const BUFFER_SIZE = 5000 +var buffer = cast[ptr uint16](alloc(BUFFER_SIZE)) + +var total_size: int64 = 0 +for i in 0 .. 4000: + let size = BUFFER_SIZE * i + #echo "requesting ", size + total_size += size.int64 + buffer = cast[ptr uint16](realloc(buffer, size)) + #echo totalSize, " total: ", getTotalMem(), " occupied: ", getOccupiedMem(), " free: ", getFreeMem() + +dealloc(buffer) +echo "success"