|
@@ -171,12 +171,20 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
|
|
/* Actually this only gives us max. 1GB in current Linux kernels. */
|
|
/* Actually this only gives us max. 1GB in current Linux kernels. */
|
|
#define CALL_MMAP(s) mmap(NULL, (s), MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0)
|
|
#define CALL_MMAP(s) mmap(NULL, (s), MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0)
|
|
|
|
|
|
-#elif defined(__MACH__) && defined(__APPLE__)
|
|
|
|
|
|
+#elif (defined(__MACH__) && defined(__APPLE__)) || \
|
|
|
|
+ defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
|
|
|
|
|
-/* OSX mmap() uses a naive first-fit linear search. That's perfect for us.
|
|
|
|
-** But -pagezero_size must be set, otherwise the lower 4GB are blocked.
|
|
|
|
|
|
+/* OSX and FreeBSD mmap() use a naive first-fit linear search.
|
|
|
|
+** That's perfect for us. Except that -pagezero_size must be set for OSX,
|
|
|
|
+** otherwise the lower 4GB are blocked. And the 32GB RLIMIT_DATA needs
|
|
|
|
+** to be reduced to 250MB on FreeBSD.
|
|
*/
|
|
*/
|
|
|
|
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
|
|
|
+#include <sys/resource.h>
|
|
|
|
+#define MMAP_REGION_START ((uintptr_t)0x10000000)
|
|
|
|
+#else
|
|
#define MMAP_REGION_START ((uintptr_t)0x10000)
|
|
#define MMAP_REGION_START ((uintptr_t)0x10000)
|
|
|
|
+#endif
|
|
#define MMAP_REGION_END ((uintptr_t)0x80000000)
|
|
#define MMAP_REGION_END ((uintptr_t)0x80000000)
|
|
|
|
|
|
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
|
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
|
@@ -184,6 +192,15 @@ static LJ_AINLINE void *CALL_MMAP(size_t size)
|
|
/* Hint for next allocation. Doesn't need to be thread-safe. */
|
|
/* Hint for next allocation. Doesn't need to be thread-safe. */
|
|
static uintptr_t alloc_hint = MMAP_REGION_START;
|
|
static uintptr_t alloc_hint = MMAP_REGION_START;
|
|
int retry = 0;
|
|
int retry = 0;
|
|
|
|
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
|
|
|
+ static int rlimit_modified = 0;
|
|
|
|
+ if (LJ_UNLIKELY(rlimit_modified == 0)) {
|
|
|
|
+ struct rlimit rlim;
|
|
|
|
+ rlim.rlim_cur = rlim.rlim_max = MMAP_REGION_START;
|
|
|
|
+ setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail below. */
|
|
|
|
+ rlimit_modified = 1;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
for (;;) {
|
|
for (;;) {
|
|
void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
|
|
void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
|
|
if ((uintptr_t)p >= MMAP_REGION_START &&
|
|
if ((uintptr_t)p >= MMAP_REGION_START &&
|
|
@@ -199,12 +216,6 @@ static LJ_AINLINE void *CALL_MMAP(size_t size)
|
|
return CMFAIL;
|
|
return CMFAIL;
|
|
}
|
|
}
|
|
|
|
|
|
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
|
|
|
-
|
|
|
|
-/* FreeBSD 64 bit kernel ignores mmap() hints for lower 32GB of memory. */
|
|
|
|
-/* See: grep -C15 RLIMIT_DATA /usr/src/sys/vm/vm_mmap.c */
|
|
|
|
-#error "No support for 64 bit FreeBSD"
|
|
|
|
-
|
|
|
|
#else
|
|
#else
|
|
|
|
|
|
#error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS"
|
|
#error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS"
|