aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-01-17 20:20:43 +0100
committerMike Pall <mike>2010-01-17 20:20:43 +0100
commit49e3bdf080ed2ff0f64332aa2b4997061021967f (patch)
tree91ca39a62c34c8c46d4c7d510ac2151e1ec87db6 /src
parent62fafb5a72d0f2054d8111cf9d3c698f54d6d9e6 (diff)
downloadluajit-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.c55
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. */
83typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits,
84 size_t *size, ULONG alloctype, ULONG prot);
85static 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
92static void INIT_MMAP(void)
93{
94 ntavm = (PNTAVM)GetProcAddress(GetModuleHandle("ntdll.dll"),
95 "NtAllocateVirtualMemory");
96}
97
98/* Win64 32 bit MMAP via NtAllocateVirtualMemory. */
99static 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 */
108static 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 */
85static LJ_AINLINE void *CALL_MMAP(size_t size) 121static 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 */
100static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) 138static 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)
989void *lj_alloc_create(void) 1028void *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;