aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-10-23 16:31:27 +0200
committerMike Pall <mike>2010-10-23 16:31:27 +0200
commit08b0ede194ae790775661a6b36a17d3f6cca873f (patch)
treed0d837fe2867d1b19a8bba8bacf0c671ab2cc2f0 /src
parent02dc9d1082738bb75450ef6dbf4e0bf32a1553db (diff)
downloadluajit-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.c29
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
182static LJ_AINLINE void *CALL_MMAP(size_t size) 190static 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"