From 9094157e284d6994cc1d4dd530797921142f88cb Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 1 Mar 2018 14:47:12 +0000 Subject: [PATCH] fixed print_formatted() to use hcl_outfmtobj() instead of hcl_print(). added 2 new optional callbacks - vmprim.alloc_heap and vmprim.free_heap --- lib/err.c | 2 - lib/hcl.c | 24 ++- lib/hcl.h | 31 +++- lib/heap.c | 4 +- lib/logfmt.c | 6 +- lib/main.c | 411 +++++++++++++++++++++++++++++---------------------- 6 files changed, 277 insertions(+), 201 deletions(-) diff --git a/lib/err.c b/lib/err.c index cfa211c..f1f5ada 100644 --- a/lib/err.c +++ b/lib/err.c @@ -321,7 +321,6 @@ void hcl_seterrwithsyserr (hcl_t* hcl, int syserr) } } - void hcl_getsynerr (hcl_t* hcl, hcl_synerr_t* synerr) { HCL_ASSERT (hcl, hcl->c != HCL_NULL); @@ -445,7 +444,6 @@ void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_FATAL, "ASSERTION FAILURE: %s at %s:%zu\n", expr, file, line); - #if defined(HAVE_BACKTRACE) btsize = backtrace (btarray, HCL_COUNTOF(btarray)); btsyms = backtrace_symbols (btarray, btsize); diff --git a/lib/hcl.c b/lib/hcl.c index 3bf4385..24bde46 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -83,6 +83,16 @@ static void fill_bigint_tables (hcl_t* hcl) } } +static void* alloc_heap (hcl_t* hcl, hcl_oow_t size) +{ + return HCL_MMGR_ALLOC(hcl->mmgr, size); +} + +static void free_heap (hcl_t* hcl, void* ptr) +{ + return HCL_MMGR_FREE(hcl->mmgr, ptr); +} + int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t* vmprim) { int modtab_inited = 0; @@ -97,6 +107,8 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t hcl->mmgr = mmgr; hcl->cmgr = hcl_getutf8cmgr(); hcl->vmprim = *vmprim; + if (!hcl->vmprim.alloc_heap) hcl->vmprim.alloc_heap = alloc_heap; + if (!hcl->vmprim.free_heap) hcl->vmprim.free_heap = free_heap; hcl->option.log_mask = ~0u; hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA; @@ -113,19 +125,19 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t * routine still function despite some side-effects when * reallocation fails */ /* +1 required for consistency with put_oocs and put_ooch in logfmt.c */ - hcl->log.ptr = (hcl_ooch_t*)hcl_allocmem (hcl, (hcl->log.capa + 1) * HCL_SIZEOF(*hcl->log.ptr)); + hcl->log.ptr = (hcl_ooch_t*)hcl_allocmem(hcl, (hcl->log.capa + 1) * HCL_SIZEOF(*hcl->log.ptr)); if (!hcl->log.ptr) goto oops; /*hcl->permheap = hcl_makeheap (hcl, what is the best size???); if (!hcl->curheap) goto oops; */ - hcl->curheap = hcl_makeheap (hcl, heapsz); + hcl->curheap = hcl_makeheap(hcl, heapsz); if (!hcl->curheap) goto oops; - hcl->newheap = hcl_makeheap (hcl, heapsz); + hcl->newheap = hcl_makeheap(hcl, heapsz); if (!hcl->newheap) goto oops; - if (hcl_rbt_init (&hcl->modtab, hcl, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops; + if (hcl_rbt_init(&hcl->modtab, hcl, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops; modtab_inited = 1; - hcl_rbt_setstyle (&hcl->modtab, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS)); + hcl_rbt_setstyle(&hcl->modtab, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS)); fill_bigint_tables (hcl); @@ -241,7 +253,7 @@ void hcl_fini (hcl_t* hcl) hcl_killheap (hcl, hcl->newheap); hcl_killheap (hcl, hcl->curheap); - hcl_killheap (hcl, hcl->permheap); + if (hcl->permheap) hcl_killheap (hcl, hcl->permheap); if (hcl->log.ptr) { diff --git a/lib/hcl.h b/lib/hcl.h index 3cc24d9..c692b66 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -686,6 +686,14 @@ struct hcl_heap_t /* ========================================================================= * VIRTUAL MACHINE PRIMITIVES * ========================================================================= */ + +typedef void* (*hcl_alloc_heap_t) (hcl_t* hcl, hcl_oow_t size); +typedef void (*hcl_free_heap_t) (hcl_t* hcl, void* ptr); + +typedef void (*hcl_log_write_t) (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len); +typedef void (*hcl_syserrstrb_t) (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len); +typedef void (*hcl_syserrstru_t) (hcl_t* hcl, int syserr, hcl_uch_t* buf, hcl_oow_t len); + enum hcl_vmprim_opendl_flag_t { HCL_VMPRIM_OPENDL_PFMOD = (1 << 0) @@ -696,27 +704,34 @@ typedef void* (*hcl_vmprim_dlopen_t) (hcl_t* hcl, const hcl_ooch_t* name, int fl typedef void (*hcl_vmprim_dlclose_t) (hcl_t* hcl, void* handle); typedef void* (*hcl_vmprim_dlgetsym_t) (hcl_t* hcl, void* handle, const hcl_ooch_t* name); -typedef void (*hcl_log_write_t) (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len); -typedef void (*hcl_syserrstrb_t) (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len); -typedef void (*hcl_syserrstru_t) (hcl_t* hcl, int syserr, hcl_uch_t* buf, hcl_oow_t len); - typedef int (*hcl_vmprim_startup_t) (hcl_t* hcl); typedef void (*hcl_vmprim_cleanup_t) (hcl_t* hcl); typedef void (*hcl_vmprim_gettime_t) (hcl_t* hcl, hcl_ntime_t* now); - typedef void (*hcl_vmprim_sleep_t) (hcl_t* hcl, const hcl_ntime_t* duration); struct hcl_vmprim_t { - hcl_vmprim_dlopen_t dl_open; - hcl_vmprim_dlclose_t dl_close; - hcl_vmprim_dlgetsym_t dl_getsym; + /* The alloc_heap callback function is called very earlier + * before hcl is fully initialized. so few features are availble + * in this callback function. If it's not provided, the default + * implementation is used. */ + hcl_alloc_heap_t alloc_heap; + + /* If you customize the heap allocator by providing the alloc_heap + * callback, you should implement the heap freer. otherwise the default + * implementation doesn't know how to free the heap allocated by + * the allocator callback. */ + hcl_free_heap_t free_heap; hcl_log_write_t log_write; hcl_syserrstrb_t syserrstrb; hcl_syserrstru_t syserrstru; + hcl_vmprim_dlopen_t dl_open; + hcl_vmprim_dlclose_t dl_close; + hcl_vmprim_dlgetsym_t dl_getsym; + hcl_vmprim_startup_t vm_startup; hcl_vmprim_cleanup_t vm_cleanup; hcl_vmprim_gettime_t vm_gettime; diff --git a/lib/heap.c b/lib/heap.c index 11279fe..d14ac79 100644 --- a/lib/heap.c +++ b/lib/heap.c @@ -30,7 +30,7 @@ hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size) { hcl_heap_t* heap; - heap = (hcl_heap_t*)HCL_MMGR_ALLOC(hcl->mmgr, HCL_SIZEOF(*heap) + size); + heap = (hcl_heap_t*)hcl->vmprim.alloc_heap(hcl, HCL_SIZEOF(*heap) + size); if (!heap) { hcl_seterrnum (hcl, HCL_ESYSMEM); @@ -58,7 +58,7 @@ hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size) void hcl_killheap (hcl_t* hcl, hcl_heap_t* heap) { - HCL_MMGR_FREE (hcl->mmgr, heap); + hcl->vmprim.free_heap (hcl, heap); } void* hcl_allocheapmem (hcl_t* hcl, hcl_heap_t* heap, hcl_oow_t size) diff --git a/lib/logfmt.c b/lib/logfmt.c index f173c1e..55b20d7 100644 --- a/lib/logfmt.c +++ b/lib/logfmt.c @@ -771,18 +771,16 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t arg = HCL_STACK_GETARG(hcl, nargs, 0); if (!HCL_OOP_IS_POINTER(arg) || HCL_OBJ_GET_FLAGS_TYPE(arg) != HCL_OBJ_TYPE_CHAR) { -#if 0 hcl_ooi_t i; /* if the first argument is not a valid formatting string, * print all arguments as objects */ - if (hcl_print(hcl, arg) <= -1) goto oops; + if (hcl_outfmtobj(hcl, data->mask, arg, outbfmt) <= -1) goto oops; for (i = 1; i < nargs; i++) { arg = HCL_STACK_GETARG(hcl, nargs, i); - if (hcl_print(hcl, arg) <= -1) goto oops; + if (hcl_outfmtobj(hcl, data->mask, arg, outbfmt) <= -1) goto oops; } return 0; -#endif } fmt = HCL_OBJ_GET_CHAR_SLOT(arg); diff --git a/lib/main.c b/lib/main.c index 4769c1d..6f5bcea 100644 --- a/lib/main.c +++ b/lib/main.c @@ -88,6 +88,7 @@ # include # include +# include #endif #if !defined(HCL_DEFAULT_PFMODPREFIX) @@ -146,14 +147,16 @@ struct xtn_t /* ========================================================================= */ +#define MB_1 (256UL*1024*1024) + static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size) { - return malloc (size); + return malloc(size); } static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size) { - return realloc (ptr, size); + return realloc(ptr, size); } static void sys_free (hcl_mmgr_t* mmgr, void* ptr) @@ -378,7 +381,7 @@ static HCL_INLINE hcl_ooi_t close_output (hcl_t* hcl, hcl_iooutarg_t* arg) fp = (FILE*)arg->handle; HCL_ASSERT (hcl, fp != HCL_NULL); - fclose (fp); + if (fp != stdout) fclose (fp); arg->handle = HCL_NULL; return 0; } @@ -395,18 +398,18 @@ static HCL_INLINE hcl_ooi_t write_output (hcl_t* hcl, hcl_iooutarg_t* arg) do { -#if defined(HCL_OOCH_IS_UCH) + #if defined(HCL_OOCH_IS_UCH) bcslen = HCL_COUNTOF(bcsbuf); ucslen = arg->len - donelen; x = hcl_convootobchars (hcl, &arg->ptr[donelen], &ucslen, bcsbuf, &bcslen); if (x <= -1 && ucslen <= 0) return -1; -#else + #else bcslen = HCL_COUNTOF(bcsbuf); ucslen = arg->len - donelen; if (ucslen > bcslen) ucslen = bcslen; else if (ucslen < bcslen) bcslen = ucslen; hcl_copybchars (bcsbuf, &arg->ptr[donelen], bcslen); -#endif + #endif if (fwrite (bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen) { @@ -442,6 +445,212 @@ static hcl_ooi_t print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) /* ========================================================================= */ +static void* alloc_heap (hcl_t* hcl, hcl_oow_t size) +{ + /* It's called 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 */ + hcl_oow_t* ptr; + int flags; + hcl_oow_t actual_size; + + flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB; +#if defined(MAP_UNINITIALIZED) + flags |= MAP_UNINITIALIZED; +#endif + + + actual_size = HCL_SIZEOF(hcl_oow_t) + size; + actual_size = HCL_ALIGN_POW2(actual_size, 2 * 1024 * 1024); + ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == MAP_FAILED) + { + flags &= ~MAP_HUGETLB; + ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == MAP_FAILED) return HCL_NULL; + } + *ptr = size; + + return (void*)(ptr + 1); + /*return HCL_MMGR_ALLOC(hcl->mmgr, size);*/ +} + +static void free_heap (hcl_t* hcl, void* ptr) +{ + hcl_oow_t* actual_ptr; + actual_ptr = (hcl_oow_t*)ptr - 1; + munmap (actual_ptr, *actual_ptr); + /*return HCL_MMGR_FREE(hcl->mmgr, ptr);*/ +} + +static int write_all (int fd, const char* ptr, hcl_oow_t len) +{ + while (len > 0) + { + hcl_ooi_t wr; + + wr = write (1, ptr, len); + + if (wr <= -1) + { + #if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK) + if (errno == EAGAIN) continue; + #else + # if defined(EAGAIN) + if (errno == EAGAIN) continue; + #elif defined(EWOULDBLOCK) + if (errno == EWOULDBLOCK) continue; + #endif + #endif + + #if defined(EINTR) + /* TODO: would this interfere with non-blocking nature of this VM? */ + if (errno == EINTR) continue; + #endif + return -1; + } + + ptr += wr; + len -= wr; + } + + return 0; +} + +static void log_write (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len) +{ +#if defined(_WIN32) +# error NOT IMPLEMENTED + +#elif defined(macintosh) +# error NOT IMPLEMENTED +#else + hcl_bch_t buf[256]; + hcl_oow_t ucslen, bcslen, msgidx; + int n; + + xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); + int logfd; + + if (mask & HCL_LOG_STDERR) + { + /* the messages that go to STDERR don't get masked out */ + logfd = 2; + } + else + { + if (!(xtn->logmask & mask & ~HCL_LOG_ALL_LEVELS)) return; /* check log types */ + if (!(xtn->logmask & mask & ~HCL_LOG_ALL_TYPES)) return; /* check log levels */ + + if (mask & HCL_LOG_STDOUT) logfd = 1; + else + { + + logfd = xtn->logfd; + if (logfd <= -1) return; + } + } + +/* TODO: beautify the log message. + * do classification based on mask. */ + if (!(mask & (HCL_LOG_STDOUT | HCL_LOG_STDERR))) + { + time_t now; + char ts[32]; + size_t tslen; + struct tm tm, *tmp; + + now = time(NULL); + #if defined(__DOS__) + tmp = localtime (&now); + tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S ", tmp); /* no timezone info */ + if (tslen == 0) + { + strcpy (ts, "0000-00-00 00:00:00"); + tslen = 19; + } + #else + tmp = localtime_r (&now, &tm); + #if defined(HAVE_STRFTIME_SMALL_Z) + tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp); + #else + tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp); + #endif + if (tslen == 0) + { + strcpy (ts, "0000-00-00 00:00:00 +0000"); + tslen = 25; + } + #endif + write_all (logfd, ts, tslen); + } + + if (xtn->logfd_istty) + { + if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7); + else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7); + else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7); + } + +#if defined(HCL_OOCH_IS_UCH) + msgidx = 0; + while (len > 0) + { + ucslen = len; + bcslen = HCL_COUNTOF(buf); + + n = hcl_convootobchars (hcl, &msg[msgidx], &ucslen, buf, &bcslen); + if (n == 0 || n == -2) + { + /* n = 0: + * converted all successfully + * n == -2: + * buffer not sufficient. not all got converted yet. + * write what have been converted this round. */ + + HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */ + + /* attempt to write all converted characters */ + if (write_all (logfd, buf, bcslen) <= -1) break; + + if (n == 0) break; + else + { + msgidx += ucslen; + len -= ucslen; + } + } + else if (n <= -1) + { + /* conversion error */ + break; + } + } +#else + write_all (logfd, msg, len); +#endif + + if (xtn->logfd_istty) + { + if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4); + } + +#endif +} + + +static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len) +{ +#if defined(HAVE_STRERROR_R) + strerror_r (syserr, buf, len); +#else + /* this is not thread safe */ + hcl_copybcstr (buf, len, strerror(syserr)); +#endif +} + +/* ========================================================================= */ + static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags) { #if defined(USE_LTDL) || defined(USE_DLFCN) @@ -671,172 +880,7 @@ static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name) #endif } -static int write_all (int fd, const char* ptr, hcl_oow_t len) -{ - while (len > 0) - { - hcl_ooi_t wr; - - wr = write (1, ptr, len); - - if (wr <= -1) - { - #if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK) - if (errno == EAGAIN) continue; - #else - # if defined(EAGAIN) - if (errno == EAGAIN) continue; - #elif defined(EWOULDBLOCK) - if (errno == EWOULDBLOCK) continue; - #endif - #endif - - #if defined(EINTR) - /* TODO: would this interfere with non-blocking nature of this VM? */ - if (errno == EINTR) continue; - #endif - return -1; - } - - ptr += wr; - len -= wr; - } - - return 0; -} - -static void log_write (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len) -{ -#if defined(_WIN32) -# error NOT IMPLEMENTED - -#elif defined(macintosh) -# error NOT IMPLEMENTED -#else - hcl_bch_t buf[256]; - hcl_oow_t ucslen, bcslen, msgidx; - int n; - - xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); - int logfd; - - if (mask & HCL_LOG_STDERR) - { - /* the messages that go to STDERR don't get masked out */ - logfd = 2; - } - else - { - if (!(xtn->logmask & mask & ~HCL_LOG_ALL_LEVELS)) return; /* check log types */ - if (!(xtn->logmask & mask & ~HCL_LOG_ALL_TYPES)) return; /* check log levels */ - - if (mask & HCL_LOG_STDOUT) logfd = 1; - else - { - - logfd = xtn->logfd; - if (logfd <= -1) return; - } - } - -/* TODO: beautify the log message. - * do classification based on mask. */ - if (!(mask & (HCL_LOG_STDOUT | HCL_LOG_STDERR))) - { - time_t now; - char ts[32]; - size_t tslen; - struct tm tm, *tmp; - - now = time(NULL); - #if defined(__DOS__) - tmp = localtime (&now); - tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S ", tmp); /* no timezone info */ - if (tslen == 0) - { - strcpy (ts, "0000-00-00 00:00:00"); - tslen = 19; - } - #else - tmp = localtime_r (&now, &tm); - #if defined(HAVE_STRFTIME_SMALL_Z) - tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp); - #else - tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp); - #endif - if (tslen == 0) - { - strcpy (ts, "0000-00-00 00:00:00 +0000"); - tslen = 25; - } - #endif - write_all (logfd, ts, tslen); - } - - if (xtn->logfd_istty) - { - if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7); - else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7); - else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7); - } - -#if defined(HCL_OOCH_IS_UCH) - msgidx = 0; - while (len > 0) - { - ucslen = len; - bcslen = HCL_COUNTOF(buf); - - n = hcl_convootobchars (hcl, &msg[msgidx], &ucslen, buf, &bcslen); - if (n == 0 || n == -2) - { - /* n = 0: - * converted all successfully - * n == -2: - * buffer not sufficient. not all got converted yet. - * write what have been converted this round. */ - - HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */ - - /* attempt to write all converted characters */ - if (write_all (logfd, buf, bcslen) <= -1) break; - - if (n == 0) break; - else - { - msgidx += ucslen; - len -= ucslen; - } - } - else if (n <= -1) - { - /* conversion error */ - break; - } - } -#else - write_all (logfd, msg, len); -#endif - - if (xtn->logfd_istty) - { - if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4); - } - -#endif -} - - -static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len) -{ -#if defined(HAVE_STRERROR_R) - strerror_r (syserr, buf, len); -#else - /* this is not thread safe */ - hcl_copybcstr (buf, len, strerror(syserr)); -#endif -} - +/* ========================================================================= */ static int vm_startup (hcl_t* hcl) { @@ -925,7 +969,6 @@ static int vm_startup (hcl_t* hcl) xtn->iothr_up = 0; /*pthread_create (&xtn->iothr, HCL_NULL, iothr_main, hcl);*/ - #endif /* USE_THREAD */ xtn->vm_running = 1; @@ -1435,6 +1478,7 @@ int main (int argc, char* argv[]) { { ":log", 'l' }, { ":memsize", 'm' }, + { "large-pages", '\0' }, #if defined(HCL_BUILD_DEBUG) { ":debug", '\0' }, /* NOTE: there is no short option for --debug */ #endif @@ -1448,6 +1492,7 @@ int main (int argc, char* argv[]) const char* logopt = HCL_NULL; hcl_oow_t memsize = MIN_MEMSIZE; + int large_pages = 0; #if defined(HCL_BUILD_DEBUG) const char* dbgopt = HCL_NULL; @@ -1477,9 +1522,13 @@ int main (int argc, char* argv[]) break; case '\0': - + if (hcl_compbcstr(opt.lngopt, "large-pages") == 0) + { + large_pages = 1; + break; + } #if defined(HCL_BUILD_DEBUG) - if (hcl_compbcstr(opt.lngopt, "debug") == 0) + else if (hcl_compbcstr(opt.lngopt, "debug") == 0) { dbgopt = opt.arg; break; @@ -1504,19 +1553,23 @@ int main (int argc, char* argv[]) if (opt.ind >= argc) goto print_usage; #endif - memset (&vmprim, 0, HCL_SIZEOF(vmprim)); + 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; vmprim.dl_close = dl_close; vmprim.dl_getsym = dl_getsym; - vmprim.log_write = log_write; - vmprim.syserrstrb = syserrstrb; vmprim.vm_startup = vm_startup; vmprim.vm_cleanup = vm_cleanup; vmprim.vm_gettime = vm_gettime; vmprim.vm_sleep = vm_sleep; - hcl = hcl_open (&sys_mmgr, HCL_SIZEOF(xtn_t), 2048000lu, &vmprim, HCL_NULL); + hcl = hcl_open (&sys_mmgr, HCL_SIZEOF(xtn_t), memsize, &vmprim, HCL_NULL); if (!hcl) { printf ("cannot open hcl\n");