diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2021-07-15 17:58:47 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-15 17:58:47 +0200 |
commit | af3d2d8ad90c31161c34f0d4f82cd0ac4a9b3d00 (patch) | |
tree | 24e40815489abb750b4a9c6ca6e46bea7c8f94dc /lib | |
parent | 8c6dd2b9a9157c0e0bd822d8a80d1014fc87ecd7 (diff) | |
download | Nim-af3d2d8ad90c31161c34f0d4f82cd0ac4a9b3d00.tar.gz |
added `nimAllocPagesViaMalloc` switch (#18490)
* added switch * alloc.nim needs page aligned memory blocks
Diffstat (limited to 'lib')
-rw-r--r-- | lib/system/alloc.nim | 3 | ||||
-rw-r--r-- | lib/system/osalloc.nim | 31 |
2 files changed, 29 insertions, 5 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index c598b8250..479458950 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -749,8 +749,9 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = 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") var size = roundup(requestedSize, MemAlign) + sysAssert(size >= sizeof(FreeCell), "rawAlloc: requested size too small") + sysAssert(size >= requestedSize, "insufficient allocated size!") #c_fprintf(stdout, "alloc; size: %ld; %ld\n", requestedSize, size) if size <= SmallChunkSize-smallChunkOverhead(): diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim index 32d3b166d..2830adb48 100644 --- a/lib/system/osalloc.nim +++ b/lib/system/osalloc.nim @@ -28,7 +28,30 @@ const doNotUnmap = not (defined(amd64) or defined(i386)) or defined(windows) or defined(nimAllocNoUnmap) -when defined(emscripten) and not defined(StandaloneHeapSize): +when defined(nimAllocPagesViaMalloc): + when not defined(gcArc) and not defined(gcOrc): + {.error: "-d:nimAllocPagesViaMalloc is only supported with --gc:arc or --gc:orc".} + + proc osTryAllocPages(size: int): pointer {.inline.} = + let base = c_malloc(csize_t size + PageSize - 1 + sizeof(uint32)) + if base == nil: raiseOutOfMem() + # memory layout: padding + offset (4 bytes) + user_data + # in order to deallocate: read offset at user_data - 4 bytes, + # then deallocate user_data - offset + let offset = PageSize - (cast[int](base) and (PageSize - 1)) + cast[ptr uint32](base +! (offset - sizeof(uint32)))[] = uint32(offset) + result = base +! offset + + proc osAllocPages(size: int): pointer {.inline.} = + result = osTryAllocPages(size) + if result == nil: raiseOutOfMem() + + proc osDeallocPages(p: pointer, size: int) {.inline.} = + # read offset at p - 4 bytes, then deallocate (p - offset) pointer + let offset = cast[ptr uint32](p -! sizeof(uint32))[] + c_free(p -! offset) + +elif defined(emscripten) and not defined(StandaloneHeapSize): const PROT_READ = 1 # page can be read PROT_WRITE = 2 # page can be written @@ -197,11 +220,11 @@ elif defined(posix) and not defined(StandaloneHeapSize): PROT_WRITE = 2 # page can be written when defined(netbsd) or defined(openbsd): - # OpenBSD security for setjmp/longjmp coroutines - var MAP_STACK {.importc: "MAP_STACK", header: "<sys/mman.h>".}: cint + # OpenBSD security for setjmp/longjmp coroutines + var MAP_STACK {.importc: "MAP_STACK", header: "<sys/mman.h>".}: cint else: const MAP_STACK = 0 # avoid sideeffects - + when defined(macosx) or defined(freebsd): const MAP_ANONYMOUS = 0x1000 const MAP_PRIVATE = 0x02 # Changes are private |