diff options
| author | Mike Pall <mike> | 2010-01-17 20:20:43 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-01-17 20:20:43 +0100 |
| commit | 49e3bdf080ed2ff0f64332aa2b4997061021967f (patch) | |
| tree | 91ca39a62c34c8c46d4c7d510ac2151e1ec87db6 | |
| parent | 62fafb5a72d0f2054d8111cf9d3c698f54d6d9e6 (diff) | |
| download | luajit-49e3bdf080ed2ff0f64332aa2b4997061021967f.tar.gz luajit-49e3bdf080ed2ff0f64332aa2b4997061021967f.tar.bz2 luajit-49e3bdf080ed2ff0f64332aa2b4997061021967f.zip | |
Allocate 32 bit memory on WIN64 using NtAllocateVirtualMemory.
| -rw-r--r-- | src/lj_alloc.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/src/lj_alloc.c b/src/lj_alloc.c index e4a9d356..c8e4910d 100644 --- a/src/lj_alloc.c +++ b/src/lj_alloc.c | |||
| @@ -74,18 +74,54 @@ | |||
| 74 | 74 | ||
| 75 | #ifdef LUA_USE_WIN | 75 | #ifdef LUA_USE_WIN |
| 76 | 76 | ||
| 77 | #if LJ_64 | ||
| 78 | #error "missing support for WIN64 to allocate in lower 2G" | ||
| 79 | #endif | ||
| 80 | |||
| 81 | #define WIN32_LEAN_AND_MEAN | 77 | #define WIN32_LEAN_AND_MEAN |
| 82 | #include <windows.h> | 78 | #include <windows.h> |
| 83 | 79 | ||
| 80 | #if LJ_64 | ||
| 81 | |||
| 82 | /* Undocumented, but hey, that's what we all love so much about Windows. */ | ||
| 83 | typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits, | ||
| 84 | size_t *size, ULONG alloctype, ULONG prot); | ||
| 85 | static PNTAVM ntavm; | ||
| 86 | |||
| 87 | /* Number of top bits of the lower 32 bits of an address that must be zero. | ||
| 88 | ** Apparently 0 gives us full 64 bit addresses and 1 gives us the lower 2GB. | ||
| 89 | */ | ||
| 90 | #define NTAVM_ZEROBITS 1 | ||
| 91 | |||
| 92 | static void INIT_MMAP(void) | ||
| 93 | { | ||
| 94 | ntavm = (PNTAVM)GetProcAddress(GetModuleHandle("ntdll.dll"), | ||
| 95 | "NtAllocateVirtualMemory"); | ||
| 96 | } | ||
| 97 | |||
| 98 | /* Win64 32 bit MMAP via NtAllocateVirtualMemory. */ | ||
| 99 | static LJ_AINLINE void *CALL_MMAP(size_t size) | ||
| 100 | { | ||
| 101 | void *ptr = NULL; | ||
| 102 | long st = ntavm(INVALID_HANDLE_VALUE, &ptr, NTAVM_ZEROBITS, &size, | ||
| 103 | MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); | ||
| 104 | return st == 0 ? ptr : MFAIL; | ||
| 105 | } | ||
| 106 | |||
| 107 | /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ | ||
| 108 | static LJ_AINLINE void *DIRECT_MMAP(size_t size) | ||
| 109 | { | ||
| 110 | void *ptr = NULL; | ||
| 111 | long st = ntavm(INVALID_HANDLE_VALUE, &ptr, NTAVM_ZEROBITS, &size, | ||
| 112 | MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE); | ||
| 113 | return st == 0 ? ptr : MFAIL; | ||
| 114 | } | ||
| 115 | |||
| 116 | #else | ||
| 117 | |||
| 118 | #define INIT_MMAP() ((void)0) | ||
| 119 | |||
| 84 | /* Win32 MMAP via VirtualAlloc */ | 120 | /* Win32 MMAP via VirtualAlloc */ |
| 85 | static LJ_AINLINE void *CALL_MMAP(size_t size) | 121 | static LJ_AINLINE void *CALL_MMAP(size_t size) |
| 86 | { | 122 | { |
| 87 | void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); | 123 | void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); |
| 88 | return (ptr != 0)? ptr: MFAIL; | 124 | return ptr ? ptr : MFAIL; |
| 89 | } | 125 | } |
| 90 | 126 | ||
| 91 | /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ | 127 | /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ |
| @@ -93,9 +129,11 @@ static LJ_AINLINE void *DIRECT_MMAP(size_t size) | |||
| 93 | { | 129 | { |
| 94 | void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, | 130 | void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, |
| 95 | PAGE_READWRITE); | 131 | PAGE_READWRITE); |
| 96 | return (ptr != 0)? ptr: MFAIL; | 132 | return ptr ? ptr : MFAIL; |
| 97 | } | 133 | } |
| 98 | 134 | ||
| 135 | #endif | ||
| 136 | |||
| 99 | /* This function supports releasing coalesed segments */ | 137 | /* This function supports releasing coalesed segments */ |
| 100 | static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) | 138 | static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) |
| 101 | { | 139 | { |
| @@ -130,6 +168,7 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) | |||
| 130 | #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) | 168 | #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) |
| 131 | #endif | 169 | #endif |
| 132 | 170 | ||
| 171 | #define INIT_MMAP() ((void)0) | ||
| 133 | #define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) | 172 | #define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) |
| 134 | #define DIRECT_MMAP(s) CALL_MMAP(s) | 173 | #define DIRECT_MMAP(s) CALL_MMAP(s) |
| 135 | #define CALL_MUNMAP(a, s) munmap((a), (s)) | 174 | #define CALL_MUNMAP(a, s) munmap((a), (s)) |
| @@ -989,7 +1028,9 @@ static void *tmalloc_small(mstate m, size_t nb) | |||
| 989 | void *lj_alloc_create(void) | 1028 | void *lj_alloc_create(void) |
| 990 | { | 1029 | { |
| 991 | size_t tsize = DEFAULT_GRANULARITY; | 1030 | size_t tsize = DEFAULT_GRANULARITY; |
| 992 | char *tbase = (char *)(CALL_MMAP(tsize)); | 1031 | char *tbase; |
| 1032 | INIT_MMAP(); | ||
| 1033 | tbase = (char *)(CALL_MMAP(tsize)); | ||
| 993 | if (tbase != CMFAIL) { | 1034 | if (tbase != CMFAIL) { |
| 994 | size_t msize = pad_request(sizeof(struct malloc_state)); | 1035 | size_t msize = pad_request(sizeof(struct malloc_state)); |
| 995 | mchunkptr mn; | 1036 | mchunkptr mn; |
