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 /src | |
parent | 62fafb5a72d0f2054d8111cf9d3c698f54d6d9e6 (diff) | |
download | luajit-49e3bdf080ed2ff0f64332aa2b4997061021967f.tar.gz luajit-49e3bdf080ed2ff0f64332aa2b4997061021967f.tar.bz2 luajit-49e3bdf080ed2ff0f64332aa2b4997061021967f.zip |
Allocate 32 bit memory on WIN64 using NtAllocateVirtualMemory.
Diffstat (limited to 'src')
-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; |