make at least bootstrapping work
This commit is contained in:
commit
7ac6462cbd
81 changed files with 1314 additions and 425 deletions
|
|
@ -116,6 +116,8 @@ type
|
|||
nextChunkSize: int
|
||||
bottomData: AvlNode
|
||||
heapLinks: HeapLinks
|
||||
when defined(nimTypeNames):
|
||||
allocCounter, deallocCounter: int
|
||||
|
||||
const
|
||||
fsLookupTable: array[byte, int8] = [
|
||||
|
|
@ -434,8 +436,9 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
|
|||
a.nextChunkSize = PageSize*4
|
||||
else:
|
||||
a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
|
||||
var size = size
|
||||
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize)
|
||||
|
||||
var size = size
|
||||
if size > a.nextChunkSize:
|
||||
result = cast[PBigChunk](osAllocPages(size))
|
||||
else:
|
||||
|
|
@ -737,6 +740,8 @@ when false:
|
|||
result = nil
|
||||
|
||||
proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
|
||||
when defined(nimTypeNames):
|
||||
inc(a.allocCounter)
|
||||
sysAssert(allocInv(a), "rawAlloc: begin")
|
||||
sysAssert(roundup(65, 8) == 72, "rawAlloc: roundup broken")
|
||||
sysAssert(requestedSize >= sizeof(FreeCell), "rawAlloc: requested size too small")
|
||||
|
|
@ -810,6 +815,8 @@ proc rawAlloc0(a: var MemRegion, requestedSize: int): pointer =
|
|||
zeroMem(result, requestedSize)
|
||||
|
||||
proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||
when defined(nimTypeNames):
|
||||
inc(a.deallocCounter)
|
||||
#sysAssert(isAllocatedPtr(a, p), "rawDealloc: no allocated pointer")
|
||||
sysAssert(allocInv(a), "rawDealloc: begin")
|
||||
var c = pageAddr(p)
|
||||
|
|
@ -975,6 +982,10 @@ proc getOccupiedMem(a: MemRegion): int {.inline.} =
|
|||
result = a.occ
|
||||
# a.currMem - a.freeMem
|
||||
|
||||
when defined(nimTypeNames):
|
||||
proc getMemCounters(a: MemRegion): (int, int) {.inline.} =
|
||||
(a.allocCounter, a.deallocCounter)
|
||||
|
||||
# ---------------------- thread memory region -------------------------------
|
||||
|
||||
template instantiateForRegion(allocator: untyped) =
|
||||
|
|
@ -1018,6 +1029,9 @@ template instantiateForRegion(allocator: untyped) =
|
|||
proc getOccupiedMem(): int = return allocator.occ #getTotalMem() - getFreeMem()
|
||||
proc getMaxMem*(): int = return getMaxMem(allocator)
|
||||
|
||||
when defined(nimTypeNames):
|
||||
proc getMemCounters*(): (int, int) = getMemCounters(allocator)
|
||||
|
||||
# -------------------- shared heap region ----------------------------------
|
||||
when hasThreadSupport:
|
||||
var sharedHeap: MemRegion
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ proc c_strcmp(a, b: cstring): cint {.
|
|||
importc: "strcmp", header: "<string.h>", noSideEffect.}
|
||||
proc c_strlen(a: cstring): csize {.
|
||||
importc: "strlen", header: "<string.h>", noSideEffect.}
|
||||
proc c_abort() {.
|
||||
importc: "abort", header: "<stdlib.h>", noSideEffect.}
|
||||
|
||||
|
||||
when defined(linux) and defined(amd64):
|
||||
type
|
||||
|
|
|
|||
|
|
@ -548,7 +548,10 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
|
|||
gcTrace(res, csAllocated)
|
||||
track("growObj old", ol, 0)
|
||||
track("growObj new", res, newsize)
|
||||
when reallyDealloc:
|
||||
when defined(nimIncrSeqV3):
|
||||
# since we steal the old seq's contents, we set the old length to 0.
|
||||
cast[PGenericSeq](old).len = 0
|
||||
elif reallyDealloc:
|
||||
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
||||
if ol.refcount shr rcShift <=% 1:
|
||||
# free immediately to save space:
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ when defined(nimTypeNames):
|
|||
for i in 0 .. n-1:
|
||||
c_fprintf(stdout, "[Heap] %s: #%ld; bytes: %ld\n", a[i][0], a[i][1], a[i][2])
|
||||
c_fprintf(stdout, "[Heap] total number of bytes: %ld\n", totalAllocated)
|
||||
when defined(nimTypeNames):
|
||||
let (allocs, deallocs) = getMemCounters()
|
||||
c_fprintf(stdout, "[Heap] allocs/deallocs: %ld/%ld\n", allocs, deallocs)
|
||||
|
||||
when defined(nimGcRefLeak):
|
||||
proc oomhandler() =
|
||||
|
|
|
|||
|
|
@ -417,12 +417,18 @@ proc setStdIoUnbuffered() =
|
|||
discard c_setvbuf(stdin, nil, IONBF, 0)
|
||||
|
||||
when declared(stdout):
|
||||
when defined(windows) and compileOption("threads"):
|
||||
var echoLock: SysLock
|
||||
initSysLock echoLock
|
||||
|
||||
proc echoBinSafe(args: openArray[string]) {.compilerProc.} =
|
||||
# flockfile deadlocks some versions of Android 5.x.x
|
||||
when not defined(windows) and not defined(android) and not defined(nintendoswitch):
|
||||
proc flockfile(f: File) {.importc, noDecl.}
|
||||
proc funlockfile(f: File) {.importc, noDecl.}
|
||||
flockfile(stdout)
|
||||
when defined(windows) and compileOption("threads"):
|
||||
acquireSys echoLock
|
||||
for s in args:
|
||||
discard c_fwrite(s.cstring, s.len, 1, stdout)
|
||||
const linefeed = "\n" # can be 1 or more chars
|
||||
|
|
@ -430,5 +436,7 @@ when declared(stdout):
|
|||
discard c_fflush(stdout)
|
||||
when not defined(windows) and not defined(android) and not defined(nintendoswitch):
|
||||
funlockfile(stdout)
|
||||
when defined(windows) and compileOption("threads"):
|
||||
releaseSys echoLock
|
||||
|
||||
{.pop.}
|
||||
|
|
|
|||
|
|
@ -144,8 +144,13 @@ proc addChar(s: NimString, c: char): NimString =
|
|||
result = s
|
||||
if result.len >= result.space:
|
||||
let r = resize(result.space)
|
||||
result = cast[NimString](growObj(result,
|
||||
sizeof(TGenericSeq) + r + 1))
|
||||
when defined(nimIncrSeqV3):
|
||||
result = rawNewStringNoInit(r)
|
||||
result.len = s.len
|
||||
copyMem(addr result.data[0], unsafeAddr(s.data[0]), s.len+1)
|
||||
else:
|
||||
result = cast[NimString](growObj(result,
|
||||
sizeof(TGenericSeq) + r + 1))
|
||||
result.reserved = r
|
||||
result.data[result.len] = c
|
||||
result.data[result.len+1] = '\0'
|
||||
|
|
@ -188,8 +193,13 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} =
|
|||
elif dest.len + addlen <= dest.space:
|
||||
result = dest
|
||||
else: # slow path:
|
||||
var sp = max(resize(dest.space), dest.len + addlen)
|
||||
result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1))
|
||||
let sp = max(resize(dest.space), dest.len + addlen)
|
||||
when defined(nimIncrSeqV3):
|
||||
result = rawNewStringNoInit(sp)
|
||||
result.len = dest.len
|
||||
copyMem(addr result.data[0], unsafeAddr(dest.data[0]), dest.len+1)
|
||||
else:
|
||||
result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1))
|
||||
result.reserved = sp
|
||||
#result = rawNewString(sp)
|
||||
#copyMem(result, dest, dest.len + sizeof(TGenericSeq))
|
||||
|
|
@ -212,7 +222,15 @@ proc setLengthStr(s: NimString, newLen: int): NimString {.compilerRtl.} =
|
|||
elif n <= s.space:
|
||||
result = s
|
||||
else:
|
||||
result = resizeString(s, n)
|
||||
let sp = max(resize(s.space), newLen)
|
||||
when defined(nimIncrSeqV3):
|
||||
result = rawNewStringNoInit(sp)
|
||||
result.len = s.len
|
||||
copyMem(addr result.data[0], unsafeAddr(s.data[0]), s.len+1)
|
||||
zeroMem(addr result.data[s.len], newLen - s.len)
|
||||
result.reserved = sp
|
||||
else:
|
||||
result = resizeString(s, n)
|
||||
result.len = n
|
||||
result.data[n] = '\0'
|
||||
|
||||
|
|
@ -242,6 +260,9 @@ proc incrSeqV2(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
|
|||
GenericSeqSize))
|
||||
result.reserved = r
|
||||
|
||||
template `+!`(p: pointer, s: int): pointer =
|
||||
cast[pointer](cast[int](p) +% s)
|
||||
|
||||
proc incrSeqV3(s: PGenericSeq, typ: PNimType): PGenericSeq {.compilerProc.} =
|
||||
if s == nil:
|
||||
result = cast[PGenericSeq](newSeq(typ, 1))
|
||||
|
|
@ -250,9 +271,16 @@ proc incrSeqV3(s: PGenericSeq, typ: PNimType): PGenericSeq {.compilerProc.} =
|
|||
result = s
|
||||
if result.len >= result.space:
|
||||
let r = resize(result.space)
|
||||
result = cast[PGenericSeq](growObj(result, typ.base.size * r +
|
||||
when defined(nimIncrSeqV3):
|
||||
result = cast[PGenericSeq](newSeq(typ, r))
|
||||
result.len = s.len
|
||||
copyMem(result +! GenericSeqSize, s +! GenericSeqSize, s.len * typ.base.size)
|
||||
# since we steal the content from 's', it's crucial to set s's len to 0.
|
||||
s.len = 0
|
||||
else:
|
||||
result = cast[PGenericSeq](growObj(result, typ.base.size * r +
|
||||
GenericSeqSize))
|
||||
result.reserved = r
|
||||
result.reserved = r
|
||||
|
||||
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||
compilerRtl, inl.} =
|
||||
|
|
@ -296,7 +324,40 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
|||
|
||||
proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
||||
compilerRtl.} =
|
||||
sysAssert typ.kind == tySequence, "setLengthSeqV2: type is not a seq"
|
||||
if s == nil:
|
||||
result = cast[PGenericSeq](newSeq(typ, newLen))
|
||||
else:
|
||||
result = setLengthSeq(s, typ.base.size, newLen)
|
||||
when defined(nimIncrSeqV3):
|
||||
let elemSize = typ.base.size
|
||||
if s.space < newLen:
|
||||
let r = max(resize(s.space), newLen)
|
||||
result = cast[PGenericSeq](newSeq(typ, r))
|
||||
copyMem(result +! GenericSeqSize, s +! GenericSeqSize, s.len * elemSize)
|
||||
# since we steal the content from 's', it's crucial to set s's len to 0.
|
||||
s.len = 0
|
||||
elif newLen < s.len:
|
||||
result = s
|
||||
# we need to decref here, otherwise the GC leaks!
|
||||
when not defined(boehmGC) and not defined(nogc) and
|
||||
not defined(gcMarkAndSweep) and not defined(gogc) and
|
||||
not defined(gcRegions):
|
||||
if ntfNoRefs notin typ.base.flags:
|
||||
for i in newLen..result.len-1:
|
||||
forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
|
||||
GenericSeqSize +% (i*%elemSize)),
|
||||
extGetCellType(result).base, waZctDecRef)
|
||||
|
||||
# XXX: zeroing out the memory can still result in crashes if a wiped-out
|
||||
# cell is aliased by another pointer (ie proc parameter or a let variable).
|
||||
# This is a tough problem, because even if we don't zeroMem here, in the
|
||||
# presence of user defined destructors, the user will expect the cell to be
|
||||
# "destroyed" thus creating the same problem. We can destoy the cell in the
|
||||
# finalizer of the sequence, but this makes destruction non-deterministic.
|
||||
zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +%
|
||||
(newLen*%elemSize)), (result.len-%newLen) *% elemSize)
|
||||
else:
|
||||
result = s
|
||||
result.len = newLen
|
||||
else:
|
||||
result = setLengthSeq(s, typ.base.size, newLen)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue