mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 19:52:36 +00:00
unsuccessful phantom bug hunting
This commit is contained in:
@@ -319,8 +319,14 @@ proc genStringCase(p: BProc, t: PNode) =
|
||||
# but we reserved a label, which we use later
|
||||
appcg(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
|
||||
[rdLoc(a), toRope(bitMask)])
|
||||
for j in countup(0, high(branches)):
|
||||
if branches[j] != nil:
|
||||
for j in countup(0, high(branches)):
|
||||
when false:
|
||||
let interior = cast[int](interiorAllocatedPtr(addr(branches[0])))+
|
||||
2*sizeof(pointer)
|
||||
let brn = cast[int](cast[pointer](branches))
|
||||
if interior != brn:
|
||||
echo "BUG! ", interior, "-", brn
|
||||
if branches[j] != nil:
|
||||
appf(p.s[cpsStmts], "case $1: $n$2break;$n",
|
||||
[intLiteral(j), branches[j]])
|
||||
appf(p.s[cpsStmts], "}$n") # else statement:
|
||||
|
||||
@@ -808,9 +808,34 @@ when hasThreadSupport:
|
||||
else:
|
||||
{.pragma: rtlThreadVar.}
|
||||
|
||||
const
|
||||
QuitSuccess* = 0
|
||||
## is the value that should be passed to ``quit`` to indicate
|
||||
## success.
|
||||
|
||||
QuitFailure* = 1
|
||||
## is the value that should be passed to ``quit`` to indicate
|
||||
## failure.
|
||||
|
||||
var program_result* {.exportc: "nim_$1".} = QuitSuccess
|
||||
## modify this varialbe to specify the exit code of the program
|
||||
## under normal circumstances. when the program is terminated
|
||||
## prematurelly using ``quit``, this value is ignored.
|
||||
|
||||
proc quit*(errorcode: int = QuitSuccess) {.
|
||||
magic: "Exit", importc: "exit", noDecl, noReturn.}
|
||||
## stops the program immediately; before stopping the program the
|
||||
## "quit procedures" are called in the opposite order they were added
|
||||
## with ``addQuitProc``. ``quit`` never returns and ignores any
|
||||
## exception that may have been raised by the quit procedures.
|
||||
## It does *not* call the garbage collector to free all the memory,
|
||||
## unless a quit procedure calls ``GC_collect``.
|
||||
|
||||
template sysAssert(cond, msg: expr) =
|
||||
# change this to activate system asserts
|
||||
#if not cond: echo "[SYSASSERT] ", msg
|
||||
#if not cond:
|
||||
# echo "[SYSASSERT] ", msg
|
||||
# quit 1
|
||||
nil
|
||||
|
||||
include "system/inclrtl"
|
||||
@@ -1530,29 +1555,6 @@ template newException*(exceptn, message: expr): expr =
|
||||
e.msg = message
|
||||
e
|
||||
|
||||
const
|
||||
QuitSuccess* = 0
|
||||
## is the value that should be passed to ``quit`` to indicate
|
||||
## success.
|
||||
|
||||
QuitFailure* = 1
|
||||
## is the value that should be passed to ``quit`` to indicate
|
||||
## failure.
|
||||
|
||||
var program_result* {.exportc: "nim_$1".} = QuitSuccess
|
||||
## modify this varialbe to specify the exit code of the program
|
||||
## under normal circumstances. when the program is terminated
|
||||
## prematurelly using ``quit``, this value is ignored.
|
||||
|
||||
proc quit*(errorcode: int = QuitSuccess) {.
|
||||
magic: "Exit", importc: "exit", noDecl, noReturn.}
|
||||
## stops the program immediately; before stopping the program the
|
||||
## "quit procedures" are called in the opposite order they were added
|
||||
## with ``addQuitProc``. ``quit`` never returns and ignores any
|
||||
## exception that may have been raised by the quit procedures.
|
||||
## It does *not* call the garbage collector to free all the memory,
|
||||
## unless a quit procedure calls ``GC_collect``.
|
||||
|
||||
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||
{.push stack_trace: off.}
|
||||
|
||||
|
||||
@@ -479,14 +479,6 @@ proc getSmallChunk(a: var TMemRegion): PSmallChunk =
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
proc getCellSize(p: pointer): int {.inline.} =
|
||||
var c = pageAddr(p)
|
||||
result = c.size
|
||||
|
||||
proc memSize(a: TMemRegion, p: pointer): int {.inline.} =
|
||||
var c = pageAddr(p)
|
||||
result = c.size
|
||||
|
||||
proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
|
||||
sysAssert(roundup(65, 8) == 72, "rawAlloc 1")
|
||||
sysAssert requestedSize >= sizeof(TFreeCell), "rawAlloc 2"
|
||||
@@ -526,6 +518,8 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
|
||||
sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9")
|
||||
if c.free < size:
|
||||
ListRemove(a.freeSmallChunks[s], c)
|
||||
sysAssert(((cast[TAddress](result) and PageMask) -% smallChunkOverhead()) %%
|
||||
size == 0, "rawAlloc 21")
|
||||
else:
|
||||
size = roundup(requestedSize+bigChunkOverhead(), PageSize)
|
||||
# allocate a large block
|
||||
@@ -549,6 +543,8 @@ proc rawDealloc(a: var TMemRegion, p: pointer) =
|
||||
# `p` is within a small chunk:
|
||||
var c = cast[PSmallChunk](c)
|
||||
var s = c.size
|
||||
sysAssert(((cast[TAddress](p) and PageMask) -% smallChunkOverhead()) %%
|
||||
s == 0, "rawDealloc 3")
|
||||
var f = cast[ptr TFreeCell](p)
|
||||
#echo("setting to nil: ", $cast[TAddress](addr(f.zeroField)))
|
||||
sysAssert(f.zeroField != 0, "rawDealloc 1")
|
||||
@@ -570,6 +566,8 @@ proc rawDealloc(a: var TMemRegion, p: pointer) =
|
||||
ListRemove(a.freeSmallChunks[s div memAlign], c)
|
||||
c.size = SmallChunkSize
|
||||
freeBigChunk(a, cast[PBigChunk](c))
|
||||
sysAssert(((cast[TAddress](p) and PageMask) -% smallChunkOverhead()) %%
|
||||
s == 0, "rawDealloc 2")
|
||||
else:
|
||||
# set to 0xff to check for usage after free bugs:
|
||||
when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead())
|
||||
@@ -687,6 +685,9 @@ template InstantiateForRegion(allocator: expr) =
|
||||
proc interiorAllocatedPtr*(p: pointer): pointer =
|
||||
result = interiorAllocatedPtr(allocator, p)
|
||||
|
||||
proc isAllocatedPtr*(p: pointer): bool =
|
||||
result = isAllocatedPtr(allocator, p)
|
||||
|
||||
proc deallocOsPages = deallocOsPages(allocator)
|
||||
|
||||
proc alloc(size: int): pointer =
|
||||
|
||||
Reference in New Issue
Block a user