diff options
author | Mike Pall <mike> | 2010-10-23 16:31:27 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-10-23 16:31:27 +0200 |
commit | 08b0ede194ae790775661a6b36a17d3f6cca873f (patch) | |
tree | d0d837fe2867d1b19a8bba8bacf0c671ab2cc2f0 /src | |
parent | 02dc9d1082738bb75450ef6dbf4e0bf32a1553db (diff) | |
download | luajit-08b0ede194ae790775661a6b36a17d3f6cca873f.tar.gz luajit-08b0ede194ae790775661a6b36a17d3f6cca873f.tar.bz2 luajit-08b0ede194ae790775661a6b36a17d3f6cca873f.zip |
Reduce 32GB RLIMIT_DATA on FreeBSD/x64 to allocate low-2GB memory.
Thanks to Tony Finch.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_alloc.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/lj_alloc.c b/src/lj_alloc.c index b027899a..2c686597 100644 --- a/src/lj_alloc.c +++ b/src/lj_alloc.c | |||
@@ -171,12 +171,20 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) | |||
171 | /* Actually this only gives us max. 1GB in current Linux kernels. */ | 171 | /* Actually this only gives us max. 1GB in current Linux kernels. */ |
172 | #define CALL_MMAP(s) mmap(NULL, (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 | 173 | ||
174 | #elif defined(__MACH__) && defined(__APPLE__) | 174 | #elif (defined(__MACH__) && defined(__APPLE__)) || \ |
175 | defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | ||
175 | 176 | ||
176 | /* OSX mmap() uses a naive first-fit linear search. That's perfect for us. | 177 | /* OSX and FreeBSD mmap() use a naive first-fit linear search. |
177 | ** But -pagezero_size must be set, otherwise the lower 4GB are blocked. | 178 | ** That's perfect for us. Except that -pagezero_size must be set for OSX, |
179 | ** otherwise the lower 4GB are blocked. And the 32GB RLIMIT_DATA needs | ||
180 | ** to be reduced to 250MB on FreeBSD. | ||
178 | */ | 181 | */ |
182 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | ||
183 | #include <sys/resource.h> | ||
184 | #define MMAP_REGION_START ((uintptr_t)0x10000000) | ||
185 | #else | ||
179 | #define MMAP_REGION_START ((uintptr_t)0x10000) | 186 | #define MMAP_REGION_START ((uintptr_t)0x10000) |
187 | #endif | ||
180 | #define MMAP_REGION_END ((uintptr_t)0x80000000) | 188 | #define MMAP_REGION_END ((uintptr_t)0x80000000) |
181 | 189 | ||
182 | static LJ_AINLINE void *CALL_MMAP(size_t size) | 190 | static LJ_AINLINE void *CALL_MMAP(size_t size) |
@@ -184,6 +192,15 @@ static LJ_AINLINE void *CALL_MMAP(size_t size) | |||
184 | /* Hint for next allocation. Doesn't need to be thread-safe. */ | 192 | /* Hint for next allocation. Doesn't need to be thread-safe. */ |
185 | static uintptr_t alloc_hint = MMAP_REGION_START; | 193 | static uintptr_t alloc_hint = MMAP_REGION_START; |
186 | int retry = 0; | 194 | int retry = 0; |
195 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | ||
196 | static int rlimit_modified = 0; | ||
197 | if (LJ_UNLIKELY(rlimit_modified == 0)) { | ||
198 | struct rlimit rlim; | ||
199 | rlim.rlim_cur = rlim.rlim_max = MMAP_REGION_START; | ||
200 | setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail below. */ | ||
201 | rlimit_modified = 1; | ||
202 | } | ||
203 | #endif | ||
187 | for (;;) { | 204 | for (;;) { |
188 | void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0); | 205 | void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0); |
189 | if ((uintptr_t)p >= MMAP_REGION_START && | 206 | if ((uintptr_t)p >= MMAP_REGION_START && |
@@ -199,12 +216,6 @@ static LJ_AINLINE void *CALL_MMAP(size_t size) | |||
199 | return CMFAIL; | 216 | return CMFAIL; |
200 | } | 217 | } |
201 | 218 | ||
202 | #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | ||
203 | |||
204 | /* FreeBSD 64 bit kernel ignores mmap() hints for lower 32GB of memory. */ | ||
205 | /* See: grep -C15 RLIMIT_DATA /usr/src/sys/vm/vm_mmap.c */ | ||
206 | #error "No support for 64 bit FreeBSD" | ||
207 | |||
208 | #else | 219 | #else |
209 | 220 | ||
210 | #error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS" | 221 | #error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS" |