From 1aa67bbc00d840b7c97bc024278e4e557fcf8ef7 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Wed, 25 Nov 2020 14:48:26 +0000 Subject: [PATCH] added --gctype fixed a bug in xma touched up gc code a bit --- moo/bin/main.c | 15 ++++++- moo/lib/exec.c | 16 +++++++- moo/lib/gc.c | 57 +++++++++++++++++---------- moo/lib/heap.c | 44 ++++++++++++++++++++- moo/lib/moo-prv.h | 25 +++++++++++- moo/lib/moo-std.h | 1 + moo/lib/moo-xma.h | 2 +- moo/lib/moo.c | 20 +++++----- moo/lib/moo.h | 11 ++++-- moo/lib/obj.c | 99 ++++++++++++++++++++++++----------------------- moo/lib/std.c | 4 +- moo/lib/xma.c | 4 +- 12 files changed, 206 insertions(+), 92 deletions(-) diff --git a/moo/bin/main.c b/moo/bin/main.c index ee81ff7..54089cf 100644 --- a/moo/bin/main.c +++ b/moo/bin/main.c @@ -89,6 +89,7 @@ int main (int argc, char* argv[]) { { ":log", 'l' }, { ":heapsize", '\0' }, + { ":gctype", '\0' }, { ":procstksize", '\0' }, { "large-pages", '\0' }, { ":base-charset", '\0' }, @@ -114,11 +115,13 @@ int main (int argc, char* argv[]) fprintf (stderr, "Usage: %s [options] filename ...\n", argv[0]); fprintf (stderr, " --log filename[,logopts]\n"); fprintf (stderr, " --heapsize=bytes\n"); + fprintf (stderr, " --gctype=ms|ss\n"); fprintf (stderr, " --procstksize=number of oops\n"); fprintf (stderr, " --large-pages\n"); fprintf (stderr, " --base-charset=name\n"); fprintf (stderr, " --input-charset=name\n"); fprintf (stderr, " --log-charset=name\n"); + #if defined(MOO_BUILD_DEBUG) fprintf (stderr, " --debug dbgopts\n"); #endif @@ -145,10 +148,17 @@ int main (int argc, char* argv[]) if (moo_comp_bcstr(opt.lngopt, "heapsize") == 0) { heapsize = strtoul(opt.arg, MOO_NULL, 0); - if (heapsize <= MIN_HEAPSIZE) heapsize = MIN_HEAPSIZE; break; } - if (moo_comp_bcstr(opt.lngopt, "procstksize") == 0) + else if (moo_comp_bcstr(opt.lngopt, "gctype") == 0) + { + if (moo_comp_bcstr(opt.arg, "ms") == 0) + cfg.gc_type = MOO_GC_TYPE_MARK_SWEEP; + else + cfg.gc_type = MOO_GC_TYPE_SEMISPACE; + break; + } + else if (moo_comp_bcstr(opt.lngopt, "procstksize") == 0) { cfg.proc_stk_size = strtoul(opt.arg, MOO_NULL, 0); break; @@ -238,6 +248,7 @@ int main (int argc, char* argv[]) moo_setoption (moo, MOO_OPTION_SYSDIC_SIZE, &tab_size); } + if (cfg.gc_type == MOO_GC_TYPE_SEMISPACE && heapsize <= MIN_HEAPSIZE) heapsize = MIN_HEAPSIZE; if (moo_ignite(moo, heapsize) <= -1) { moo_logbfmt (moo, MOO_LOG_STDERR, "ERROR: cannot ignite moo - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo)); diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 1a4e91d..0e3dee6 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -6369,6 +6369,16 @@ void moo_abort (moo_t* moo) moo->abort_req = 1; } +#if defined(MOO_PROFILE_VM) && defined(MOO_ENABLE_GC_MARK_SWEEP) +static void xma_dumper (void* ctx, const char* fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + moo_logbfmtv ((moo_t*)ctx, MOO_LOG_IC | MOO_LOG_INFO, fmt, ap); + va_end (ap); +} +#endif + int moo_invoke (moo_t* moo, const moo_oocs_t* objname, const moo_oocs_t* mthname) { int n; @@ -6428,7 +6438,11 @@ int moo_invoke (moo_t* moo, const moo_oocs_t* objname, const moo_oocs_t* mthname MOO_LOG2 (moo, MOO_LOG_IC | MOO_LOG_INFO, "Method cache - hits: %zu, misses: %zu\n", moo->stat.method_cache_hits, moo->stat.method_cache_misses); MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_INFO, "Total instructions: %zu\n", moo->stat.inst_counter); #if defined(MOO_ENABLE_GC_MARK_SWEEP) - MOO_LOG2 (moo, MOO_LOG_IC | MOO_LOG_INFO, "GC - gci.bsz: %zu, gci.stack.max: %zu\n", moo->gci.bsz, moo->gci.stack.max); + if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP) + { + MOO_LOG2 (moo, MOO_LOG_IC | MOO_LOG_INFO, "GC - gci.bsz: %zu, gci.stack.max: %zu\n", moo->gci.bsz, moo->gci.stack.max); + if (moo->heap->xma) moo_xma_dump (moo->heap->xma, xma_dumper, moo); + } #endif #endif diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 9b60c58..6c09219 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -798,9 +798,6 @@ static moo_rbt_walk_t call_module_gc (moo_rbt_t* rbt, moo_rbt_pair_t* pair, void /* ----------------------------------------------------------------------- */ #if defined(MOO_ENABLE_GC_MARK_SWEEP) - - - #if 0 static MOO_INLINE void gc_mark (moo_t* moo, moo_oop_t oop) { @@ -1021,7 +1018,7 @@ static MOO_INLINE void gc_sweep (moo_t* moo) else moo->gci.b = next; moo->gci.bsz -= MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, obj); - moo_freemem (moo, curr); + moo_freeheapmem (moo, moo->heap, curr); } curr = next; @@ -1031,18 +1028,12 @@ static MOO_INLINE void gc_sweep (moo_t* moo) /* ----------------------------------------------------------------------- */ -moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop) +static moo_oop_t move_oop_in_heap_space (moo_t* moo, moo_oop_t oop) { #if defined(MOO_SUPPORT_GC_DURING_IGNITION) if (!oop) return oop; #endif -#if defined(MOO_ENABLE_GC_MARK_SWEEP) -/* TODO: temporary... */ - gc_mark (moo, oop); - return oop; -#endif - if (!MOO_OOP_IS_POINTER(oop)) return oop; if (MOO_OBJ_GET_FLAGS_PERM(oop)) return oop; @@ -1179,16 +1170,8 @@ static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t** } -void moo_gc (moo_t* moo) +static void scan_roots (moo_t* moo) { -#if defined(MOO_ENABLE_GC_MARK_SWEEP) - MOO_LOG1 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Starting GC (mark-sweep) - gci.bsz = %zu\n", moo->gci.bsz); -moo->gci.stack.len = 0; -/*moo->gci.stack.max = 0;*/ - gc_mark_root (moo); - gc_sweep (moo); - MOO_LOG2 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Finished GC (mark-sweep) - gci.bsz = %zu, gci.stack.max %zu\n", moo->gci.bsz, moo->gci.stack.max); -#else /* * move a referenced object to the new heap. * inspect the fields of the moved object in the new heap. @@ -1352,7 +1335,41 @@ moo->gci.stack.len = 0; MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Finished GC curheap base %p ptr %p newheap base %p ptr %p\n", moo->heap->curspace.base, moo->heap->curspace.ptr, moo->heap->newspace.base, moo->heap->newspace.ptr); +} + + +void moo_gc (moo_t* moo) +{ +#if defined(MOO_ENABLE_GC_MARK_SWEEP) + if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP) + { + MOO_LOG1 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Starting GC (mark-sweep) - gci.bsz = %zu\n", moo->gci.bsz); + moo->gci.stack.len = 0; + /*moo->gci.stack.max = 0;*/ + gc_mark_root (moo); + gc_sweep (moo); + MOO_LOG2 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Finished GC (mark-sweep) - gci.bsz = %zu, gci.stack.max %zu\n", moo->gci.bsz, moo->gci.stack.max); + } + else #endif + { + scan_roots (moo); + } +} + +moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop) +{ +#if defined(MOO_ENABLE_GC_MARK_SWEEP) + if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP) + { + gc_mark (moo, oop); + return oop; + } + else +#endif + { + return move_oop_in_heap_space(moo, oop); + } } void moo_pushvolat (moo_t* moo, moo_oop_t* oop_ptr) diff --git a/moo/lib/heap.c b/moo/lib/heap.c index 7ecd128..dd414f8 100644 --- a/moo/lib/heap.c +++ b/moo/lib/heap.c @@ -67,10 +67,12 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) { if (size <= 0) { + /* use the existing memory allocator */ heap->xmmgr = *moo_getmmgr(moo); } else { + /* create a new memory allocator over the allocated heap */ heap->xma = moo_xma_open(moo_getmmgr(moo), 0, heap->base, heap->size); if (MOO_UNLIKELY(!heap->xma)) { @@ -87,7 +89,7 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) } else { - MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_SS_COPY); + MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_SEMISPACE); space_size = (size - PERM_SPACE_SIZE) / 2; @@ -125,6 +127,8 @@ void* moo_allocheapspace (moo_t* moo, moo_space_t* space, moo_oow_t size) { moo_uint8_t* ptr; + MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_SEMISPACE); + /* check the space size limit */ if (space->ptr >= space->limit || space->limit - space->ptr < size) { @@ -140,3 +144,41 @@ void* moo_allocheapspace (moo_t* moo, moo_space_t* space, moo_oow_t size) return ptr; } + +void* moo_allocheapmem (moo_t* moo, moo_heap_t* heap, moo_oow_t size) +{ + void* ptr; + + MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_MARK_SWEEP); + ptr = MOO_MMGR_ALLOC(&heap->xmmgr, size); + if (MOO_UNLIKELY(!ptr)) + { + MOO_DEBUG2 (moo, "Cannot allocate %zd bytes from heap - ptr %p\n", size, heap); + moo_seterrnum (moo, MOO_EOOMEM); + } + return ptr; +} + +void* moo_callocheapmem (moo_t* moo, moo_heap_t* heap, moo_oow_t size) +{ + void* ptr; + + MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_MARK_SWEEP); + ptr = MOO_MMGR_ALLOC(&heap->xmmgr, size); + if (MOO_UNLIKELY(!ptr)) + { + MOO_DEBUG2 (moo, "Cannot callocate %zd bytes from heap - ptr %p\n", size, heap); + moo_seterrnum (moo, MOO_EOOMEM); + } + else + { + MOO_MEMSET (ptr, 0, size); + } + return ptr; +} + +void moo_freeheapmem (moo_t* moo, moo_heap_t* heap, void* ptr) +{ + MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_MARK_SWEEP); + MOO_MMGR_FREE (&heap->xmmgr, ptr); +} diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index afb263e..c46aae6 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1109,8 +1109,8 @@ void moo_killheap ( ); /** - * The moo_allocheapspace() function allocates \a size bytes in the heap pointed - * to by \a heap. + * The moo_allocheapspace() function allocates \a size bytes in a semi-space + * of the heap pointed to by \a heap. * * \return memory pointer on success and #MOO_NULL on failure. */ @@ -1120,6 +1120,27 @@ void* moo_allocheapspace ( moo_oow_t size ); + +/** + * The moo_allocheapmem(0 function allocates \a size bytes from the given heap. + */ +void* moo_allocheapmem ( + moo_t* moo, + moo_heap_t* heap, + moo_oow_t size +); + +void* moo_callocheapmem ( + moo_t* moo, + moo_heap_t* heap, + moo_oow_t size +); + +void moo_freeheapmem ( + moo_t* moo, + moo_heap_t* heap, + void* ptr +); /* ========================================================================= */ /* obj.c */ /* ========================================================================= */ diff --git a/moo/lib/moo-std.h b/moo/lib/moo-std.h index 2e834f4..a0e8b44 100644 --- a/moo/lib/moo-std.h +++ b/moo/lib/moo-std.h @@ -15,6 +15,7 @@ struct moo_cfgstd_t { moo_cfgstd_type_t type; + moo_gc_type_t gc_type; moo_oow_t proc_stk_size; int large_pages; moo_cmgr_t* cmgr; diff --git a/moo/lib/moo-xma.h b/moo/lib/moo-xma.h index e31fab7..63c0b88 100644 --- a/moo/lib/moo-xma.h +++ b/moo/lib/moo-xma.h @@ -115,7 +115,7 @@ struct moo_xma_t * The moo_xma_dumper_t type defines a printf-like output function * for moo_xma_dump(). */ -typedef int (*moo_xma_dumper_t) ( +typedef void (*moo_xma_dumper_t) ( void* ctx, const moo_bch_t* fmt, ... diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 2cd99b7..9221a48 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -26,7 +26,7 @@ #include "moo-prv.h" -moo_t* moo_open (moo_mmgr_t* mmgr, moo_oow_t xtnsize, moo_cmgr_t* cmgr, const moo_vmprim_t* vmprim, moo_errinf_t* errinfo) +moo_t* moo_open (moo_mmgr_t* mmgr, moo_oow_t xtnsize, moo_cmgr_t* cmgr, const moo_vmprim_t* vmprim, moo_gc_type_t gctype, moo_errinf_t* errinfo) { moo_t* moo; @@ -36,7 +36,7 @@ moo_t* moo_open (moo_mmgr_t* mmgr, moo_oow_t xtnsize, moo_cmgr_t* cmgr, const mo moo = (moo_t*)MOO_MMGR_ALLOC(mmgr, MOO_SIZEOF(*moo) + xtnsize); if (moo) { - if (moo_init(moo, mmgr, cmgr, vmprim) <= -1) + if (moo_init(moo, mmgr, cmgr, vmprim, gctype) <= -1) { if (errinfo) moo_geterrinf (moo, errinfo); MOO_MMGR_FREE (mmgr, moo); @@ -96,7 +96,7 @@ static MOO_INLINE void free_heap (moo_t* moo, void* ptr) moo_freemem (moo, ptr); } -int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_cmgr_t* cmgr, const moo_vmprim_t* vmprim) +int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_cmgr_t* cmgr, const moo_vmprim_t* vmprim, moo_gc_type_t gctype) { int modtab_inited = 0; @@ -111,6 +111,7 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_cmgr_t* cmgr, const moo_vmprim_t moo->_mmgr = mmgr; moo->_cmgr = cmgr; + moo->gc_type = gctype; moo->vmprim = *vmprim; if (!moo->vmprim.alloc_heap) moo->vmprim.alloc_heap = alloc_heap; if (!moo->vmprim.free_heap) moo->vmprim.free_heap = free_heap; @@ -260,11 +261,7 @@ void moo_fini (moo_t* moo) moo->proc_map_free_last = -1; } -/* TOOD: persistency? storing objects to image file? */ - - /* if the moo object is closed without moo_ignite(), - * the heap may not exist */ - if (moo->heap) moo_killheap (moo, moo->heap); +/* TOOD: persistency? storing objects to image file before destroying all objects and the heap? */ #if defined(MOO_ENABLE_GC_MARK_SWEEP) if (moo->gci.b) @@ -273,9 +270,8 @@ void moo_fini (moo_t* moo) do { next = moo->gci.b->next; - moo->gci.bsz -= MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, (moo_oop_t)(moo->gci.b + 1)); - moo_freemem (moo, moo->gci.b); + moo_freeheapmem (moo, moo->heap, moo->gci.b); moo->gci.b = next; } while (moo->gci.b); @@ -292,6 +288,10 @@ void moo_fini (moo_t* moo) } #endif + /* if the moo object is closed without moo_ignite(), + * the heap may not exist */ + if (moo->heap) moo_killheap (moo, moo->heap); + moo_finidbgi (moo); for (i = 0; i < MOO_COUNTOF(moo->sbuf); i++) diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 123d128..d0ef763 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -35,7 +35,7 @@ /* TODO: move this macro out to the build files.... */ #define MOO_INCLUDE_COMPILER -//#define MOO_ENABLE_GC_MARK_SWEEP +#define MOO_ENABLE_GC_MARK_SWEEP typedef struct moo_mod_t moo_mod_t; @@ -218,7 +218,7 @@ struct moo_gchdr_t enum moo_gc_type_t { - MOO_GC_TYPE_SS_COPY, + MOO_GC_TYPE_SEMISPACE, MOO_GC_TYPE_MARK_SWEEP }; typedef enum moo_gc_type_t moo_gc_type_t; @@ -1012,10 +1012,13 @@ struct moo_heap_t moo_uint8_t* base; moo_oow_t size; +/* for semi-space gc */ moo_space_t permspace; moo_space_t curspace; moo_space_t newspace; +/* for mark sweep gc */ +/* TODO: use union ... */ moo_xma_t* xma; /* used if MARK_SWEEP is enabled */ moo_mmgr_t xmmgr; }; @@ -2084,6 +2087,7 @@ MOO_EXPORT moo_t* moo_open ( moo_oow_t xtnsize, moo_cmgr_t* cmgr, const moo_vmprim_t* vmprim, + moo_gc_type_t gctype, moo_errinf_t* errinfo ); @@ -2095,7 +2099,8 @@ MOO_EXPORT int moo_init ( moo_t* moo, moo_mmgr_t* mmgr, moo_cmgr_t* cmgr, - const moo_vmprim_t* vmprim + const moo_vmprim_t* vmprim, + moo_gc_type_t gctype ); MOO_EXPORT void moo_fini ( diff --git a/moo/lib/obj.c b/moo/lib/obj.c index ff42885..220a4cc 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -28,71 +28,74 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size) { - moo_uint8_t* ptr; -#if defined(MOO_ENABLE_GC_MARK_SWEEP) - moo_gchdr_t* gch; -#endif - #if defined(MOO_BUILD_DEBUG) /* DEBUG_GC is set but NOGC is not set */ if ((moo->option.trait & (MOO_TRAIT_DEBUG_GC | MOO_TRAIT_NOGC)) == MOO_TRAIT_DEBUG_GC) moo_gc (moo); #endif #if defined(MOO_ENABLE_GC_MARK_SWEEP) - if (MOO_UNLIKELY(moo->igniting)) + if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP) { -/* TODO: use heap.xmmgr for allocation... */ - gch = (moo_gchdr_t*)moo_callocmem(moo, MOO_SIZEOF(*gch) + size); - if (MOO_UNLIKELY(!gch)) return MOO_NULL; - } - else - { - if (moo->gci.bsz >= moo->gci.threshold) - { - moo_gc (moo); - moo->gci.threshold = moo->gci.bsz + 100000; /* TODO: change this fomula */ - } + moo_gchdr_t* gch; - gch = (moo_gchdr_t*)moo_callocmem(moo, MOO_SIZEOF(*gch) + size); - if (!gch && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC)) + if (MOO_UNLIKELY(moo->igniting)) { - moo_gc (moo); - MOO_LOG0 (moo, MOO_LOG_GC | MOO_LOG_INFO, "GC completed\n"); /* TODO: add more inforamtion */ - gch = (moo_gchdr_t*)moo_callocmem(moo, MOO_SIZEOF(*gch) + size); + gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, MOO_SIZEOF(*gch) + size); if (MOO_UNLIKELY(!gch)) return MOO_NULL; } - } + else + { + if (moo->gci.bsz >= moo->gci.threshold) + { + moo_gc (moo); + moo->gci.threshold = moo->gci.bsz + 100000; /* TODO: change this fomula */ + } - gch->next = moo->gci.b; - moo->gci.b = gch; - moo->gci.bsz += size; + gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, MOO_SIZEOF(*gch) + size); + if (!gch && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC)) + { + moo_gc (moo); + MOO_LOG0 (moo, MOO_LOG_GC | MOO_LOG_INFO, "GC completed\n"); /* TODO: add more inforamtion */ + gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, MOO_SIZEOF(*gch) + size); + if (MOO_UNLIKELY(!gch)) return MOO_NULL; + } + } - ptr = (moo_uint8_t*)(gch + 1); -#else - if (MOO_UNLIKELY(moo->igniting)) - { - /* you must increase the size of the permspace if this allocation fails */ - ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->permspace, size); + gch->next = moo->gci.b; + moo->gci.b = gch; + moo->gci.bsz += size; + + return (moo_uint8_t*)(gch + 1); } else - { - ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size); - if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC)) - { - moo_gc (moo); - MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, - "GC completed - current heap ptr %p limit %p size %zd free %zd\n", - moo->heap->curspace.ptr, moo->heap->curspace.limit, - (moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.base), - (moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.ptr) - ); - ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size); - /* TODO: grow heap if ptr is still null. */ - } - } #endif + { + moo_uint8_t* ptr; - return ptr; + if (MOO_UNLIKELY(moo->igniting)) + { + /* you must increase the size of the permspace if this allocation fails */ + ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->permspace, size); + } + else + { + ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size); + if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC)) + { + moo_gc (moo); + MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, + "GC completed - current heap ptr %p limit %p size %zd free %zd\n", + moo->heap->curspace.ptr, moo->heap->curspace.limit, + (moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.base), + (moo_oow_t)(moo->heap->curspace.limit - moo->heap->curspace.ptr) + ); + ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size); + /* TODO: grow heap if ptr is still null. */ + } + } + + return ptr; + } } moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size) diff --git a/moo/lib/std.c b/moo/lib/std.c index 336097a..c757c31 100644 --- a/moo/lib/std.c +++ b/moo/lib/std.c @@ -4207,8 +4207,8 @@ moo_t* moo_openstd (moo_oow_t xtnsize, const moo_cfgstd_t* cfg, moo_errinf_t* er vmprim.vm_getsig = vm_getsig; vmprim.vm_setsig = vm_setsig; - moo = moo_open(&sys_mmgr, MOO_SIZEOF(xtn_t) + xtnsize, ((cfg && cfg->cmgr)? cfg->cmgr: moo_get_utf8_cmgr()), &vmprim, errinfo); - if (!moo) return MOO_NULL; + moo = moo_open(&sys_mmgr, MOO_SIZEOF(xtn_t) + xtnsize, ((cfg && cfg->cmgr)? cfg->cmgr: moo_get_utf8_cmgr()), &vmprim, cfg->gc_type, errinfo); + if (MOO_UNLIKELY(!moo)) return MOO_NULL; /* adjust the object size by the sizeof xtn_t so that moo_getxtn() returns the right pointer. */ moo->_instsize += MOO_SIZEOF(xtn_t); diff --git a/moo/lib/xma.c b/moo/lib/xma.c index f00e36c..34c37c0 100644 --- a/moo/lib/xma.c +++ b/moo/lib/xma.c @@ -234,7 +234,7 @@ int moo_xma_init (moo_xma_t* xma, moo_mmgr_t* mmgr, void* zoneptr, moo_oow_t zon zoneptr = MOO_MMGR_ALLOC(mmgr, zonesize); if (MOO_UNLIKELY(!zoneptr)) return -1; - internal = 1; + internal = 1; /* internally created. must be freed upon moo_xma_fini() */ } first = (moo_xma_fblk_t*)zoneptr; @@ -259,7 +259,7 @@ int moo_xma_init (moo_xma_t* xma, moo_mmgr_t* mmgr, void* zoneptr, moo_oow_t zon /* let it be the head, which is natural with only a block */ xma->start = (moo_uint8_t*)first; xma->end = xma->start + zonesize; - xma->internal = 1; + xma->internal = internal; /* initialize some statistical variables */ #if defined(MOO_XMA_ENABLE_STAT)