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