diff options
author | Mike Pall <mike> | 2010-03-04 16:27:42 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-03-04 16:27:42 +0100 |
commit | f76e5a311ba543ae174acd3b585fb672fde8a3b5 (patch) | |
tree | 98b04ad6e7c3e9b793353328ea589879b6f57f29 /src | |
parent | 3d2abf3148c2280b0fd018cd179acd30099c5ed7 (diff) | |
download | luajit-f76e5a311ba543ae174acd3b585fb672fde8a3b5.tar.gz luajit-f76e5a311ba543ae174acd3b585fb672fde8a3b5.tar.bz2 luajit-f76e5a311ba543ae174acd3b585fb672fde8a3b5.zip |
Allocate 32 bit memory on OSX/x64 with mmap() hinting.
Must set -pagezero_size, otherwise the lower 4GB are blocked.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/lj_alloc.c | 45 |
2 files changed, 43 insertions, 5 deletions
diff --git a/src/Makefile b/src/Makefile index a9ad8eb9..9a071246 100644 --- a/src/Makefile +++ b/src/Makefile | |||
@@ -227,6 +227,9 @@ ifeq (Darwin,$(TARGET_SYS)) | |||
227 | TARGET_DYNXLDOPTS= | 227 | TARGET_DYNXLDOPTS= |
228 | TARGET_XSHLDFLAGS+= -install_name $(PREFIX)/lib/$(TARGET_DYLIBNAME) | 228 | TARGET_XSHLDFLAGS+= -install_name $(PREFIX)/lib/$(TARGET_DYLIBNAME) |
229 | endif | 229 | endif |
230 | ifeq (x64,$(TARGET_CCARCH)) | ||
231 | TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000 | ||
232 | endif | ||
230 | else | 233 | else |
231 | TARGET_XLDFLAGS+= -Wl,-E | 234 | TARGET_XLDFLAGS+= -Wl,-E |
232 | ifeq (Linux,$(TARGET_SYS)) | 235 | ifeq (Linux,$(TARGET_SYS)) |
diff --git a/src/lj_alloc.c b/src/lj_alloc.c index 58887469..b027899a 100644 --- a/src/lj_alloc.c +++ b/src/lj_alloc.c | |||
@@ -164,23 +164,58 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) | |||
164 | #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) | 164 | #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) |
165 | 165 | ||
166 | #if LJ_64 | 166 | #if LJ_64 |
167 | /* Need special support for allocating memory in the lower 2GB. */ | 167 | /* 64 bit mode needs special support for allocating memory in the lower 2GB. */ |
168 | 168 | ||
169 | #if defined(__linux__) | 169 | #if defined(__linux__) |
170 | |||
170 | /* Actually this only gives us max. 1GB in current Linux kernels. */ | 171 | /* Actually this only gives us max. 1GB in current Linux kernels. */ |
171 | #define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0) | 172 | #define CALL_MMAP(s) mmap(NULL, (s), MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0) |
173 | |||
172 | #elif defined(__MACH__) && defined(__APPLE__) | 174 | #elif defined(__MACH__) && defined(__APPLE__) |
173 | #error "NYI: no support for 64 bit OSX (yet)" | 175 | |
176 | /* OSX mmap() uses a naive first-fit linear search. That's perfect for us. | ||
177 | ** But -pagezero_size must be set, otherwise the lower 4GB are blocked. | ||
178 | */ | ||
179 | #define MMAP_REGION_START ((uintptr_t)0x10000) | ||
180 | #define MMAP_REGION_END ((uintptr_t)0x80000000) | ||
181 | |||
182 | static LJ_AINLINE void *CALL_MMAP(size_t size) | ||
183 | { | ||
184 | /* Hint for next allocation. Doesn't need to be thread-safe. */ | ||
185 | static uintptr_t alloc_hint = MMAP_REGION_START; | ||
186 | int retry = 0; | ||
187 | for (;;) { | ||
188 | void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0); | ||
189 | if ((uintptr_t)p >= MMAP_REGION_START && | ||
190 | (uintptr_t)p + size < MMAP_REGION_END) { | ||
191 | alloc_hint = (uintptr_t)p + size; | ||
192 | return p; | ||
193 | } | ||
194 | if (p != CMFAIL) munmap(p, size); | ||
195 | if (retry) break; | ||
196 | retry = 1; | ||
197 | alloc_hint = MMAP_REGION_START; | ||
198 | } | ||
199 | return CMFAIL; | ||
200 | } | ||
201 | |||
174 | #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | 202 | #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) |
203 | |||
175 | /* FreeBSD 64 bit kernel ignores mmap() hints for lower 32GB of memory. */ | 204 | /* FreeBSD 64 bit kernel ignores mmap() hints for lower 32GB of memory. */ |
176 | /* See /usr/src/sys/vm/vm_mmap.c near RLIMIT_DATA. */ | 205 | /* See: grep -C15 RLIMIT_DATA /usr/src/sys/vm/vm_mmap.c */ |
177 | #error "No support for 64 bit FreeBSD" | 206 | #error "No support for 64 bit FreeBSD" |
207 | |||
178 | #else | 208 | #else |
209 | |||
179 | #error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS" | 210 | #error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS" |
211 | |||
180 | #endif | 212 | #endif |
181 | 213 | ||
182 | #else | 214 | #else |
183 | #define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) | 215 | |
216 | /* 32 bit mode is easy. */ | ||
217 | #define CALL_MMAP(s) mmap(NULL, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) | ||
218 | |||
184 | #endif | 219 | #endif |
185 | 220 | ||
186 | #define INIT_MMAP() ((void)0) | 221 | #define INIT_MMAP() ((void)0) |