diff --git a/hawk/lib/fnc.c b/hawk/lib/fnc.c index 87064446..ebd461e3 100644 --- a/hawk/lib/fnc.c +++ b/hawk/lib/fnc.c @@ -30,6 +30,7 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); +static int fnc_gcrefs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); static int fnc_ismap (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); static int fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi); @@ -60,6 +61,7 @@ static hawk_fnc_t sysfnctab[] = { {HAWK_T("isnil"), 5}, 0, { {1, 1, HAWK_NULL}, fnc_isnil, 0 }, HAWK_NULL}, { {HAWK_T("ismap"), 5}, 0, { {1, 1, HAWK_NULL}, fnc_ismap, 0 }, HAWK_NULL}, { {HAWK_T("typename"), 8}, 0, { {1, 1, HAWK_NULL}, fnc_typename, 0 }, HAWK_NULL}, + { {HAWK_T("gcrefs"), 6}, 0, { {1, 1, HAWK_NULL}, fnc_gcrefs, 0 }, HAWK_NULL}, /* map(array) sort */ { {HAWK_T("asort"), 5}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asort, 0 }, HAWK_NULL}, @@ -1749,6 +1751,15 @@ static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) return 0; } +static int fnc_gcrefs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + hawk_val_t* a0; + a0 = hawk_rtx_getarg(rtx, 0); + hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, HAWK_VTR_IS_POINTER(a0)? a0->v_refs: 0)); + return 0; +} + + static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) { hawk_val_t* a0; diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index 23eed26b..1470534b 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -379,6 +379,14 @@ struct hawk_rtx_t hawk_val_chunk_t* rchunk; } vmgr; + struct + { + int collecting; + hawk_oow_t all_count; + hawk_gci_t all; /* allocated objects */ + hawk_gci_t saved; /* objects to preserve */ + } gc; + hawk_nde_blk_t* active_block; hawk_uint8_t* pattern_range_state; @@ -495,7 +503,7 @@ struct hawk_mod_data_t (refval)->v_refs = (_nrefs); \ (refval)->v_static = 0; \ (refval)->nstr = 0; \ - (refval)->fcb = 0; \ + (refval)->v_gc = 0; \ (refval)->id = (_id); \ (refval)->adr = (_adr); \ } while(0); diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index 76b3fc8d..f2b0dbb7 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -129,27 +129,29 @@ struct hawk_rtx_alt_t /* ------------------------------------------------------------------------ */ -typedef struct hawk_gc_info_t hawk_gc_info_t; -struct hawk_gc_info_t +typedef struct hawk_gci_t hawk_gci_t; +struct hawk_gci_t { - hawk_gc_info_t* gc_prev; - hawk_gc_info_t* gc_next; + hawk_gci_t* gc_prev; + hawk_gci_t* gc_next; hawk_uintptr_t gc_refs; }; #if defined(HAWK_HAVE_INLINE) -static HAWK_INLINE hawk_gc_info_t* hawk_val_to_gcinfo(hawk_val_t* v) -{ - return ((hawk_gc_info_t*)v) - 1; -} -static HAWK_INLINE hawk_val_t* hawk_gcinfo_to_val(hawk_gc_info_t* gci) + +static HAWK_INLINE hawk_val_t* hawk_gci_to_val(hawk_gci_t* gci) { return (hawk_val_t*)(gci + 1); } +static HAWK_INLINE hawk_gci_t* hawk_val_to_gci(hawk_val_t* v) +{ + return ((hawk_gci_t*)v) - 1; +} + #else -# defined hawk_val_to_gcinfo(v) (((hawk_gc_info_t*)(v)) - 1) -# defined hawk_gcinfo_to_val(gci) ((hawk_val_t*)(((hawk_gc_info_t*)(gci)) + 1)) +# define hawk_val_to_gci(v) (((hawk_gci_t*)(v)) - 1) +# define hawk_gci_to_val(gci) ((hawk_val_t*)(((hawk_gci_t*)(gci)) + 1)) #endif /** @@ -166,14 +168,14 @@ static HAWK_INLINE hawk_val_t* hawk_gcinfo_to_val(hawk_gc_info_t* gci) unsigned int v_refs: 24; \ unsigned int v_static: 1; \ unsigned int nstr: 2; \ - unsigned int fcb: 1 + unsigned int v_gc: 1 */ #define HAWK_VAL_HDR \ hawk_uintptr_t v_type: 4; \ hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \ hawk_uintptr_t v_static: 1; \ hawk_uintptr_t nstr: 2; \ - hawk_uintptr_t fcb: 1 + hawk_uintptr_t v_gc: 1 /** * The hawk_val_t type is an abstract value type. A value commonly contains: diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 093086cd..51864e37 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -876,7 +876,7 @@ hawk_rtx_t* hawk_rtx_open (hawk_t* awk, hawk_oow_t xtnsize, hawk_rio_cbs_t* rio) /* allocate the storage for the rtx object */ rtx = (hawk_rtx_t*)hawk_allocmem(awk, HAWK_SIZEOF(hawk_rtx_t) + xtnsize); - if (!rtx) + if (HAWK_UNLIKELY(!rtx)) { /* if it fails, the failure is reported thru the awk object */ return HAWK_NULL; @@ -885,13 +885,13 @@ hawk_rtx_t* hawk_rtx_open (hawk_t* awk, hawk_oow_t xtnsize, hawk_rio_cbs_t* rio) /* initialize the rtx object */ HAWK_MEMSET (rtx, 0, HAWK_SIZEOF(hawk_rtx_t) + xtnsize); rtx->_instsize = HAWK_SIZEOF(hawk_rtx_t); - if (init_rtx(rtx, awk, rio) <= -1) + if (HAWK_UNLIKELY(init_rtx(rtx, awk, rio) <= -1)) { hawk_freemem (awk, rtx); return HAWK_NULL; } - if (init_globals(rtx) <= -1) + if (HAWK_UNLIKELY(init_globals(rtx) <= -1)) { hawk_rtx_errortohawk (rtx, awk); fini_rtx (rtx, 0); @@ -1020,7 +1020,7 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio) stack_limit = awk->parse.pragma.rtx_stack_limit > 0? awk->parse.pragma.rtx_stack_limit: awk->opt.rtx_stack_limit; if (stack_limit < HAWK_MIN_RTX_STACK_LIMIT) stack_limit = HAWK_MIN_RTX_STACK_LIMIT; rtx->stack = hawk_rtx_allocmem(rtx, stack_limit * HAWK_SIZEOF(void*)); - if (!rtx->stack) goto oops_0; + if (HAWK_UNLIKELY(!rtx->stack)) goto oops_0; rtx->stack_top = 0; rtx->stack_base = 0; rtx->stack_limit = stack_limit; @@ -1032,6 +1032,14 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio) rtx->vmgr.rchunk = HAWK_NULL; rtx->vmgr.rfree = HAWK_NULL; + /* initialize circular doubly-linked list */ + rtx->gc.collecting = 0; + rtx->gc.all_count = 0; + rtx->gc.all.gc_next = &rtx->gc.all; + rtx->gc.all.gc_prev = &rtx->gc.all; + rtx->gc.saved.gc_next = &rtx->gc.saved; + rtx->gc.saved.gc_prev = &rtx->gc.saved; + rtx->inrec.buf_pos = 0; rtx->inrec.buf_len = 0; rtx->inrec.flds = HAWK_NULL; @@ -1039,39 +1047,39 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio) rtx->inrec.maxflds = 0; rtx->inrec.d0 = hawk_val_nil; - if (hawk_ooecs_init(&rtx->inrec.line, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_1; - if (hawk_ooecs_init(&rtx->inrec.linew, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_2; - if (hawk_ooecs_init(&rtx->inrec.lineg, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_3; - if (hawk_becs_init(&rtx->inrec.linegb, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_4; - if (hawk_ooecs_init(&rtx->format.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_5; - if (hawk_ooecs_init(&rtx->format.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_6; + if (HAWK_UNLIKELY(hawk_ooecs_init(&rtx->inrec.line, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1)) goto oops_1; + if (HAWK_UNLIKELY(hawk_ooecs_init(&rtx->inrec.linew, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1)) goto oops_2; + if (HAWK_UNLIKELY(hawk_ooecs_init(&rtx->inrec.lineg, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1)) goto oops_3; + if (HAWK_UNLIKELY(hawk_becs_init(&rtx->inrec.linegb, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1)) goto oops_4; + if (HAWK_UNLIKELY(hawk_ooecs_init(&rtx->format.out, hawk_rtx_getgem(rtx), 256) <= -1)) goto oops_5; + if (HAWK_UNLIKELY(hawk_ooecs_init(&rtx->format.fmt, hawk_rtx_getgem(rtx), 256) <= -1)) goto oops_6; - if (hawk_becs_init(&rtx->formatmbs.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_7; - if (hawk_becs_init(&rtx->formatmbs.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_8; + if (HAWK_UNLIKELY(hawk_becs_init(&rtx->formatmbs.out, hawk_rtx_getgem(rtx), 256) <= -1)) goto oops_7; + if (HAWK_UNLIKELY(hawk_becs_init(&rtx->formatmbs.fmt, hawk_rtx_getgem(rtx), 256) <= -1)) goto oops_8; - if (hawk_becs_init(&rtx->fnc.bout, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_9; - if (hawk_ooecs_init(&rtx->fnc.oout, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_10; + if (HAWK_UNLIKELY(hawk_becs_init(&rtx->fnc.bout, hawk_rtx_getgem(rtx), 256) <= -1)) goto oops_9; + if (HAWK_UNLIKELY(hawk_ooecs_init(&rtx->fnc.oout, hawk_rtx_getgem(rtx), 256) <= -1)) goto oops_10; rtx->named = hawk_htb_open(hawk_rtx_getgem(rtx), HAWK_SIZEOF(rtx), 1024, 70, HAWK_SIZEOF(hawk_ooch_t), 1); - if (!rtx->named) goto oops_11; + if (HAWK_UNLIKELY(!rtx->named)) goto oops_11; *(hawk_rtx_t**)hawk_htb_getxtn(rtx->named) = rtx; hawk_htb_setstyle (rtx->named, &style_for_named); rtx->format.tmp.ptr = (hawk_ooch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_ooch_t)); - if (!rtx->format.tmp.ptr) goto oops_12; /* the error is set on the awk object after this jump is made */ + if (HAWK_UNLIKELY(!rtx->format.tmp.ptr)) goto oops_12; /* the error is set on the awk object after this jump is made */ rtx->format.tmp.len = 4096; rtx->format.tmp.inc = 4096 * 2; rtx->formatmbs.tmp.ptr = (hawk_bch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_bch_t)); - if (!rtx->formatmbs.tmp.ptr) goto oops_13; + if (HAWK_UNLIKELY(!rtx->formatmbs.tmp.ptr)) goto oops_13; rtx->formatmbs.tmp.len = 4096; rtx->formatmbs.tmp.inc = 4096 * 2; if (rtx->hawk->tree.chain_size > 0) { rtx->pattern_range_state = (hawk_oob_t*)hawk_rtx_allocmem(rtx, rtx->hawk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t)); - if (!rtx->pattern_range_state) goto oops_14; + if (HAWK_UNLIKELY(!rtx->pattern_range_state)) goto oops_14; HAWK_MEMSET (rtx->pattern_range_state, 0, rtx->hawk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t)); } else rtx->pattern_range_state = HAWK_NULL; diff --git a/hawk/lib/val.c b/hawk/lib/val.c index 138cf14d..81095072 100644 --- a/hawk/lib/val.c +++ b/hawk/lib/val.c @@ -39,15 +39,173 @@ hawk_val_t* hawk_val_zlm = (hawk_val_t*)&awk_zlm; /* --------------------------------------------------------------------- */ -/* TOOD: */ +/*#define HAWK_ENABLE_GC*/ +#define GCI_MOVED HAWK_TYPE_MAX(hawk_uintptr_t) + static hawk_val_t* gc_calloc (hawk_rtx_t* rtx, hawk_oow_t size) { - hawk_gc_info_t* gci; + hawk_gci_t* gci; - gci = (hawk_gc_info_t*)hawk_rtx_callocmem(rtx, HAWK_SIZEOF(*gci) + size); + gci = (hawk_gci_t*)hawk_rtx_callocmem(rtx, HAWK_SIZEOF(*gci) + size); if (HAWK_UNLIKELY(!gci)) return HAWK_NULL; - return hawk_gcinfo_to_val(gci); + return hawk_gci_to_val(gci); +} + +static HAWK_INLINE void gc_chain_gci (hawk_gci_t* list, hawk_gci_t* gci) +{ + gci->gc_next = list; + gci->gc_prev = list->gc_prev; + gci->gc_prev->gc_next = gci; + list->gc_prev = gci; +} + +static HAWK_INLINE void gc_chain_val (hawk_gci_t* list, hawk_val_t* v) +{ + gc_chain_gci (list, hawk_val_to_gci(v)); +} + +static HAWK_INLINE void gc_unchain_gci (hawk_gci_t* gci) +{ + gci->gc_prev->gc_next = gci->gc_next; + gci->gc_next->gc_prev = gci->gc_prev; +} + +static HAWK_INLINE void gc_unchain_val (hawk_val_t* v) +{ + gc_unchain_gci (hawk_val_to_gci(v)); +} + +static void gc_clone_refs (hawk_gci_t* list) +{ + hawk_gci_t* gci; + + gci = list->gc_next; + while (gci != list) + { + gci->gc_refs = hawk_gci_to_val(gci)->v_refs; + gci = gci->gc_next; + } +} + +static void gc_trace_refs (hawk_gci_t* list) +{ + hawk_gci_t* gci; + hawk_val_t* v, * iv; + hawk_map_itr_t itr; + hawk_map_pair_t* pair; + + gci = list->gc_next; + while (gci != list) + { + v = hawk_gci_to_val(gci); + + /* as of now, there is only one type available - HAWK_VAL_MAP */ + HAWK_ASSERT (v->v_type == HAWK_VAL_MAP); + itr._dir = 0; + pair = hawk_map_getfirstpair(((hawk_val_map_t*)v)->map, &itr); + while (pair) + { + iv = (hawk_val_t*)HAWK_MAP_VPTR(pair); + if (HAWK_VTR_IS_POINTER(iv) && iv->v_gc) + { +printf ("decrementing...\n"); + hawk_val_to_gci(iv)->gc_refs--; + } + pair = hawk_map_getnextpair(((hawk_val_map_t*)v)->map, &itr); + } + + gci = gci->gc_next; + } +} + +static void gc_dump_refs (hawk_rtx_t* rtx, hawk_gci_t* list) +{ + hawk_gci_t* gci; + + gci = list->gc_next; + while (gci != list) + { + printf (" %p %d\n", gci, (int)gci->gc_refs); + gci = gci->gc_next; + } + printf ("-----all_count => %d---------\n\n", (int)rtx->gc.all_count); +} + +static void gc_move_roots (hawk_gci_t* list, hawk_gci_t* reachable_list) +{ + hawk_gci_t* gci, * next; + + gci = list->gc_next; + while (gci != list) + { + next = gci->gc_next; + if (gci->gc_refs > 0) + { + gc_unchain_gci (gci); + gc_chain_gci (reachable_list, gci); + gci->gc_refs = GCI_MOVED; + } + gci = next; + } +} + +static void gc_move_reachables_from_root (hawk_gci_t* reachable_list) +{ + hawk_gci_t* gci, * igci; + hawk_val_t* v, * iv; + hawk_map_itr_t itr; + hawk_map_pair_t* pair; + + gci = reachable_list->gc_next; + while (gci != reachable_list) + { + v = hawk_gci_to_val(gci); + + /* as of now, there is only one type available - HAWK_VAL_MAP */ +/* the key part is a string. don't care. but if a generic value is allowed as a key, this should change... */ + HAWK_ASSERT (v->v_type == HAWK_VAL_MAP); + itr._dir = 0; + pair = hawk_map_getfirstpair(((hawk_val_map_t*)v)->map, &itr); + while (pair) + { + iv = (hawk_val_t*)HAWK_MAP_VPTR(pair); + if (HAWK_VPTR_IS_POINTER(iv) && iv->v_gc) + { + igci = hawk_val_to_gci(iv); + if (igci->gc_refs != GCI_MOVED) + { + gc_unchain_gci (igci); + gc_chain_gci (reachable_list, igci); + igci->gc_refs = GCI_MOVED; + } + } + pair = hawk_map_getnextpair(((hawk_val_map_t*)v)->map, &itr); + } + + gci = gci->gc_next; + } +} + +void gc_collect_garbage (hawk_rtx_t* rtx) +{ + hawk_gci_t reachable; + + gc_clone_refs (&rtx->gc.all); + gc_trace_refs (&rtx->gc.all); + +gc_dump_refs (rtx, &rtx->gc.all); + + + /*reachable.gc_prev = &reachable; + reachable.gc_next = &reachable; + gc_move_roots (&rtx->gc.all, &reachable);*/ +/* + gc_move_reachables_from_root (&reachable, &reachable); + + + destroy_all_in_ rtx->gc.all + move_reachable_back_to rtx->gc.all???*/ } /* --------------------------------------------------------------------- */ @@ -83,10 +241,8 @@ hawk_val_t* hawk_rtx_makeintval (hawk_rtx_t* rtx, hawk_int_t v) * any alignment issues on platforms requiring * aligned memory access - using the code commented out * will cause a fault on such a platform */ - - /* c = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(hawk_val_chunk_t) + HAWK_SIZEOF(hawk_val_int_t)*CHUNKSIZE); */ c = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(hawk_val_ichunk_t)); - if (!c) return HAWK_NULL; + if (HAWK_UNLIKELY(!c)) return HAWK_NULL; c->next = rtx->vmgr.ichunk; /*run->vmgr.ichunk = c;*/ @@ -114,7 +270,7 @@ hawk_val_t* hawk_rtx_makeintval (hawk_rtx_t* rtx, hawk_int_t v) val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->i_val = v; val->nde = HAWK_NULL; @@ -131,26 +287,14 @@ hawk_val_t* hawk_rtx_makefltval (hawk_rtx_t* rtx, hawk_flt_t v) if (rtx->vmgr.rfree == HAWK_NULL) { hawk_val_rchunk_t* c; - /*hawk_val_flt_t* x;*/ hawk_oow_t i; - /* c = hawk_rtx_allocmem (rtx, HAWK_SIZEOF(hawk_val_chunk_t) + HAWK_SIZEOF(hawk_val_flt_t) * CHUNKSIZE); */ c = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(hawk_val_rchunk_t)); if (!c) return HAWK_NULL; c->next = rtx->vmgr.rchunk; - /*run->vmgr.rchunk = c;*/ rtx->vmgr.rchunk = (hawk_val_chunk_t*)c; - /* - x = (hawk_val_flt_t*)(c + 1); - for (i = 0; i < CHUNKSIZE-1; i++) - x[i].nde = (hawk_nde_flt_t*)&x[i+1]; - x[i].nde = HAWK_NULL; - - run->vmgr.rfree = x; - */ - for (i = 0; i < CHUNKSIZE-1; i++) c->slot[i].nde = (hawk_nde_flt_t*)&c->slot[i+1]; c->slot[i].nde = HAWK_NULL; @@ -165,7 +309,7 @@ hawk_val_t* hawk_rtx_makefltval (hawk_rtx_t* rtx, hawk_flt_t v) val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->val = v; val->nde = HAWK_NULL; @@ -208,7 +352,7 @@ init: val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->val.len = len1 + len2; val->val.ptr = (hawk_ooch_t*)(val + 1); if (HAWK_LIKELY(str1)) hawk_copy_oochars_to_oocstr_unlimited (&val->val.ptr[0], str1, len1); @@ -427,7 +571,7 @@ hawk_val_t* hawk_rtx_makembsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* pt val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->val.len = len; val->val.ptr = (hawk_bch_t*)(val + 1); if (ptr) HAWK_MEMCPY (val->val.ptr, ptr, xsz); @@ -513,7 +657,7 @@ hawk_val_t* hawk_rtx_makerexval (hawk_rtx_t* rtx, const hawk_oocs_t* str, hawk_t val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->str.len = str->len; val->str.ptr = (hawk_ooch_t*)(val + 1); @@ -570,14 +714,19 @@ hawk_val_t* hawk_rtx_makemapval (hawk_rtx_t* rtx) }; hawk_val_map_t* val; +#if defined(HAWK_ENABLE_GC) +gc_collect_garbage(rtx); + val = (hawk_val_map_t*)gc_calloc(rtx, HAWK_SIZEOF(hawk_val_map_t) + HAWK_SIZEOF(hawk_map_t) + HAWK_SIZEOF(rtx)); +#else val = (hawk_val_map_t*)hawk_rtx_callocmem(rtx, HAWK_SIZEOF(hawk_val_map_t) + HAWK_SIZEOF(hawk_map_t) + HAWK_SIZEOF(rtx)); +#endif if (HAWK_UNLIKELY(!val)) return HAWK_NULL; val->v_type = HAWK_VAL_MAP; val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->map = (hawk_map_t*)(val + 1); if (hawk_map_init(val->map, hawk_rtx_getgem(rtx), 256, 70, HAWK_SIZEOF(hawk_ooch_t), 1) <= -1) @@ -588,6 +737,12 @@ hawk_val_t* hawk_rtx_makemapval (hawk_rtx_t* rtx) *(hawk_rtx_t**)hawk_map_getxtn(val->map) = rtx; hawk_map_setstyle (val->map, &style); +#if defined(HAWK_ENABLE_GC) + gc_chain_val (&rtx->gc.all, (hawk_val_t*)val); + rtx->gc.all_count++; + val->v_gc = 1; +#endif + return (hawk_val_t*)val; } @@ -753,7 +908,7 @@ hawk_val_t* hawk_rtx_makefunval (hawk_rtx_t* rtx, const hawk_fun_t* fun) val->v_refs = 0; val->v_static = 0; val->nstr = 0; - val->fcb = 0; + val->v_gc = 0; val->fun = (hawk_fun_t*)fun; return (hawk_val_t*)val; @@ -877,22 +1032,24 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int cache) break; case HAWK_VAL_MAP: - { + #if defined(HAWK_ENABLE_GC) + rtx->gc.all_count--; + gc_unchain_val (val); + hawk_map_fini (((hawk_val_map_t*)val)->map); + hawk_rtx_freemem (rtx, hawk_val_to_gci(val)); + #else hawk_map_fini (((hawk_val_map_t*)val)->map); hawk_rtx_freemem (rtx, val); + #endif break; - } case HAWK_VAL_REF: - { if (cache && rtx->rcache_count < HAWK_COUNTOF(rtx->rcache)) { rtx->rcache[rtx->rcache_count++] = (hawk_val_ref_t*)val; } else hawk_rtx_freemem (rtx, val); break; - } - } } }