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) |
