added some code to implement gc
This commit is contained in:
parent
1285d77c1e
commit
7fe9ea0936
@ -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_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_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_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_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_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);
|
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("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("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("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 */
|
/* map(array) sort */
|
||||||
{ {HAWK_T("asort"), 5}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asort, 0 }, HAWK_NULL},
|
{ {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;
|
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)
|
static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
hawk_val_t* a0;
|
hawk_val_t* a0;
|
||||||
|
@ -379,6 +379,14 @@ struct hawk_rtx_t
|
|||||||
hawk_val_chunk_t* rchunk;
|
hawk_val_chunk_t* rchunk;
|
||||||
} vmgr;
|
} 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_nde_blk_t* active_block;
|
||||||
hawk_uint8_t* pattern_range_state;
|
hawk_uint8_t* pattern_range_state;
|
||||||
|
|
||||||
@ -495,7 +503,7 @@ struct hawk_mod_data_t
|
|||||||
(refval)->v_refs = (_nrefs); \
|
(refval)->v_refs = (_nrefs); \
|
||||||
(refval)->v_static = 0; \
|
(refval)->v_static = 0; \
|
||||||
(refval)->nstr = 0; \
|
(refval)->nstr = 0; \
|
||||||
(refval)->fcb = 0; \
|
(refval)->v_gc = 0; \
|
||||||
(refval)->id = (_id); \
|
(refval)->id = (_id); \
|
||||||
(refval)->adr = (_adr); \
|
(refval)->adr = (_adr); \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
@ -129,27 +129,29 @@ struct hawk_rtx_alt_t
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
typedef struct hawk_gc_info_t hawk_gc_info_t;
|
typedef struct hawk_gci_t hawk_gci_t;
|
||||||
struct hawk_gc_info_t
|
struct hawk_gci_t
|
||||||
{
|
{
|
||||||
hawk_gc_info_t* gc_prev;
|
hawk_gci_t* gc_prev;
|
||||||
hawk_gc_info_t* gc_next;
|
hawk_gci_t* gc_next;
|
||||||
hawk_uintptr_t gc_refs;
|
hawk_uintptr_t gc_refs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(HAWK_HAVE_INLINE)
|
#if defined(HAWK_HAVE_INLINE)
|
||||||
static HAWK_INLINE hawk_gc_info_t* hawk_val_to_gcinfo(hawk_val_t* v)
|
|
||||||
{
|
static HAWK_INLINE hawk_val_t* hawk_gci_to_val(hawk_gci_t* gci)
|
||||||
return ((hawk_gc_info_t*)v) - 1;
|
|
||||||
}
|
|
||||||
static HAWK_INLINE hawk_val_t* hawk_gcinfo_to_val(hawk_gc_info_t* gci)
|
|
||||||
{
|
{
|
||||||
return (hawk_val_t*)(gci + 1);
|
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
|
#else
|
||||||
# defined hawk_val_to_gcinfo(v) (((hawk_gc_info_t*)(v)) - 1)
|
# define hawk_val_to_gci(v) (((hawk_gci_t*)(v)) - 1)
|
||||||
# defined hawk_gcinfo_to_val(gci) ((hawk_val_t*)(((hawk_gc_info_t*)(gci)) + 1))
|
# define hawk_gci_to_val(gci) ((hawk_val_t*)(((hawk_gci_t*)(gci)) + 1))
|
||||||
#endif
|
#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_refs: 24; \
|
||||||
unsigned int v_static: 1; \
|
unsigned int v_static: 1; \
|
||||||
unsigned int nstr: 2; \
|
unsigned int nstr: 2; \
|
||||||
unsigned int fcb: 1
|
unsigned int v_gc: 1
|
||||||
*/
|
*/
|
||||||
#define HAWK_VAL_HDR \
|
#define HAWK_VAL_HDR \
|
||||||
hawk_uintptr_t v_type: 4; \
|
hawk_uintptr_t v_type: 4; \
|
||||||
hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \
|
hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \
|
||||||
hawk_uintptr_t v_static: 1; \
|
hawk_uintptr_t v_static: 1; \
|
||||||
hawk_uintptr_t nstr: 2; \
|
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:
|
* The hawk_val_t type is an abstract value type. A value commonly contains:
|
||||||
|
@ -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 */
|
/* allocate the storage for the rtx object */
|
||||||
rtx = (hawk_rtx_t*)hawk_allocmem(awk, HAWK_SIZEOF(hawk_rtx_t) + xtnsize);
|
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 */
|
/* if it fails, the failure is reported thru the awk object */
|
||||||
return HAWK_NULL;
|
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 */
|
/* initialize the rtx object */
|
||||||
HAWK_MEMSET (rtx, 0, HAWK_SIZEOF(hawk_rtx_t) + xtnsize);
|
HAWK_MEMSET (rtx, 0, HAWK_SIZEOF(hawk_rtx_t) + xtnsize);
|
||||||
rtx->_instsize = HAWK_SIZEOF(hawk_rtx_t);
|
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);
|
hawk_freemem (awk, rtx);
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_globals(rtx) <= -1)
|
if (HAWK_UNLIKELY(init_globals(rtx) <= -1))
|
||||||
{
|
{
|
||||||
hawk_rtx_errortohawk (rtx, awk);
|
hawk_rtx_errortohawk (rtx, awk);
|
||||||
fini_rtx (rtx, 0);
|
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;
|
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;
|
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*));
|
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_top = 0;
|
||||||
rtx->stack_base = 0;
|
rtx->stack_base = 0;
|
||||||
rtx->stack_limit = stack_limit;
|
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.rchunk = HAWK_NULL;
|
||||||
rtx->vmgr.rfree = 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_pos = 0;
|
||||||
rtx->inrec.buf_len = 0;
|
rtx->inrec.buf_len = 0;
|
||||||
rtx->inrec.flds = HAWK_NULL;
|
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.maxflds = 0;
|
||||||
rtx->inrec.d0 = hawk_val_nil;
|
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_UNLIKELY(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_UNLIKELY(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_UNLIKELY(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_UNLIKELY(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_UNLIKELY(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->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_UNLIKELY(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.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_UNLIKELY(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_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);
|
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_rtx_t**)hawk_htb_getxtn(rtx->named) = rtx;
|
||||||
hawk_htb_setstyle (rtx->named, &style_for_named);
|
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));
|
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.len = 4096;
|
||||||
rtx->format.tmp.inc = 4096 * 2;
|
rtx->format.tmp.inc = 4096 * 2;
|
||||||
|
|
||||||
rtx->formatmbs.tmp.ptr = (hawk_bch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_bch_t));
|
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.len = 4096;
|
||||||
rtx->formatmbs.tmp.inc = 4096 * 2;
|
rtx->formatmbs.tmp.inc = 4096 * 2;
|
||||||
|
|
||||||
if (rtx->hawk->tree.chain_size > 0)
|
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));
|
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));
|
HAWK_MEMSET (rtx->pattern_range_state, 0, rtx->hawk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t));
|
||||||
}
|
}
|
||||||
else rtx->pattern_range_state = HAWK_NULL;
|
else rtx->pattern_range_state = HAWK_NULL;
|
||||||
|
219
hawk/lib/val.c
219
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)
|
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;
|
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
|
* any alignment issues on platforms requiring
|
||||||
* aligned memory access - using the code commented out
|
* aligned memory access - using the code commented out
|
||||||
* will cause a fault on such a platform */
|
* 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));
|
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;
|
c->next = rtx->vmgr.ichunk;
|
||||||
/*run->vmgr.ichunk = c;*/
|
/*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_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->i_val = v;
|
val->i_val = v;
|
||||||
val->nde = HAWK_NULL;
|
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)
|
if (rtx->vmgr.rfree == HAWK_NULL)
|
||||||
{
|
{
|
||||||
hawk_val_rchunk_t* c;
|
hawk_val_rchunk_t* c;
|
||||||
/*hawk_val_flt_t* x;*/
|
|
||||||
hawk_oow_t i;
|
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));
|
c = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(hawk_val_rchunk_t));
|
||||||
if (!c) return HAWK_NULL;
|
if (!c) return HAWK_NULL;
|
||||||
|
|
||||||
c->next = rtx->vmgr.rchunk;
|
c->next = rtx->vmgr.rchunk;
|
||||||
/*run->vmgr.rchunk = c;*/
|
|
||||||
rtx->vmgr.rchunk = (hawk_val_chunk_t*)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++)
|
for (i = 0; i < CHUNKSIZE-1; i++)
|
||||||
c->slot[i].nde = (hawk_nde_flt_t*)&c->slot[i+1];
|
c->slot[i].nde = (hawk_nde_flt_t*)&c->slot[i+1];
|
||||||
c->slot[i].nde = HAWK_NULL;
|
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_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->val = v;
|
val->val = v;
|
||||||
val->nde = HAWK_NULL;
|
val->nde = HAWK_NULL;
|
||||||
|
|
||||||
@ -208,7 +352,7 @@ init:
|
|||||||
val->v_refs = 0;
|
val->v_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->val.len = len1 + len2;
|
val->val.len = len1 + len2;
|
||||||
val->val.ptr = (hawk_ooch_t*)(val + 1);
|
val->val.ptr = (hawk_ooch_t*)(val + 1);
|
||||||
if (HAWK_LIKELY(str1)) hawk_copy_oochars_to_oocstr_unlimited (&val->val.ptr[0], str1, len1);
|
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_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->val.len = len;
|
val->val.len = len;
|
||||||
val->val.ptr = (hawk_bch_t*)(val + 1);
|
val->val.ptr = (hawk_bch_t*)(val + 1);
|
||||||
if (ptr) HAWK_MEMCPY (val->val.ptr, ptr, xsz);
|
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_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->str.len = str->len;
|
val->str.len = str->len;
|
||||||
|
|
||||||
val->str.ptr = (hawk_ooch_t*)(val + 1);
|
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;
|
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));
|
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;
|
if (HAWK_UNLIKELY(!val)) return HAWK_NULL;
|
||||||
|
|
||||||
val->v_type = HAWK_VAL_MAP;
|
val->v_type = HAWK_VAL_MAP;
|
||||||
val->v_refs = 0;
|
val->v_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->map = (hawk_map_t*)(val + 1);
|
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)
|
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_rtx_t**)hawk_map_getxtn(val->map) = rtx;
|
||||||
hawk_map_setstyle (val->map, &style);
|
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;
|
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_refs = 0;
|
||||||
val->v_static = 0;
|
val->v_static = 0;
|
||||||
val->nstr = 0;
|
val->nstr = 0;
|
||||||
val->fcb = 0;
|
val->v_gc = 0;
|
||||||
val->fun = (hawk_fun_t*)fun;
|
val->fun = (hawk_fun_t*)fun;
|
||||||
|
|
||||||
return (hawk_val_t*)val;
|
return (hawk_val_t*)val;
|
||||||
@ -877,14 +1032,18 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int cache)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HAWK_VAL_MAP:
|
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_map_fini (((hawk_val_map_t*)val)->map);
|
||||||
hawk_rtx_freemem (rtx, val);
|
hawk_rtx_freemem (rtx, val);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case HAWK_VAL_REF:
|
case HAWK_VAL_REF:
|
||||||
{
|
|
||||||
if (cache && rtx->rcache_count < HAWK_COUNTOF(rtx->rcache))
|
if (cache && rtx->rcache_count < HAWK_COUNTOF(rtx->rcache))
|
||||||
{
|
{
|
||||||
rtx->rcache[rtx->rcache_count++] = (hawk_val_ref_t*)val;
|
rtx->rcache[rtx->rcache_count++] = (hawk_val_ref_t*)val;
|
||||||
@ -892,8 +1051,6 @@ void hawk_rtx_freeval (hawk_rtx_t* rtx, hawk_val_t* val, int cache)
|
|||||||
else hawk_rtx_freemem (rtx, val);
|
else hawk_rtx_freemem (rtx, val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user