diff --git a/moo/configure b/moo/configure index 3b75ae0..35c7504 100755 --- a/moo/configure +++ b/moo/configure @@ -18225,7 +18225,7 @@ fi done -for ac_header in dlfcn.h ltdl.h +for ac_header in dlfcn.h ltdl.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -18361,12 +18361,13 @@ _ACEOF fi done -for ac_func in isatty +for ac_func in isatty mmap munmap do : - ac_fn_c_check_func "$LINENO" "isatty" "ac_cv_func_isatty" -if test "x$ac_cv_func_isatty" = xyes; then : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_ISATTY 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi diff --git a/moo/configure.ac b/moo/configure.ac index 7e4e556..7b7bcb9 100644 --- a/moo/configure.ac +++ b/moo/configure.ac @@ -127,7 +127,7 @@ dnl check header files. AC_HEADER_STDC AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h dirent.h]) AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h]) -AC_CHECK_HEADERS([dlfcn.h ltdl.h]) +AC_CHECK_HEADERS([dlfcn.h ltdl.h sys/mman.h]) AC_CHECK_HEADERS([sys/devpoll.h sys/epoll.h poll.h]) AC_CHECK_HEADERS([dyncall.h]) AC_CHECK_HEADERS([xcb/xcb.h]) @@ -147,7 +147,7 @@ AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext]) AC_CHECK_FUNCS([clock_nanosleep nanosleep usleep]) AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf strerror_r]) AC_CHECK_FUNCS([accept4]) -AC_CHECK_FUNCS([isatty]) +AC_CHECK_FUNCS([isatty mmap munmap]) save_LIBS="$LIBS" AC_SEARCH_LIBS([dlopen], [dl dld], [ diff --git a/moo/lib/main.c b/moo/lib/main.c index a9a6bf8..1a85bfc 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -101,6 +101,9 @@ # if defined(HAVE_SIGNAL_H) # include # endif +# if defined(HAVE_SYS_MMAN_H) +# include +# endif # include # include @@ -483,14 +486,65 @@ static moo_ooi_t input_handler (moo_t* moo, moo_iocmd_t cmd, moo_ioarg_t* arg) static void* alloc_heap (moo_t* moo, moo_oow_t size) { +#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(MAP_ANONYMOUS) + /* It's called via moo_makeheap() when HCL creates a GC heap. + * The heap is large in size. I can use a different memory allocation + * function instead of an ordinary malloc. + * upon failure, it doesn't require to set error information as moo_makeheap() + * set the error number to MOO_EOOMEM. */ + +#if !defined(MAP_HUGETLB) && (defined(__amd64__) || defined(__x86_64__)) +# define MAP_HUGETLB 0x40000 +#endif + + moo_oow_t* ptr; + int flags; + moo_oow_t actual_size; + + flags = MAP_PRIVATE | MAP_ANONYMOUS; + + #if defined(MAP_HUGETLB) + flags |= MAP_HUGETLB; + #endif + + #if defined(MAP_UNINITIALIZED) + flags |= MAP_UNINITIALIZED; + #endif + + actual_size = MOO_SIZEOF(moo_oow_t) + size; + actual_size = MOO_ALIGN_POW2(actual_size, 2 * 1024 * 1024); + ptr = (moo_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == MAP_FAILED) + { + #if defined(MAP_HUGETLB) + flags &= ~MAP_HUGETLB; + ptr = (moo_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == MAP_FAILED) return MOO_NULL; + #else + return MOO_NULL; + #endif + } + *ptr = actual_size; + + return (void*)(ptr + 1); + +#else return MOO_MMGR_ALLOC(moo->mmgr, size); +#endif } static void free_heap (moo_t* moo, void* ptr) { +#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) + moo_oow_t* actual_ptr; + actual_ptr = (moo_oow_t*)ptr - 1; + munmap (actual_ptr, *actual_ptr); +#else return MOO_MMGR_FREE(moo->mmgr, ptr); +#endif } + #if defined(_WIN32) /* nothing to do */ @@ -2228,6 +2282,7 @@ int main (int argc, char* argv[]) { { ":log", 'l' }, { ":memsize", 'm' }, + { "large-pages", '\0' }, #if defined(MOO_BUILD_DEBUG) { ":debug", '\0' }, /* NOTE: there is no short option for --debug */ #endif @@ -2241,6 +2296,7 @@ int main (int argc, char* argv[]) const char* logopt = MOO_NULL; moo_oow_t memsize = MIN_MEMSIZE; + int large_pages = 0; #if defined(MOO_BUILD_DEBUG) const char* dbgopt = MOO_NULL; @@ -2270,9 +2326,13 @@ int main (int argc, char* argv[]) break; case '\0': - + if (moo_compbcstr(opt.lngopt, "large-pages") == 0) + { + large_pages = 1; + break; + } #if defined(MOO_BUILD_DEBUG) - if (moo_compbcstr(opt.lngopt, "debug") == 0) + else if (moo_compbcstr(opt.lngopt, "debug") == 0) { dbgopt = opt.arg; break; @@ -2298,8 +2358,11 @@ int main (int argc, char* argv[]) #endif memset (&vmprim, 0, MOO_SIZEOF(vmprim)); - vmprim.alloc_heap = alloc_heap; - vmprim.free_heap = free_heap; + if (large_pages) + { + vmprim.alloc_heap = alloc_heap; + vmprim.free_heap = free_heap; + } vmprim.log_write = log_write; vmprim.syserrstrb = syserrstrb; vmprim.dl_open = dl_open; diff --git a/moo/lib/moo-cfg.h.in b/moo/lib/moo-cfg.h.in index 348ca87..b159655 100644 --- a/moo/lib/moo-cfg.h.in +++ b/moo/lib/moo-cfg.h.in @@ -114,6 +114,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP @@ -204,6 +210,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EPOLL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H