bugfixes for .rod files and visual C++

This commit is contained in:
Araq 2011-12-03 17:21:35 +01:00
commit c8d270268a
13 changed files with 135 additions and 130 deletions

View file

@ -73,7 +73,7 @@ proc CompileModule(filename: string, flags: TSymFlags): PSym =
var f = addFileExt(filename, nimExt) var f = addFileExt(filename, nimExt)
result = newModule(filename) result = newModule(filename)
result.flags = result.flags + flags result.flags = result.flags + flags
if gCmd in {cmdCompileToC, cmdCompileToCpp}: if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCheck, cmdIdeTools}:
rd = handleSymbolFile(result, f) rd = handleSymbolFile(result, f)
if result.id < 0: if result.id < 0:
InternalError("handleSymbolFile should have set the module\'s ID") InternalError("handleSymbolFile should have set the module\'s ID")

View file

@ -643,6 +643,10 @@ proc startsWith(buf: cstring, token: string, pos = 0): bool =
proc newRodReader(modfilename: string, crc: TCrc32, proc newRodReader(modfilename: string, crc: TCrc32,
readerIndex: int): PRodReader = readerIndex: int): PRodReader =
new(result) new(result)
try:
result.memFile = memfiles.open(modfilename)
except EOS:
return nil
result.files = @[] result.files = @[]
result.modDeps = @[] result.modDeps = @[]
result.methods = @[] result.methods = @[]
@ -653,10 +657,6 @@ proc newRodReader(modfilename: string, crc: TCrc32,
r.readerIndex = readerIndex r.readerIndex = readerIndex
r.filename = modfilename r.filename = modfilename
InitIdTable(r.syms) InitIdTable(r.syms)
try:
r.memFile = memfiles.open(modfilename)
except EOS:
return nil
# we terminate the file explicitely with ``\0``, so the cast to `cstring` # we terminate the file explicitely with ``\0``, so the cast to `cstring`
# is safe: # is safe:
r.s = cast[cstring](r.memFile.mem) r.s = cast[cstring](r.memFile.mem)
@ -793,6 +793,7 @@ proc getModuleIdx(filename: string): int =
setlen(gMods, result + 1) setlen(gMods, result + 1)
proc checkDep(filename: string): TReasonForRecompile = proc checkDep(filename: string): TReasonForRecompile =
assert(not isNil(filename))
var idx = getModuleIdx(filename) var idx = getModuleIdx(filename)
if gMods[idx].reason != rrEmpty: if gMods[idx].reason != rrEmpty:
# reason has already been computed for this module: # reason has already been computed for this module:
@ -804,30 +805,28 @@ proc checkDep(filename: string): TReasonForRecompile =
result = rrNone result = rrNone
var r: PRodReader = nil var r: PRodReader = nil
var rodfile = toGeneratedFile(filename, RodExt) var rodfile = toGeneratedFile(filename, RodExt)
if ExistsFile(rodfile): r = newRodReader(rodfile, crc, idx)
r = newRodReader(rodfile, crc, idx) if r == nil:
if r == nil: result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
result = rrRodInvalid
else:
result = r.reason
if result == rrNone:
# check modules it depends on
# NOTE: we need to process the entire module graph so that no ID will
# be used twice! However, compilation speed does not suffer much from
# this, since results are cached.
var res = checkDep(options.libpath / addFileExt("system", nimExt))
if res != rrNone: result = rrModDeps
for i in countup(0, high(r.modDeps)):
res = checkDep(r.modDeps[i])
if res != rrNone:
result = rrModDeps
# we cannot break here, because of side-effects of `checkDep`
else: else:
result = rrRodDoesNotExist result = r.reason
if result == rrNone:
# check modules it depends on
# NOTE: we need to process the entire module graph so that no ID will
# be used twice! However, compilation speed does not suffer much from
# this, since results are cached.
var res = checkDep(options.libpath / addFileExt("system", nimExt))
if res != rrNone: result = rrModDeps
for i in countup(0, high(r.modDeps)):
res = checkDep(r.modDeps[i])
if res != rrNone:
result = rrModDeps
# we cannot break here, because of side-effects of `checkDep`
if result != rrNone and gVerbosity > 0: if result != rrNone and gVerbosity > 0:
rawMessage(hintProcessing, reasonToFrmt[result] % filename) rawMessage(hintProcessing, reasonToFrmt[result] % filename)
if result != rrNone or optForceFullMake in gGlobalOptions: if result != rrNone or optForceFullMake in gGlobalOptions:
# recompilation is necessary: # recompilation is necessary:
if r != nil: memfiles.close(r.memFile)
r = nil r = nil
gMods[idx].rd = r gMods[idx].rd = r
gMods[idx].reason = result # now we know better gMods[idx].reason = result # now we know better
@ -853,8 +852,12 @@ proc handleSymbolFile(module: PSym, filename: string): PRodReader =
module.id = getID() module.id = getID()
proc GetCRC*(filename: string): TCrc32 = proc GetCRC*(filename: string): TCrc32 =
var idx = getModuleIdx(filename) for i in countup(0, high(gMods)):
result = gMods[idx].crc if sameFile(gMods[i].filename, filename): return gMods[i].crc
result = crcFromFile(filename)
#var idx = getModuleIdx(filename)
#result = gMods[idx].crc
proc rawLoadStub(s: PSym) = proc rawLoadStub(s: PSym) =
if s.kind != skStub: InternalError("loadStub") if s.kind != skStub: InternalError("loadStub")

View file

@ -423,6 +423,7 @@ proc writeRod(w: PRodWriter) =
var f: TFile var f: TFile
if not open(f, completeGeneratedFilePath(changeFileExt(w.filename, "rod")), if not open(f, completeGeneratedFilePath(changeFileExt(w.filename, "rod")),
fmWrite): fmWrite):
#echo "couldn't write rod file for: ", w.filename
return return
# write header: # write header:
f.write("NIM:") f.write("NIM:")

View file

@ -72,7 +72,7 @@ icc.options.linker = "-cxxlib"
# Configuration for the GNU C/C++ compiler: # Configuration for the GNU C/C++ compiler:
@if windows: @if windows:
gcc.path = r"$nimrod\dist\mingw\bin" #gcc.path = r"$nimrod\dist\mingw\bin"
@end @end
gcc.options.debug = "-g3 -O0" gcc.options.debug = "-g3 -O0"

View file

@ -79,10 +79,10 @@ __TINYC__
/* --------------- how int64 constants should be declared: ----------- */ /* --------------- how int64 constants should be declared: ----------- */
#if defined(__GNUC__) || defined(__LCC__) || \ #if defined(__GNUC__) || defined(__LCC__) || \
defined(__POCC__) || defined(__DMC__) defined(__POCC__) || defined(__DMC__) || defined(_MSC_VER)
# define IL64(x) x##LL # define IL64(x) x##LL
#else /* works only without LL */ #else /* works only without LL */
# define IL64(x) x # define IL64(x) ((NI64)x)
#endif #endif
/* ---------------- casting without correct aliasing rules ----------- */ /* ---------------- casting without correct aliasing rules ----------- */

View file

@ -47,9 +47,9 @@ elif defined(windows):
when defined(vcc): when defined(vcc):
# newest version of Visual C++ defines time_t to be of 64 bits # newest version of Visual C++ defines time_t to be of 64 bits
type TTimeImpl {.importc: "time_t", header: "<sys/time.h>".} = int64 type TTimeImpl {.importc: "time_t", header: "<time.h>".} = int64
else: else:
type TTimeImpl {.importc: "time_t", header: "<sys/time.h>".} = int32 type TTimeImpl {.importc: "time_t", header: "<time.h>".} = int32
type type
TTime* = distinct TTimeImpl TTime* = distinct TTimeImpl

View file

@ -808,8 +808,9 @@ when hasThreadSupport:
else: else:
{.pragma: rtlThreadVar.} {.pragma: rtlThreadVar.}
template sysAssert(cond: expr) = template sysAssert(cond, msg: expr) =
# change this to activate system asserts # change this to activate system asserts
#if not cond: echo msg
nil nil
include "system/inclrtl" include "system/inclrtl"
@ -1821,14 +1822,14 @@ when not defined(EcmaScript) and not defined(NimrodVM):
proc reprAny(p: pointer, typ: PNimType): string {.compilerRtl.} proc reprAny(p: pointer, typ: PNimType): string {.compilerRtl.}
proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int = proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int =
sysAssert(n.kind == nkCase) sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase")
var d: int var d: int
var a = cast[TAddress](aa) var a = cast[TAddress](aa)
case n.typ.size case n.typ.size
of 1: d = ze(cast[ptr int8](a +% n.offset)[]) of 1: d = ze(cast[ptr int8](a +% n.offset)[])
of 2: d = ze(cast[ptr int16](a +% n.offset)[]) of 2: d = ze(cast[ptr int16](a +% n.offset)[])
of 4: d = int(cast[ptr int32](a +% n.offset)[]) of 4: d = int(cast[ptr int32](a +% n.offset)[])
else: sysAssert(false) else: sysAssert(false, "getDiscriminant: invalid n.typ.size")
return d return d
proc selectBranch(aa: Pointer, n: ptr TNimNode): ptr TNimNode = proc selectBranch(aa: Pointer, n: ptr TNimNode): ptr TNimNode =

View file

@ -131,12 +131,12 @@ template bigChunkOverhead(): expr = sizeof(TBigChunk)-sizeof(TAlignType)
proc roundup(x, v: int): int {.inline.} = proc roundup(x, v: int): int {.inline.} =
result = (x + (v-1)) and not (v-1) result = (x + (v-1)) and not (v-1)
sysAssert(result >= x) sysAssert(result >= x, "roundup: result < x")
#return ((-x) and (v-1)) +% x #return ((-x) and (v-1)) +% x
sysAssert(roundup(14, PageSize) == PageSize) sysAssert(roundup(14, PageSize) == PageSize, "invalid PageSize")
sysAssert(roundup(15, 8) == 16) sysAssert(roundup(15, 8) == 16, "roundup broken")
sysAssert(roundup(65, 8) == 72) sysAssert(roundup(65, 8) == 72, "roundup broken 2")
# ------------- chunk table --------------------------------------------------- # ------------- chunk table ---------------------------------------------------
# We use a PtrSet of chunk starts and a table[Page, chunksize] for chunk # We use a PtrSet of chunk starts and a table[Page, chunksize] for chunk
@ -180,7 +180,7 @@ proc llAlloc(a: var TMemRegion, size: int): pointer =
# the requested size is ``roundup(size+sizeof(TLLChunk), PageSize)``, but # the requested size is ``roundup(size+sizeof(TLLChunk), PageSize)``, but
# since we know ``size`` is a (small) constant, we know the requested size # since we know ``size`` is a (small) constant, we know the requested size
# is one page: # is one page:
sysAssert roundup(size+sizeof(TLLChunk), PageSize) == PageSize sysAssert roundup(size+sizeof(TLLChunk), PageSize) == PageSize, "roundup 6"
var old = a.llmem # can be nil and is correct with nil var old = a.llmem # can be nil and is correct with nil
a.llmem = cast[PLLChunk](osAllocPages(PageSize)) a.llmem = cast[PLLChunk](osAllocPages(PageSize))
incCurrMem(a, PageSize) incCurrMem(a, PageSize)
@ -268,7 +268,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk =
incCurrMem(a, size) incCurrMem(a, size)
inc(a.freeMem, size) inc(a.freeMem, size)
result = cast[PBigChunk](osAllocPages(size)) result = cast[PBigChunk](osAllocPages(size))
sysAssert((cast[TAddress](result) and PageMask) == 0) sysAssert((cast[TAddress](result) and PageMask) == 0, "requestOsChunks 1")
#zeroMem(result, size) #zeroMem(result, size)
result.next = nil result.next = nil
result.prev = nil result.prev = nil
@ -276,7 +276,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk =
result.size = size result.size = size
# update next.prevSize: # update next.prevSize:
var nxt = cast[TAddress](result) +% size var nxt = cast[TAddress](result) +% size
sysAssert((nxt and PageMask) == 0) sysAssert((nxt and PageMask) == 0, "requestOsChunks 2")
var next = cast[PChunk](nxt) var next = cast[PChunk](nxt)
if pageIndex(next) in a.chunkStarts: if pageIndex(next) in a.chunkStarts:
#echo("Next already allocated!") #echo("Next already allocated!")
@ -284,7 +284,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk =
# set result.prevSize: # set result.prevSize:
var lastSize = if a.lastSize != 0: a.lastSize else: PageSize var lastSize = if a.lastSize != 0: a.lastSize else: PageSize
var prv = cast[TAddress](result) -% lastSize var prv = cast[TAddress](result) -% lastSize
sysAssert((nxt and PageMask) == 0) sysAssert((nxt and PageMask) == 0, "requestOsChunks 3")
var prev = cast[PChunk](prv) var prev = cast[PChunk](prv)
if pageIndex(prev) in a.chunkStarts and prev.size == lastSize: if pageIndex(prev) in a.chunkStarts and prev.size == lastSize:
#echo("Prev already allocated!") #echo("Prev already allocated!")
@ -297,7 +297,7 @@ proc freeOsChunks(a: var TMemRegion, p: pointer, size: int) =
# update next.prevSize: # update next.prevSize:
var c = cast[PChunk](p) var c = cast[PChunk](p)
var nxt = cast[TAddress](p) +% c.size var nxt = cast[TAddress](p) +% c.size
sysAssert((nxt and PageMask) == 0) sysAssert((nxt and PageMask) == 0, "freeOsChunks")
var next = cast[PChunk](nxt) var next = cast[PChunk](nxt)
if pageIndex(next) in a.chunkStarts: if pageIndex(next) in a.chunkStarts:
next.prevSize = 0 # XXX used next.prevSize = 0 # XXX used
@ -325,23 +325,23 @@ proc writeFreeList(a: TMemRegion) =
it = it.next it = it.next
proc ListAdd[T](head: var T, c: T) {.inline.} = proc ListAdd[T](head: var T, c: T) {.inline.} =
sysAssert(c notin head) sysAssert(c notin head, "listAdd 1")
sysAssert c.prev == nil sysAssert c.prev == nil, "listAdd 2"
sysAssert c.next == nil sysAssert c.next == nil, "listAdd 3"
c.next = head c.next = head
if head != nil: if head != nil:
sysAssert head.prev == nil sysAssert head.prev == nil, "listAdd 4"
head.prev = c head.prev = c
head = c head = c
proc ListRemove[T](head: var T, c: T) {.inline.} = proc ListRemove[T](head: var T, c: T) {.inline.} =
sysAssert(c in head) sysAssert(c in head, "listRemove")
if c == head: if c == head:
head = c.next head = c.next
sysAssert c.prev == nil sysAssert c.prev == nil, "listRemove 2"
if head != nil: head.prev = nil if head != nil: head.prev = nil
else: else:
sysAssert c.prev != nil sysAssert c.prev != nil, "listRemove 3"
c.prev.next = c.next c.prev.next = c.next
if c.next != nil: c.next.prev = c.prev if c.next != nil: c.next.prev = c.prev
c.next = nil c.next = nil
@ -356,19 +356,19 @@ proc chunkUnused(c: PChunk): bool {.inline.} =
proc updatePrevSize(a: var TMemRegion, c: PBigChunk, proc updatePrevSize(a: var TMemRegion, c: PBigChunk,
prevSize: int) {.inline.} = prevSize: int) {.inline.} =
var ri = cast[PChunk](cast[TAddress](c) +% c.size) var ri = cast[PChunk](cast[TAddress](c) +% c.size)
sysAssert((cast[TAddress](ri) and PageMask) == 0) sysAssert((cast[TAddress](ri) and PageMask) == 0, "updatePrevSize")
if isAccessible(a, ri): if isAccessible(a, ri):
ri.prevSize = prevSize ri.prevSize = prevSize
proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = proc freeBigChunk(a: var TMemRegion, c: PBigChunk) =
var c = c var c = c
sysAssert(c.size >= PageSize) sysAssert(c.size >= PageSize, "freeBigChunk")
inc(a.freeMem, c.size) inc(a.freeMem, c.size)
when coalescRight: when coalescRight:
var ri = cast[PChunk](cast[TAddress](c) +% c.size) var ri = cast[PChunk](cast[TAddress](c) +% c.size)
sysAssert((cast[TAddress](ri) and PageMask) == 0) sysAssert((cast[TAddress](ri) and PageMask) == 0, "freeBigChunk 2")
if isAccessible(a, ri) and chunkUnused(ri): if isAccessible(a, ri) and chunkUnused(ri):
sysAssert(not isSmallChunk(ri)) sysAssert(not isSmallChunk(ri), "freeBigChunk 3")
if not isSmallChunk(ri): if not isSmallChunk(ri):
ListRemove(a.freeChunksList, cast[PBigChunk](ri)) ListRemove(a.freeChunksList, cast[PBigChunk](ri))
inc(c.size, ri.size) inc(c.size, ri.size)
@ -376,9 +376,9 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) =
when coalescLeft: when coalescLeft:
if c.prevSize != 0: if c.prevSize != 0:
var le = cast[PChunk](cast[TAddress](c) -% c.prevSize) var le = cast[PChunk](cast[TAddress](c) -% c.prevSize)
sysAssert((cast[TAddress](le) and PageMask) == 0) sysAssert((cast[TAddress](le) and PageMask) == 0, "freeBigChunk 4")
if isAccessible(a, le) and chunkUnused(le): if isAccessible(a, le) and chunkUnused(le):
sysAssert(not isSmallChunk(le)) sysAssert(not isSmallChunk(le), "freeBigChunk 5")
if not isSmallChunk(le): if not isSmallChunk(le):
ListRemove(a.freeChunksList, cast[PBigChunk](le)) ListRemove(a.freeChunksList, cast[PBigChunk](le))
inc(le.size, c.size) inc(le.size, c.size)
@ -395,7 +395,7 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) =
proc splitChunk(a: var TMemRegion, c: PBigChunk, size: int) = proc splitChunk(a: var TMemRegion, c: PBigChunk, size: int) =
var rest = cast[PBigChunk](cast[TAddress](c) +% size) var rest = cast[PBigChunk](cast[TAddress](c) +% size)
sysAssert(rest notin a.freeChunksList) sysAssert(rest notin a.freeChunksList, "splitChunk")
rest.size = c.size - size rest.size = c.size - size
rest.used = false rest.used = false
rest.next = nil rest.next = nil
@ -408,12 +408,12 @@ proc splitChunk(a: var TMemRegion, c: PBigChunk, size: int) =
proc getBigChunk(a: var TMemRegion, size: int): PBigChunk = proc getBigChunk(a: var TMemRegion, size: int): PBigChunk =
# use first fit for now: # use first fit for now:
sysAssert((size and PageMask) == 0) sysAssert((size and PageMask) == 0, "getBigChunk 1")
sysAssert(size > 0) sysAssert(size > 0, "getBigChunk 2")
result = a.freeChunksList result = a.freeChunksList
block search: block search:
while result != nil: while result != nil:
sysAssert chunkUnused(result) sysAssert chunkUnused(result), "getBigChunk 3"
if result.size == size: if result.size == size:
ListRemove(a.freeChunksList, result) ListRemove(a.freeChunksList, result)
break search break search
@ -422,7 +422,7 @@ proc getBigChunk(a: var TMemRegion, size: int): PBigChunk =
splitChunk(a, result, size) splitChunk(a, result, size)
break search break search
result = result.next result = result.next
sysAssert result != a.freeChunksList sysAssert result != a.freeChunksList, "getBigChunk 4"
if size < InitialMemoryRequest: if size < InitialMemoryRequest:
result = requestOsChunks(a, InitialMemoryRequest) result = requestOsChunks(a, InitialMemoryRequest)
splitChunk(a, result, size) splitChunk(a, result, size)
@ -435,8 +435,8 @@ proc getBigChunk(a: var TMemRegion, size: int): PBigChunk =
proc getSmallChunk(a: var TMemRegion): PSmallChunk = proc getSmallChunk(a: var TMemRegion): PSmallChunk =
var res = getBigChunk(a, PageSize) var res = getBigChunk(a, PageSize)
sysAssert res.prev == nil sysAssert res.prev == nil, "getSmallChunk 1"
sysAssert res.next == nil sysAssert res.next == nil, "getSmallChunk 2"
result = cast[PSmallChunk](res) result = cast[PSmallChunk](res)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@ -450,8 +450,8 @@ proc memSize(a: TMemRegion, p: pointer): int {.inline.} =
result = c.size result = c.size
proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
sysAssert(roundup(65, 8) == 72) sysAssert(roundup(65, 8) == 72, "rawAlloc 1")
sysAssert requestedSize >= sizeof(TFreeCell) sysAssert requestedSize >= sizeof(TFreeCell), "rawAlloc 2"
var size = roundup(requestedSize, MemAlign) var size = roundup(requestedSize, MemAlign)
#c_fprintf(c_stdout, "alloc; size: %ld; %ld\n", requestedSize, size) #c_fprintf(c_stdout, "alloc; size: %ld; %ld\n", requestedSize, size)
if size <= SmallChunkSize-smallChunkOverhead(): if size <= SmallChunkSize-smallChunkOverhead():
@ -461,7 +461,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
if c == nil: if c == nil:
c = getSmallChunk(a) c = getSmallChunk(a)
c.freeList = nil c.freeList = nil
sysAssert c.size == PageSize sysAssert c.size == PageSize, "rawAlloc 3"
c.size = size c.size = size
c.acc = size c.acc = size
c.free = SmallChunkSize - smallChunkOverhead() - size c.free = SmallChunkSize - smallChunkOverhead() - size
@ -469,34 +469,35 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer =
c.prev = nil c.prev = nil
ListAdd(a.freeSmallChunks[s], c) ListAdd(a.freeSmallChunks[s], c)
result = addr(c.data) result = addr(c.data)
sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0) sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 4")
else: else:
sysAssert c.next != c sysAssert c.next != c, "rawAlloc 5"
#if c.size != size: #if c.size != size:
# c_fprintf(c_stdout, "csize: %lld; size %lld\n", c.size, size) # c_fprintf(c_stdout, "csize: %lld; size %lld\n", c.size, size)
sysAssert c.size == size sysAssert c.size == size, "rawAlloc 6"
if c.freeList == nil: if c.freeList == nil:
sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize) sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize,
"rawAlloc 7")
result = cast[pointer](cast[TAddress](addr(c.data)) +% c.acc) result = cast[pointer](cast[TAddress](addr(c.data)) +% c.acc)
inc(c.acc, size) inc(c.acc, size)
else: else:
result = c.freeList result = c.freeList
sysAssert(c.freeList.zeroField == 0) sysAssert(c.freeList.zeroField == 0, "rawAlloc 8")
c.freeList = c.freeList.next c.freeList = c.freeList.next
dec(c.free, size) dec(c.free, size)
sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0) sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9")
if c.free < size: if c.free < size:
ListRemove(a.freeSmallChunks[s], c) ListRemove(a.freeSmallChunks[s], c)
else: else:
size = roundup(requestedSize+bigChunkOverhead(), PageSize) size = roundup(requestedSize+bigChunkOverhead(), PageSize)
# allocate a large block # allocate a large block
var c = getBigChunk(a, size) var c = getBigChunk(a, size)
sysAssert c.prev == nil sysAssert c.prev == nil, "rawAlloc 10"
sysAssert c.next == nil sysAssert c.next == nil, "rawAlloc 11"
sysAssert c.size == size sysAssert c.size == size, "rawAlloc 12"
result = addr(c.data) result = addr(c.data)
sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0) sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13")
sysAssert(isAccessible(a, result)) sysAssert(isAccessible(a, result), "rawAlloc 14")
proc rawAlloc0(a: var TMemRegion, requestedSize: int): pointer = proc rawAlloc0(a: var TMemRegion, requestedSize: int): pointer =
result = rawAlloc(a, requestedSize) result = rawAlloc(a, requestedSize)
@ -510,7 +511,7 @@ proc rawDealloc(a: var TMemRegion, p: pointer) =
var s = c.size var s = c.size
var f = cast[ptr TFreeCell](p) var f = cast[ptr TFreeCell](p)
#echo("setting to nil: ", $cast[TAddress](addr(f.zeroField))) #echo("setting to nil: ", $cast[TAddress](addr(f.zeroField)))
sysAssert(f.zeroField != 0) sysAssert(f.zeroField != 0, "rawDealloc 1")
f.zeroField = 0 f.zeroField = 0
f.next = c.freeList f.next = c.freeList
c.freeList = f c.freeList = f
@ -520,7 +521,6 @@ proc rawDealloc(a: var TMemRegion, p: pointer) =
s -% sizeof(TFreeCell)) s -% sizeof(TFreeCell))
# check if it is not in the freeSmallChunks[s] list: # check if it is not in the freeSmallChunks[s] list:
if c.free < s: if c.free < s:
sysAssert c notin a.freeSmallChunks[s div memAlign]
# add it to the freeSmallChunks[s] array: # add it to the freeSmallChunks[s] array:
ListAdd(a.freeSmallChunks[s div memAlign], c) ListAdd(a.freeSmallChunks[s div memAlign], c)
inc(c.free, s) inc(c.free, s)
@ -557,7 +557,7 @@ proc ptrSize(p: pointer): int =
proc alloc(allocator: var TMemRegion, size: int): pointer = proc alloc(allocator: var TMemRegion, size: int): pointer =
result = rawAlloc(allocator, size+sizeof(TFreeCell)) result = rawAlloc(allocator, size+sizeof(TFreeCell))
cast[ptr TFreeCell](result).zeroField = 1 # mark it as used cast[ptr TFreeCell](result).zeroField = 1 # mark it as used
sysAssert(not isAllocatedPtr(allocator, result)) sysAssert(not isAllocatedPtr(allocator, result), "alloc")
result = cast[pointer](cast[TAddress](result) +% sizeof(TFreeCell)) result = cast[pointer](cast[TAddress](result) +% sizeof(TFreeCell))
proc alloc0(allocator: var TMemRegion, size: int): pointer = proc alloc0(allocator: var TMemRegion, size: int): pointer =
@ -566,9 +566,9 @@ proc alloc0(allocator: var TMemRegion, size: int): pointer =
proc dealloc(allocator: var TMemRegion, p: pointer) = proc dealloc(allocator: var TMemRegion, p: pointer) =
var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell)) var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell))
sysAssert(cast[ptr TFreeCell](x).zeroField == 1) sysAssert(cast[ptr TFreeCell](x).zeroField == 1, "dealloc 1")
rawDealloc(allocator, x) rawDealloc(allocator, x)
sysAssert(not isAllocatedPtr(allocator, x)) sysAssert(not isAllocatedPtr(allocator, x), "dealloc 2")
proc realloc(allocator: var TMemRegion, p: pointer, newsize: int): pointer = proc realloc(allocator: var TMemRegion, p: pointer, newsize: int): pointer =
if newsize > 0: if newsize > 0:

View file

@ -24,7 +24,7 @@ proc genericAssignAux(dest, src: Pointer, n: ptr TNimNode, shallow: bool) =
n.typ.size) n.typ.size)
var m = selectBranch(src, n) var m = selectBranch(src, n)
if m != nil: genericAssignAux(dest, src, m, shallow) if m != nil: genericAssignAux(dest, src, m, shallow)
of nkNone: sysAssert(false) of nkNone: sysAssert(false, "genericAssignAux")
#else: #else:
# echo "ugh memory corruption! ", n.kind # echo "ugh memory corruption! ", n.kind
# quit 1 # quit 1
@ -33,7 +33,7 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
var var
d = cast[TAddress](dest) d = cast[TAddress](dest)
s = cast[TAddress](src) s = cast[TAddress](src)
sysAssert(mt != nil) sysAssert(mt != nil, "genericAssignAux 2")
case mt.Kind case mt.Kind
of tyString: of tyString:
var x = cast[ppointer](dest) var x = cast[ppointer](dest)
@ -50,7 +50,7 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
# this can happen! nil sequences are allowed # this can happen! nil sequences are allowed
unsureAsgnRef(x, s2) unsureAsgnRef(x, s2)
return return
sysAssert(dest != nil) sysAssert(dest != nil, "genericAssignAux 3")
unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize))
var dst = cast[taddress](cast[ppointer](dest)[]) var dst = cast[taddress](cast[ppointer](dest)[])
for i in 0..seq.len-1: for i in 0..seq.len-1:
@ -101,7 +101,7 @@ proc objectInit(dest: Pointer, typ: PNimType) {.compilerProc.}
proc objectInitAux(dest: Pointer, n: ptr TNimNode) = proc objectInitAux(dest: Pointer, n: ptr TNimNode) =
var d = cast[TAddress](dest) var d = cast[TAddress](dest)
case n.kind case n.kind
of nkNone: sysAssert(false) of nkNone: sysAssert(false, "objectInitAux")
of nkSLot: objectInit(cast[pointer](d +% n.offset), n.typ) of nkSLot: objectInit(cast[pointer](d +% n.offset), n.typ)
of nkList: of nkList:
for i in 0..n.len-1: for i in 0..n.len-1:
@ -134,7 +134,7 @@ proc genericReset(dest: Pointer, mt: PNimType) {.compilerProc.}
proc genericResetAux(dest: Pointer, n: ptr TNimNode) = proc genericResetAux(dest: Pointer, n: ptr TNimNode) =
var d = cast[TAddress](dest) var d = cast[TAddress](dest)
case n.kind case n.kind
of nkNone: sysAssert(false) of nkNone: sysAssert(false, "genericResetAux")
of nkSlot: genericReset(cast[pointer](d +% n.offset), n.typ) of nkSlot: genericReset(cast[pointer](d +% n.offset), n.typ)
of nkList: of nkList:
for i in 0..n.len-1: genericResetAux(dest, n.sons[i]) for i in 0..n.len-1: genericResetAux(dest, n.sons[i])
@ -145,7 +145,7 @@ proc genericResetAux(dest: Pointer, n: ptr TNimNode) =
proc genericReset(dest: Pointer, mt: PNimType) = proc genericReset(dest: Pointer, mt: PNimType) =
var d = cast[TAddress](dest) var d = cast[TAddress](dest)
sysAssert(mt != nil) sysAssert(mt != nil, "genericReset 2")
case mt.Kind case mt.Kind
of tyString, tyRef, tySequence: of tyString, tyRef, tySequence:
unsureAsgnRef(cast[ppointer](dest), nil) unsureAsgnRef(cast[ppointer](dest), nil)

View file

@ -102,9 +102,9 @@ proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc =
proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) = proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
var h = cast[int](desc.key) and t.max var h = cast[int](desc.key) and t.max
while data[h] != nil: while data[h] != nil:
sysAssert(data[h] != desc) sysAssert(data[h] != desc, "CellSetRawInsert 1")
h = nextTry(h, t.max) h = nextTry(h, t.max)
sysAssert(data[h] == nil) sysAssert(data[h] == nil, "CellSetRawInsert 2")
data[h] = desc data[h] = desc
proc CellSetEnlarge(t: var TCellSet) = proc CellSetEnlarge(t: var TCellSet) =
@ -130,7 +130,7 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
inc(t.counter) inc(t.counter)
h = cast[int](key) and t.max h = cast[int](key) and t.max
while t.data[h] != nil: h = nextTry(h, t.max) while t.data[h] != nil: h = nextTry(h, t.max)
sysAssert(t.data[h] == nil) sysAssert(t.data[h] == nil, "CellSetPut")
# the new page descriptor goes into result # the new page descriptor goes into result
result = cast[PPageDesc](Alloc0(sizeof(TPageDesc))) result = cast[PPageDesc](Alloc0(sizeof(TPageDesc)))
result.next = t.head result.next = t.head

View file

@ -133,30 +133,30 @@ when traceGC:
of csAllocated: of csAllocated:
if c in states[csAllocated]: if c in states[csAllocated]:
writeCell("attempt to alloc an already allocated cell", c) writeCell("attempt to alloc an already allocated cell", c)
sysAssert(false) sysAssert(false, "traceCell 1")
excl(states[csCycFreed], c) excl(states[csCycFreed], c)
excl(states[csZctFreed], c) excl(states[csZctFreed], c)
of csZctFreed: of csZctFreed:
if c in states[csZctFreed]: if c in states[csZctFreed]:
writeCell("attempt to free zct cell twice", c) writeCell("attempt to free zct cell twice", c)
sysAssert(false) sysAssert(false, "traceCell 2")
if c in states[csCycFreed]: if c in states[csCycFreed]:
writeCell("attempt to free with zct, but already freed with cyc", c) writeCell("attempt to free with zct, but already freed with cyc", c)
sysAssert(false) sysAssert(false, "traceCell 3")
if c notin states[csAllocated]: if c notin states[csAllocated]:
writeCell("attempt to free not an allocated cell", c) writeCell("attempt to free not an allocated cell", c)
sysAssert(false) sysAssert(false, "traceCell 4")
excl(states[csAllocated], c) excl(states[csAllocated], c)
of csCycFreed: of csCycFreed:
if c notin states[csAllocated]: if c notin states[csAllocated]:
writeCell("attempt to free a not allocated cell", c) writeCell("attempt to free a not allocated cell", c)
sysAssert(false) sysAssert(false, "traceCell 5")
if c in states[csCycFreed]: if c in states[csCycFreed]:
writeCell("attempt to free cyc cell twice", c) writeCell("attempt to free cyc cell twice", c)
sysAssert(false) sysAssert(false, "traceCell 6")
if c in states[csZctFreed]: if c in states[csZctFreed]:
writeCell("attempt to free with cyc, but already freed with zct", c) writeCell("attempt to free with cyc, but already freed with zct", c)
sysAssert(false) sysAssert(false, "traceCell 7")
excl(states[csAllocated], c) excl(states[csAllocated], c)
incl(states[state], c) incl(states[state], c)
@ -225,7 +225,7 @@ proc decRef(c: PCell) {.inline.} =
when stressGC: when stressGC:
if c.refcount <% rcIncrement: if c.refcount <% rcIncrement:
writeCell("broken cell", c) writeCell("broken cell", c)
sysAssert(c.refcount >=% rcIncrement) sysAssert(c.refcount >=% rcIncrement, "decRef")
#if c.refcount <% rcIncrement: quit("leck mich") #if c.refcount <% rcIncrement: quit("leck mich")
if --c.refcount: if --c.refcount:
rtlAddZCT(c) rtlAddZCT(c)
@ -242,7 +242,7 @@ proc nimGCunref(p: pointer) {.compilerProc, inline.} = decRef(usrToCell(p))
proc asgnRef(dest: ppointer, src: pointer) {.compilerProc, inline.} = proc asgnRef(dest: ppointer, src: pointer) {.compilerProc, inline.} =
# the code generator calls this proc! # the code generator calls this proc!
sysAssert(not isOnStack(dest)) sysAssert(not isOnStack(dest), "asgnRef")
# BUGFIX: first incRef then decRef! # BUGFIX: first incRef then decRef!
if src != nil: incRef(usrToCell(src)) if src != nil: incRef(usrToCell(src))
if dest[] != nil: decRef(usrToCell(dest[])) if dest[] != nil: decRef(usrToCell(dest[]))
@ -298,7 +298,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
of nkCase: of nkCase:
var m = selectBranch(dest, n) var m = selectBranch(dest, n)
if m != nil: forAllSlotsAux(dest, m, op) if m != nil: forAllSlotsAux(dest, m, op)
of nkNone: sysAssert(false) of nkNone: sysAssert(false, "forAllSlotsAux")
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) = proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
var d = cast[TAddress](dest) var d = cast[TAddress](dest)
@ -315,9 +315,9 @@ proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
else: nil else: nil
proc forAllChildren(cell: PCell, op: TWalkOp) = proc forAllChildren(cell: PCell, op: TWalkOp) =
sysAssert(cell != nil) sysAssert(cell != nil, "forAllChildren: 1")
sysAssert(cell.typ != nil) sysAssert(cell.typ != nil, "forAllChildren: 2")
sysAssert cell.typ.kind in {tyRef, tySequence, tyString} sysAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 3"
case cell.typ.Kind case cell.typ.Kind
of tyRef: # common case of tyRef: # common case
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
@ -377,11 +377,11 @@ proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
proc newObj(typ: PNimType, size: int, gch: var TGcHeap): pointer = proc newObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
# generates a new object and sets its reference counter to 0 # generates a new object and sets its reference counter to 0
acquire(gch) acquire(gch)
sysAssert(typ.kind in {tyRef, tyString, tySequence}) sysAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
collectCT(gch) collectCT(gch)
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
zeroMem(res, size+sizeof(TCell)) zeroMem(res, size+sizeof(TCell))
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0) sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
# now it is buffered in the ZCT # now it is buffered in the ZCT
res.typ = typ res.typ = typ
when debugGC and not hasThreadSupport: when debugGC and not hasThreadSupport:
@ -389,7 +389,7 @@ proc newObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
res.filename = framePtr.prev.filename res.filename = framePtr.prev.filename
res.line = framePtr.prev.line res.line = framePtr.prev.line
res.refcount = rcZct # refcount is zero, but mark it to be in the ZCT res.refcount = rcZct # refcount is zero, but mark it to be in the ZCT
sysAssert(isAllocatedPtr(gch.region, res)) sysAssert(isAllocatedPtr(gch.region, res), "newObj: 3")
# its refcount is zero, so add it to the ZCT: # its refcount is zero, so add it to the ZCT:
addNewObjToZCT(res, gch) addNewObjToZCT(res, gch)
when logGC: writeCell("new cell", res) when logGC: writeCell("new cell", res)
@ -410,8 +410,8 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
acquire(gch) acquire(gch)
collectCT(gch) collectCT(gch)
var ol = usrToCell(old) var ol = usrToCell(old)
sysAssert(ol.typ != nil) sysAssert(ol.typ != nil, "growObj: 1")
sysAssert(ol.typ.kind in {tyString, tySequence}) sysAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
var res = cast[PCell](rawAlloc(gch.region, newsize + sizeof(TCell))) var res = cast[PCell](rawAlloc(gch.region, newsize + sizeof(TCell)))
var elemSize = 1 var elemSize = 1
if ol.typ.kind != tyString: elemSize = ol.typ.base.size if ol.typ.kind != tyString: elemSize = ol.typ.base.size
@ -420,8 +420,8 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
copyMem(res, ol, oldsize + sizeof(TCell)) copyMem(res, ol, oldsize + sizeof(TCell))
zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)), zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)),
newsize-oldsize) newsize-oldsize)
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0) sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
sysAssert(res.refcount shr rcShift <=% 1) sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
#if res.refcount <% rcIncrement: #if res.refcount <% rcIncrement:
# add(gch.zct, res) # add(gch.zct, res)
#else: # XXX: what to do here? #else: # XXX: what to do here?
@ -442,7 +442,7 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
gcTrace(res, csAllocated) gcTrace(res, csAllocated)
when reallyDealloc: rawDealloc(gch.region, ol) when reallyDealloc: rawDealloc(gch.region, ol)
else: else:
sysAssert(ol.typ != nil) sysAssert(ol.typ != nil, "growObj: 5")
zeroMem(ol, sizeof(TCell)) zeroMem(ol, sizeof(TCell))
release(gch) release(gch)
result = cellToUsr(res) result = cellToUsr(res)
@ -455,17 +455,17 @@ proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
proc doOperation(p: pointer, op: TWalkOp) = proc doOperation(p: pointer, op: TWalkOp) =
if p == nil: return if p == nil: return
var c: PCell = usrToCell(p) var c: PCell = usrToCell(p)
sysAssert(c != nil) sysAssert(c != nil, "doOperation: 1")
case op # faster than function pointers because of easy prediction case op # faster than function pointers because of easy prediction
of waZctDecRef: of waZctDecRef:
sysAssert(c.refcount >=% rcIncrement) sysAssert(c.refcount >=% rcIncrement, "doOperation 2")
c.refcount = c.refcount -% rcIncrement c.refcount = c.refcount -% rcIncrement
when logGC: writeCell("decref (from doOperation)", c) when logGC: writeCell("decref (from doOperation)", c)
if c.refcount <% rcIncrement: addZCT(gch.zct, c) if c.refcount <% rcIncrement: addZCT(gch.zct, c)
of waPush: of waPush:
add(gch.tempStack, c) add(gch.tempStack, c)
of waCycleDecRef: of waCycleDecRef:
sysAssert(c.refcount >=% rcIncrement) sysAssert(c.refcount >=% rcIncrement, "doOperation 3")
c.refcount = c.refcount -% rcIncrement c.refcount = c.refcount -% rcIncrement
# we now use a much simpler and non-recursive algorithm for cycle removal # we now use a much simpler and non-recursive algorithm for cycle removal
@ -507,7 +507,7 @@ proc collectCycles(gch: var TGcHeap) =
when logGC: writeCell("cycle collector dealloc cell", c) when logGC: writeCell("cycle collector dealloc cell", c)
when reallyDealloc: rawDealloc(gch.region, c) when reallyDealloc: rawDealloc(gch.region, c)
else: else:
sysAssert(c.typ != nil) sysAssert(c.typ != nil, "collectCycles")
zeroMem(c, sizeof(TCell)) zeroMem(c, sizeof(TCell))
Deinit(gch.cycleRoots) Deinit(gch.cycleRoots)
Init(gch.cycleRoots) Init(gch.cycleRoots)
@ -686,7 +686,7 @@ proc CollectZCT(gch: var TGcHeap) =
while L[] > 0: while L[] > 0:
var c = gch.zct.d[0] var c = gch.zct.d[0]
# remove from ZCT: # remove from ZCT:
sysAssert((c.refcount and colorMask) == rcZct) sysAssert((c.refcount and rcZct) == rcZct, "collectZCT")
c.refcount = c.refcount and not colorMask c.refcount = c.refcount and not colorMask
gch.zct.d[0] = gch.zct.d[L[] - 1] gch.zct.d[0] = gch.zct.d[L[] - 1]
dec(L[]) dec(L[])
@ -707,19 +707,19 @@ proc CollectZCT(gch: var TGcHeap) =
forAllChildren(c, waZctDecRef) forAllChildren(c, waZctDecRef)
when reallyDealloc: rawDealloc(gch.region, c) when reallyDealloc: rawDealloc(gch.region, c)
else: else:
sysAssert(c.typ != nil) sysAssert(c.typ != nil, "collectZCT 2")
zeroMem(c, sizeof(TCell)) zeroMem(c, sizeof(TCell))
proc unmarkStackAndRegisters(gch: var TGcHeap) = proc unmarkStackAndRegisters(gch: var TGcHeap) =
var d = gch.decStack.d var d = gch.decStack.d
for i in 0..gch.decStack.len-1: for i in 0..gch.decStack.len-1:
sysAssert isAllocatedPtr(allocator, d[i]) sysAssert isAllocatedPtr(gch.region, d[i]), "unmarkStackAndRegisters"
# decRef(d[i]) inlined: cannot create a cycle and must not acquire lock # decRef(d[i]) inlined: cannot create a cycle and must not acquire lock
var c = d[i] var c = d[i]
# XXX no need for an atomic dec here: # XXX no need for an atomic dec here:
if --c.refcount: if --c.refcount:
addZCT(gch.zct, c) addZCT(gch.zct, c)
sysAssert c.typ != nil sysAssert c.typ != nil, "unmarkStackAndRegisters 2"
gch.decStack.len = 0 gch.decStack.len = 0
proc collectCT(gch: var TGcHeap) = proc collectCT(gch: var TGcHeap) =
@ -727,7 +727,7 @@ proc collectCT(gch: var TGcHeap) =
getOccupiedMem(gch.region) >= gch.cycleThreshold) or stressGC) and getOccupiedMem(gch.region) >= gch.cycleThreshold) or stressGC) and
gch.recGcLock == 0: gch.recGcLock == 0:
gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize()) gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize())
sysAssert(gch.decStack.len == 0) sysAssert(gch.decStack.len == 0, "collectCT")
markStackAndRegisters(gch) markStackAndRegisters(gch)
markThreadStacks(gch) markThreadStacks(gch)
gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len) gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len)

View file

@ -207,7 +207,7 @@ else:
include "system/alloc" include "system/alloc"
include "system/cellsets" include "system/cellsets"
sysAssert(sizeof(TCell) == sizeof(TFreeCell)) sysAssert(sizeof(TCell) == sizeof(TFreeCell), "sizeof TFreeCell")
include "system/gc" include "system/gc"
{.pop.} {.pop.}

View file

@ -158,7 +158,7 @@ when not defined(useNimRtl):
proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode, proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
cl: var TReprClosure) = cl: var TReprClosure) =
case n.kind case n.kind
of nkNone: sysAssert(false) of nkNone: sysAssert(false, "reprRecordAux")
of nkSlot: of nkSlot:
add result, $n.name add result, $n.name
add result, " = " add result, " = "
@ -206,7 +206,7 @@ when not defined(useNimRtl):
var t = cast[ptr PNimType](p)[] var t = cast[ptr PNimType](p)[]
reprRecord(result, p, t, cl) reprRecord(result, p, t, cl)
of tyRef, tyPtr: of tyRef, tyPtr:
sysAssert(p != nil) sysAssert(p != nil, "reprAux")
if cast[ppointer](p)[] == nil: add result, "nil" if cast[ppointer](p)[] == nil: add result, "nil"
else: reprRef(result, cast[ppointer](p)[], typ, cl) else: reprRef(result, cast[ppointer](p)[], typ, cl)
of tySequence: of tySequence: