diff options
author | Araq <rumpf_a@web.de> | 2011-12-22 15:04:00 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-12-22 15:04:00 +0100 |
commit | cd83cc81aa58922e0a8370ae5928d5b5aaa16f84 (patch) | |
tree | e3abff5b7a2cd46977e8435a4ebbfdde0c19ba07 /lib | |
parent | f19c1c0f6e93a561dc13ef57d136957edeba9ed4 (diff) | |
download | Nim-cd83cc81aa58922e0a8370ae5928d5b5aaa16f84.tar.gz |
code gen can generate code to keep alive stack roots
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/nimbase.h | 8 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 43 | ||||
-rwxr-xr-x | lib/system/alloc.nim | 19 | ||||
-rwxr-xr-x | lib/system/gc.nim | 7 |
4 files changed, 67 insertions, 10 deletions
diff --git a/lib/nimbase.h b/lib/nimbase.h index bc8c3c28c..e2afed8f9 100755 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -16,6 +16,7 @@ __GNUC__ __DMC__ __POCC__ __TINYC__ +__clang__ */ @@ -437,4 +438,11 @@ __declspec(naked) int __fastcall NimXadd(volatile int* pNum, int val) { # define unlikely(x) (x) #endif +#if defined(__GNUC__) || defined(__clang__) +static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } +# define GC_GUARD __attribute__ ((cleanup(GCGuard))) +#else +# define GC_GUARD +#endif + #endif diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 33bb5b5f0..6b6c3861f 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -699,7 +699,7 @@ proc find*(s, sub: string, start: int = 0): int {.noSideEffect, rtl, extern: "nsuFindStr".} = ## Searches for `sub` in `s` starting at position `start`. Searching is ## case-sensitive. If `sub` is not in `s`, -1 is returned. - var a: TSkipTable + var a {.noinit.}: TSkipTable preprocessSub(sub, a) result = findAux(s, sub, start, a) @@ -742,7 +742,7 @@ proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} = proc replace*(s, sub: string, by = ""): string {.noSideEffect, rtl, extern: "nsuReplaceStr".} = ## Replaces `sub` in `s` by the string `by`. - var a: TSkipTable + var a {.noinit.}: TSkipTable result = "" preprocessSub(sub, a) var i = 0 @@ -989,7 +989,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, ## after the decimal point for Nimrod's ``biggestFloat`` type. const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] var - frmtstr: array[0..5, char] + frmtstr {.noinit.}: array[0..5, char] buf: array[0..80, char] frmtstr[0] = '%' frmtstr[1] = '#' @@ -1018,16 +1018,41 @@ proc formatFloat*(f: float, format: TFloatFormat = ffDefault, ## after the decimal point for Nimrod's ``float`` type. result = formatBiggestFloat(f, format, precision) +proc formatSize*(bytes: biggestInt, decimalSep = '.'): string = + ## Rounds and formats `bytes`. Examples: + ## + ## .. code-block:: nimrod + ## + ## formatSize(1'i64 shl 31 + 300'i64) == "4GB" + ## formatSize(4096) == "4KB" + ## + template frmt(a, b, c: expr): expr = + let bs = $b + insertSep($a) & decimalSep & bs.substr(0, 2) & c + let gigabytes = bytes shr 30 + let megabytes = bytes shr 20 + let kilobytes = bytes shr 10 + if gigabytes != 0: + result = frmt(gigabytes, megabytes, "GB") + elif megabytes != 0: + result = frmt(megabytes, kilobytes, "MB") + elif kilobytes != 0: + result = frmt(kilobytes, bytes, "KB") + else: + result = insertSep($bytes) & "B" + {.pop.} when isMainModule: - assert align("abc", 4) == " abc" - assert align("a", 0) == "a" - assert align("1232", 6) == " 1232" + doAssert align("abc", 4) == " abc" + doAssert align("a", 0) == "a" + doAssert align("1232", 6) == " 1232" echo wordWrap(""" this is a long text -- muchlongerthan10chars and here it goes""", 10, false) - assert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" - assert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11" + doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" + doAssert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11" - assert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" + doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" + echo formatSize(1'i64 shl 31 + 300'i64) # == "4,GB" + echo formatSize(1'i64 shl 31) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 6dee145c8..f33d40b0a 100755 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -171,7 +171,7 @@ proc getMaxMem(a: var TMemRegion): int = # Since we update maxPagesCount only when freeing pages, # maxPagesCount may not be up to date. Thus we use the # maximum of these both values here: - return max(a.currMem, a.maxMem) + result = max(a.currMem, a.maxMem) proc llAlloc(a: var TMemRegion, size: int): pointer = # *low-level* alloc for the memory managers data structures. Deallocation @@ -550,6 +550,23 @@ proc isAllocatedPtr(a: TMemRegion, p: pointer): bool = var c = cast[PBigChunk](c) result = p == addr(c.data) and cast[ptr TFreeCell](p).zeroField >% 1 +proc interiorAllocatedPtr(a: TMemRegion, p: pointer): pointer = + if isAccessible(a, p): + var c = pageAddr(p) + if not chunkUnused(c): + if isSmallChunk(c): + var c = cast[PSmallChunk](c) + var offset = (cast[TAddress](p) and (PageSize-1)) -% + smallChunkOverhead() + if c.acc >% offset: + var d = cast[ptr TFreeCell](cast[TAddress](addr(c.data)) +% + offset -% (offset %% c.size)) + if d.zeroField >% 1: result = d + else: + var c = cast[PBigChunk](c) + var d = addr(c.data) + if p >= d and cast[ptr TFreeCell](d).zeroField >% 1: result = d + proc ptrSize(p: pointer): int = var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell)) result = pageAddr(x).size - sizeof(TFreeCell) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index caab22e34..f13015573 100755 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -579,6 +579,13 @@ proc nimKeepAlive(p: PGenericSeq) {.compilerRtl, noinline.} = if isAllocatedPtr(gch.region, c): c.refcount = c.refcount or rcMarked +proc nimGCFrame(p: pointer) {.compilerRtl, noinline.} = + # 'cast' is correct here! no offset to add: + var c = cast[PCell](p) + var x = cast[TAddress](c) + if x <% PageSize and (x and (MemAlign-1)) == 0: + c.refcount = c.refcount or rcMarked + proc markThreadStacks(gch: var TGcHeap) = when hasThreadSupport and hasSharedHeap: {.error: "not fully implemented".} |