forked from nim-lang/Nim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from nim-lang/devel
Cleaned up mmdisp.nim, moved implementations into lib/system/mm/ (#13…
- Loading branch information
Showing
5 changed files
with
416 additions
and
392 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
|
||
proc boehmGCinit {.importc: "GC_init", boehmGC.} | ||
proc boehmGC_disable {.importc: "GC_disable", boehmGC.} | ||
proc boehmGC_enable {.importc: "GC_enable", boehmGC.} | ||
proc boehmGCincremental {. | ||
importc: "GC_enable_incremental", boehmGC.} | ||
proc boehmGCfullCollect {.importc: "GC_gcollect", boehmGC.} | ||
proc boehmGC_set_all_interior_pointers(flag: cint) {. | ||
importc: "GC_set_all_interior_pointers", boehmGC.} | ||
proc boehmAlloc(size: int): pointer {.importc: "GC_malloc", boehmGC.} | ||
proc boehmAllocAtomic(size: int): pointer {. | ||
importc: "GC_malloc_atomic", boehmGC.} | ||
proc boehmRealloc(p: pointer, size: int): pointer {. | ||
importc: "GC_realloc", boehmGC.} | ||
proc boehmDealloc(p: pointer) {.importc: "GC_free", boehmGC.} | ||
when hasThreadSupport: | ||
proc boehmGC_allow_register_threads {. | ||
importc: "GC_allow_register_threads", boehmGC.} | ||
|
||
proc boehmGetHeapSize: int {.importc: "GC_get_heap_size", boehmGC.} | ||
## Return the number of bytes in the heap. Excludes collector private | ||
## data structures. Includes empty blocks and fragmentation loss. | ||
## Includes some pages that were allocated but never written. | ||
|
||
proc boehmGetFreeBytes: int {.importc: "GC_get_free_bytes", boehmGC.} | ||
## Return a lower bound on the number of free bytes in the heap. | ||
|
||
proc boehmGetBytesSinceGC: int {.importc: "GC_get_bytes_since_gc", boehmGC.} | ||
## Return the number of bytes allocated since the last collection. | ||
|
||
proc boehmGetTotalBytes: int {.importc: "GC_get_total_bytes", boehmGC.} | ||
## Return the total number of bytes allocated in this process. | ||
## Never decreases. | ||
|
||
proc boehmRegisterFinalizer(obj, ff, cd, off, ocd: pointer) {.importc: "GC_register_finalizer", boehmGC.} | ||
|
||
proc allocAtomic(size: int): pointer = | ||
result = boehmAllocAtomic(size) | ||
zeroMem(result, size) | ||
|
||
when not defined(useNimRtl): | ||
|
||
proc allocImpl(size: Natural): pointer = | ||
result = boehmAlloc(size) | ||
if result == nil: raiseOutOfMem() | ||
proc alloc0Impl(size: Natural): pointer = | ||
result = alloc(size) | ||
proc reallocImpl(p: pointer, newSize: Natural): pointer = | ||
result = boehmRealloc(p, newSize) | ||
if result == nil: raiseOutOfMem() | ||
proc realloc0Impl(p: pointer, oldSize, newSize: Natural): pointer = | ||
result = boehmRealloc(p, newSize) | ||
if result == nil: raiseOutOfMem() | ||
if newsize > oldsize: | ||
zeroMem(cast[pointer](cast[int](result) + oldsize), newsize - oldsize) | ||
proc deallocImpl(p: pointer) = boehmDealloc(p) | ||
|
||
proc allocSharedImpl(size: Natural): pointer = allocImpl(size) | ||
proc allocShared0Impl(size: Natural): pointer = alloc0Impl(size) | ||
proc reallocSharedImpl(p: pointer, newsize: Natural): pointer = reallocImpl(p, newsize) | ||
proc reallocShared0Impl(p: pointer, oldsize, newsize: Natural): pointer = realloc0Impl(p, oldsize, newsize) | ||
proc deallocSharedImpl(p: pointer) = deallocImpl(p) | ||
|
||
when hasThreadSupport: | ||
proc getFreeSharedMem(): int = | ||
boehmGetFreeBytes() | ||
proc getTotalSharedMem(): int = | ||
boehmGetHeapSize() | ||
proc getOccupiedSharedMem(): int = | ||
getTotalSharedMem() - getFreeSharedMem() | ||
|
||
#boehmGCincremental() | ||
|
||
proc GC_disable() = boehmGC_disable() | ||
proc GC_enable() = boehmGC_enable() | ||
proc GC_fullCollect() = boehmGCfullCollect() | ||
proc GC_setStrategy(strategy: GC_Strategy) = discard | ||
proc GC_enableMarkAndSweep() = discard | ||
proc GC_disableMarkAndSweep() = discard | ||
proc GC_getStatistics(): string = return "" | ||
|
||
proc getOccupiedMem(): int = return boehmGetHeapSize()-boehmGetFreeBytes() | ||
proc getFreeMem(): int = return boehmGetFreeBytes() | ||
proc getTotalMem(): int = return boehmGetHeapSize() | ||
|
||
proc nimGC_setStackBottom(theStackBottom: pointer) = discard | ||
|
||
proc initGC() = | ||
when defined(boehmNoIntPtr): | ||
# See #12286 | ||
boehmGC_set_all_interior_pointers(0) | ||
boehmGCinit() | ||
when hasThreadSupport: | ||
boehmGC_allow_register_threads() | ||
|
||
proc boehmgc_finalizer(obj: pointer, typedFinalizer: (proc(x: pointer) {.cdecl.})) = | ||
typedFinalizer(obj) | ||
|
||
proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} = | ||
if ntfNoRefs in typ.flags: result = allocAtomic(size) | ||
else: result = alloc(size) | ||
if typ.finalizer != nil: | ||
boehmRegisterFinalizer(result, boehmgc_finalizer, typ.finalizer, nil, nil) | ||
proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} = | ||
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize)) | ||
cast[PGenericSeq](result).len = len | ||
cast[PGenericSeq](result).reserved = len | ||
|
||
proc growObj(old: pointer, newsize: int): pointer = | ||
result = realloc(old, newsize) | ||
|
||
proc nimGCref(p: pointer) {.compilerproc, inline.} = discard | ||
proc nimGCunref(p: pointer) {.compilerproc, inline.} = discard | ||
|
||
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = | ||
dest[] = src | ||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = | ||
dest[] = src | ||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline, | ||
deprecated: "old compiler compat".} = asgnRef(dest, src) | ||
|
||
type | ||
MemRegion = object | ||
|
||
proc alloc(r: var MemRegion, size: int): pointer = | ||
result = boehmAlloc(size) | ||
if result == nil: raiseOutOfMem() | ||
proc alloc0(r: var MemRegion, size: int): pointer = | ||
result = alloc(size) | ||
zeroMem(result, size) | ||
proc dealloc(r: var MemRegion, p: pointer) = boehmDealloc(p) | ||
proc deallocOsPages(r: var MemRegion) {.inline.} = discard | ||
proc deallocOsPages() {.inline.} = discard | ||
|
||
include "system/cellsets" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
|
||
when defined(windows): | ||
const goLib = "libgo.dll" | ||
elif defined(macosx): | ||
const goLib = "libgo.dylib" | ||
else: | ||
const goLib = "libgo.so" | ||
|
||
proc initGC() = discard | ||
proc GC_disable() = discard | ||
proc GC_enable() = discard | ||
proc go_gc() {.importc: "go_gc", dynlib: goLib.} | ||
proc GC_fullCollect() = go_gc() | ||
proc GC_setStrategy(strategy: GC_Strategy) = discard | ||
proc GC_enableMarkAndSweep() = discard | ||
proc GC_disableMarkAndSweep() = discard | ||
|
||
const | ||
goNumSizeClasses = 67 | ||
|
||
type | ||
goMStats = object | ||
alloc: uint64 # bytes allocated and still in use | ||
total_alloc: uint64 # bytes allocated (even if freed) | ||
sys: uint64 # bytes obtained from system | ||
nlookup: uint64 # number of pointer lookups | ||
nmalloc: uint64 # number of mallocs | ||
nfree: uint64 # number of frees | ||
heap_objects: uint64 # total number of allocated objects | ||
pause_total_ns: uint64 # cumulative nanoseconds in GC stop-the-world pauses since the program started | ||
numgc: uint32 # number of completed GC cycles | ||
|
||
proc goMemStats(): goMStats {.importc: "go_mem_stats", dynlib: goLib.} | ||
proc goMalloc(size: uint): pointer {.importc: "go_malloc", dynlib: goLib.} | ||
proc goSetFinalizer(obj: pointer, f: pointer) {.importc: "set_finalizer", codegenDecl:"$1 $2$3 __asm__ (\"main.Set_finalizer\");\n$1 $2$3", dynlib: goLib.} | ||
proc writebarrierptr(dest: PPointer, src: pointer) {.importc: "writebarrierptr", codegenDecl:"$1 $2$3 __asm__ (\"main.Atomic_store_pointer\");\n$1 $2$3", dynlib: goLib.} | ||
|
||
proc `$`*(x: uint64): string {.noSideEffect, raises: [].} | ||
|
||
proc GC_getStatistics(): string = | ||
var mstats = goMemStats() | ||
result = "[GC] total allocated memory: " & $(mstats.total_alloc) & "\n" & | ||
"[GC] total memory obtained from system: " & $(mstats.sys) & "\n" & | ||
"[GC] occupied memory: " & $(mstats.alloc) & "\n" & | ||
"[GC] number of pointer lookups: " & $(mstats.nlookup) & "\n" & | ||
"[GC] number of mallocs: " & $(mstats.nmalloc) & "\n" & | ||
"[GC] number of frees: " & $(mstats.nfree) & "\n" & | ||
"[GC] heap objects: " & $(mstats.heap_objects) & "\n" & | ||
"[GC] number of completed GC cycles: " & $(mstats.numgc) & "\n" & | ||
"[GC] total GC pause time [ms]: " & $(mstats.pause_total_ns div 1000_000) | ||
|
||
proc getOccupiedMem(): int = | ||
var mstats = goMemStats() | ||
result = int(mstats.alloc) | ||
|
||
proc getFreeMem(): int = | ||
var mstats = goMemStats() | ||
result = int(mstats.sys - mstats.alloc) | ||
|
||
proc getTotalMem(): int = | ||
var mstats = goMemStats() | ||
result = int(mstats.sys) | ||
|
||
proc nimGC_setStackBottom(theStackBottom: pointer) = discard | ||
|
||
proc allocImpl(size: Natural): pointer = | ||
result = goMalloc(size.uint) | ||
|
||
proc alloc0Impl(size: Natural): pointer = | ||
result = goMalloc(size.uint) | ||
|
||
proc reallocImpl(p: pointer, newsize: Natural): pointer = | ||
doAssert false, "not implemented" | ||
|
||
proc realloc0Impl(p: pointer, oldsize, newsize: Natural): pointer = | ||
doAssert false, "not implemented" | ||
|
||
proc deallocImpl(p: pointer) = | ||
discard | ||
|
||
proc allocSharedImpl(size: Natural): pointer = allocImpl(size) | ||
proc allocShared0Impl(size: Natural): pointer = alloc0Impl(size) | ||
proc reallocSharedImpl(p: pointer, newsize: Natural): pointer = reallocImpl(p, newsize) | ||
proc reallocShared0Impl(p: pointer, oldsize, newsize: Natural): pointer = realloc0Impl(p, oldsize, newsize) | ||
proc deallocSharedImpl(p: pointer) = deallocImpl(p) | ||
|
||
when hasThreadSupport: | ||
proc getFreeSharedMem(): int = discard | ||
proc getTotalSharedMem(): int = discard | ||
proc getOccupiedSharedMem(): int = discard | ||
|
||
proc newObj(typ: PNimType, size: int): pointer {.compilerproc.} = | ||
writebarrierptr(addr(result), goMalloc(size.uint)) | ||
if typ.finalizer != nil: | ||
goSetFinalizer(result, typ.finalizer) | ||
|
||
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = | ||
writebarrierptr(addr(result), newObj(typ, size)) | ||
|
||
proc newObjNoInit(typ: PNimType, size: int): pointer = | ||
writebarrierptr(addr(result), newObj(typ, size)) | ||
|
||
proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.} = | ||
writebarrierptr(addr(result), newObj(typ, len * typ.base.size + GenericSeqSize)) | ||
cast[PGenericSeq](result).len = len | ||
cast[PGenericSeq](result).reserved = len | ||
cast[PGenericSeq](result).elemSize = typ.base.size | ||
|
||
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} = | ||
writebarrierptr(addr(result), newSeq(typ, len)) | ||
|
||
proc nimNewSeqOfCap(typ: PNimType, cap: int): pointer {.compilerproc.} = | ||
result = newObj(typ, cap * typ.base.size + GenericSeqSize) | ||
cast[PGenericSeq](result).len = 0 | ||
cast[PGenericSeq](result).reserved = cap | ||
cast[PGenericSeq](result).elemSize = typ.base.size | ||
|
||
proc typedMemMove(dest: pointer, src: pointer, size: uint) {.importc: "typedmemmove", dynlib: goLib.} | ||
|
||
proc growObj(old: pointer, newsize: int): pointer = | ||
# the Go GC doesn't have a realloc | ||
var metadataOld = cast[PGenericSeq](old) | ||
if metadataOld.elemSize == 0: | ||
metadataOld.elemSize = 1 | ||
let oldsize = cast[PGenericSeq](old).len * cast[PGenericSeq](old).elemSize + GenericSeqSize | ||
writebarrierptr(addr(result), goMalloc(newsize.uint)) | ||
typedMemMove(result, old, oldsize.uint) | ||
|
||
proc nimGCref(p: pointer) {.compilerproc, inline.} = discard | ||
proc nimGCunref(p: pointer) {.compilerproc, inline.} = discard | ||
proc nimGCunrefNoCycle(p: pointer) {.compilerProc, inline.} = discard | ||
proc nimGCunrefRC1(p: pointer) {.compilerProc, inline.} = discard | ||
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} = discard | ||
|
||
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = | ||
writebarrierptr(dest, src) | ||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = | ||
writebarrierptr(dest, src) | ||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline, | ||
deprecated: "old compiler compat".} = asgnRef(dest, src) | ||
|
||
type | ||
MemRegion = object | ||
|
||
proc alloc(r: var MemRegion, size: int): pointer = | ||
result = alloc(size) | ||
proc alloc0(r: var MemRegion, size: int): pointer = | ||
result = alloc0Impl(size) | ||
proc dealloc(r: var MemRegion, p: pointer) = dealloc(p) | ||
proc deallocOsPages(r: var MemRegion) {.inline.} = discard | ||
proc deallocOsPages() {.inline.} = discard | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
|
||
proc allocImpl(size: Natural): pointer = | ||
c_malloc(size.csize_t) | ||
|
||
proc alloc0Impl(size: Natural): pointer = | ||
c_calloc(size.csize_t, 1) | ||
|
||
proc reallocImpl(p: pointer, newsize: Natural): pointer = | ||
c_realloc(p, newSize.csize_t) | ||
|
||
proc realloc0Impl(p: pointer, oldsize, newsize: Natural): pointer = | ||
result = realloc(p, newsize.csize_t) | ||
if newsize > oldsize: | ||
zeroMem(cast[pointer](cast[int](result) + oldsize), newsize - oldsize) | ||
|
||
proc deallocImpl(p: pointer) = | ||
c_free(p) | ||
|
||
|
||
# The shared allocators map on the regular ones | ||
|
||
proc allocSharedImpl(size: Natural): pointer = | ||
allocImpl(size) | ||
|
||
proc allocShared0Impl(size: Natural): pointer = | ||
alloc0Impl(size) | ||
|
||
proc reallocSharedImpl(p: pointer, newsize: Natural): pointer = | ||
reallocImpl(p, newsize) | ||
|
||
proc reallocShared0Impl(p: pointer, oldsize, newsize: Natural): pointer = | ||
realloc0Impl(p, oldsize, newsize) | ||
|
||
proc deallocSharedImpl(p: pointer) = deallocImpl(p) | ||
|
||
|
||
# Empty stubs for the GC | ||
|
||
proc GC_disable() = discard | ||
proc GC_enable() = discard | ||
proc GC_fullCollect() = discard | ||
proc GC_setStrategy(strategy: GC_Strategy) = discard | ||
proc GC_enableMarkAndSweep() = discard | ||
proc GC_disableMarkAndSweep() = discard | ||
|
||
proc getOccupiedMem(): int = discard | ||
proc getFreeMem(): int = discard | ||
proc getTotalMem(): int = discard | ||
|
||
proc nimGC_setStackBottom(theStackBottom: pointer) = discard | ||
|
||
proc initGC() = discard | ||
|
||
proc newObjNoInit(typ: PNimType, size: int): pointer = | ||
result = alloc(size) | ||
|
||
proc growObj(old: pointer, newsize: int): pointer = | ||
result = realloc(old, newsize) | ||
|
||
proc nimGCref(p: pointer) {.compilerproc, inline.} = discard | ||
proc nimGCunref(p: pointer) {.compilerproc, inline.} = discard | ||
|
||
proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = | ||
dest[] = src | ||
proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = | ||
dest[] = src | ||
proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline, | ||
deprecated: "old compiler compat".} = asgnRef(dest, src) | ||
|
||
type | ||
MemRegion = object | ||
|
||
proc alloc(r: var MemRegion, size: int): pointer = | ||
result = alloc(size) | ||
proc alloc0Impl(r: var MemRegion, size: int): pointer = | ||
result = alloc0Impl(size) | ||
proc dealloc(r: var MemRegion, p: pointer) = dealloc(p) | ||
proc deallocOsPages(r: var MemRegion) {.inline.} = discard | ||
proc deallocOsPages() {.inline.} = discard | ||
|
Oops, something went wrong.