working on lazy sweeping
This commit is contained in:
parent
1aa67bbc00
commit
ebcb6215fb
@ -10585,7 +10585,7 @@ static void gc_oopbuf (moo_t* moo, moo_oopbuf_t* oopbuf)
|
|||||||
|
|
||||||
for (i = 0; i < oopbuf->count; i++)
|
for (i = 0; i < oopbuf->count; i++)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = moo_moveoop(moo, oopbuf->ptr[i]);
|
moo_oop_t x = moo_updateoopforgc(moo, oopbuf->ptr[i]);
|
||||||
oopbuf->ptr[i] = x;
|
oopbuf->ptr[i] = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10614,12 +10614,12 @@ static void gc_cunit_chain (moo_t* moo)
|
|||||||
pd = (moo_cunit_pooldic_t*)cunit;
|
pd = (moo_cunit_pooldic_t*)cunit;
|
||||||
if (pd->pd_oop)
|
if (pd->pd_oop)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = moo_moveoop(moo, (moo_oop_t)pd->pd_oop);
|
moo_oop_t x = moo_updateoopforgc(moo, (moo_oop_t)pd->pd_oop);
|
||||||
pd->pd_oop = (moo_oop_dic_t)x;
|
pd->pd_oop = (moo_oop_dic_t)x;
|
||||||
}
|
}
|
||||||
if (pd->ns_oop)
|
if (pd->ns_oop)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = moo_moveoop(moo, (moo_oop_t)pd->ns_oop);
|
moo_oop_t x = moo_updateoopforgc(moo, (moo_oop_t)pd->ns_oop);
|
||||||
pd->ns_oop = (moo_oop_nsdic_t)x;
|
pd->ns_oop = (moo_oop_nsdic_t)x;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -10632,29 +10632,29 @@ static void gc_cunit_chain (moo_t* moo)
|
|||||||
cc = (moo_cunit_class_t*)cunit;
|
cc = (moo_cunit_class_t*)cunit;
|
||||||
|
|
||||||
if (cc->self_oop)
|
if (cc->self_oop)
|
||||||
cc->self_oop = (moo_oop_class_t)moo_moveoop(moo, (moo_oop_t)cc->self_oop);
|
cc->self_oop = (moo_oop_class_t)moo_updateoopforgc(moo, (moo_oop_t)cc->self_oop);
|
||||||
|
|
||||||
if (cc->super_oop)
|
if (cc->super_oop)
|
||||||
cc->super_oop = moo_moveoop(moo, cc->super_oop);
|
cc->super_oop = moo_updateoopforgc(moo, cc->super_oop);
|
||||||
|
|
||||||
for (i = 0; i < MOO_COUNTOF(cc->var); i++)
|
for (i = 0; i < MOO_COUNTOF(cc->var); i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < cc->var[i].initv_count; j++)
|
for (j = 0; j < cc->var[i].initv_count; j++)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = cc->var[i].initv[j].v;
|
register moo_oop_t x = cc->var[i].initv[j].v;
|
||||||
if (x) cc->var[i].initv[j].v = moo_moveoop(moo, x);
|
if (x) cc->var[i].initv[j].v = moo_updateoopforgc(moo, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc->ns_oop)
|
if (cc->ns_oop)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = moo_moveoop(moo, (moo_oop_t)cc->ns_oop);
|
moo_oop_t x = moo_updateoopforgc(moo, (moo_oop_t)cc->ns_oop);
|
||||||
cc->ns_oop = (moo_oop_nsdic_t)x;
|
cc->ns_oop = (moo_oop_nsdic_t)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc->superns_oop)
|
if (cc->superns_oop)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = moo_moveoop(moo, (moo_oop_t)cc->superns_oop);
|
moo_oop_t x = moo_updateoopforgc(moo, (moo_oop_t)cc->superns_oop);
|
||||||
cc->superns_oop = (moo_oop_nsdic_t)x;
|
cc->superns_oop = (moo_oop_nsdic_t)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10672,11 +10672,11 @@ static void gc_cunit_chain (moo_t* moo)
|
|||||||
ifce = (moo_cunit_interface_t*)cunit;
|
ifce = (moo_cunit_interface_t*)cunit;
|
||||||
|
|
||||||
if (ifce->self_oop)
|
if (ifce->self_oop)
|
||||||
ifce->self_oop = (moo_oop_interface_t)moo_moveoop(moo, (moo_oop_t)ifce->self_oop);
|
ifce->self_oop = (moo_oop_interface_t)moo_updateoopforgc(moo, (moo_oop_t)ifce->self_oop);
|
||||||
|
|
||||||
if (ifce->ns_oop)
|
if (ifce->ns_oop)
|
||||||
{
|
{
|
||||||
register moo_oop_t x = moo_moveoop(moo, (moo_oop_t)ifce->ns_oop);
|
moo_oop_t x = moo_updateoopforgc(moo, (moo_oop_t)ifce->ns_oop);
|
||||||
ifce->ns_oop = (moo_oop_nsdic_t)x;
|
ifce->ns_oop = (moo_oop_nsdic_t)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ static MOO_INLINE void vm_cleanup (moo_t* moo)
|
|||||||
moo_deregallfinalizables (moo);
|
moo_deregallfinalizables (moo);
|
||||||
|
|
||||||
/* final garbage collection */
|
/* final garbage collection */
|
||||||
moo_gc (moo);
|
moo_gc (moo, 1);
|
||||||
|
|
||||||
MOO_DEBUG0 (moo, "VM cleaned up\n");
|
MOO_DEBUG0 (moo, "VM cleaned up\n");
|
||||||
}
|
}
|
||||||
@ -6356,6 +6356,7 @@ int moo_execute (moo_t* moo)
|
|||||||
moo->proc_switched = 0;
|
moo->proc_switched = 0;
|
||||||
moo->abort_req = 0;
|
moo->abort_req = 0;
|
||||||
|
|
||||||
|
moo->gci.lazy_sweep = 1;
|
||||||
n = __execute (moo);
|
n = __execute (moo);
|
||||||
|
|
||||||
vm_cleanup (moo);
|
vm_cleanup (moo);
|
||||||
|
229
moo/lib/gc.c
229
moo/lib/gc.c
@ -799,7 +799,7 @@ 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 defined(MOO_ENABLE_GC_MARK_SWEEP)
|
||||||
#if 0
|
#if 0
|
||||||
static MOO_INLINE void gc_mark (moo_t* moo, moo_oop_t oop)
|
static MOO_INLINE void gc_ms_mark (moo_t* moo, moo_oop_t oop)
|
||||||
{
|
{
|
||||||
moo_oow_t i, sz;
|
moo_oow_t i, sz;
|
||||||
|
|
||||||
@ -812,7 +812,7 @@ static MOO_INLINE void gc_mark (moo_t* moo, moo_oop_t oop)
|
|||||||
|
|
||||||
MOO_OBJ_SET_FLAGS_MOVED(oop, 1); /* mark */
|
MOO_OBJ_SET_FLAGS_MOVED(oop, 1); /* mark */
|
||||||
|
|
||||||
gc_mark (moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop)); /* TODO: remove recursion */
|
gc_ms_mark (moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop)); /* TODO: remove recursion */
|
||||||
|
|
||||||
if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)
|
if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)
|
||||||
{
|
{
|
||||||
@ -836,12 +836,12 @@ static MOO_INLINE void gc_mark (moo_t* moo, moo_oop_t oop)
|
|||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
moo_oop_t tmp = MOO_OBJ_GET_OOP_VAL(oop, i);
|
moo_oop_t tmp = MOO_OBJ_GET_OOP_VAL(oop, i);
|
||||||
if (MOO_OOP_IS_POINTER(tmp)) gc_mark (moo, tmp); /* TODO: no resursion */
|
if (MOO_OOP_IS_POINTER(tmp)) gc_ms_mark (moo, tmp); /* TODO: no resursion */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static MOO_INLINE void gc_mark_object (moo_t* moo, moo_oop_t oop)
|
static MOO_INLINE void gc_ms_mark_object (moo_t* moo, moo_oop_t oop)
|
||||||
{
|
{
|
||||||
#if defined(MOO_SUPPORT_GC_DURING_IGNITION)
|
#if defined(MOO_SUPPORT_GC_DURING_IGNITION)
|
||||||
if (!oop) return;
|
if (!oop) return;
|
||||||
@ -854,7 +854,7 @@ MOO_ASSERT (moo, moo->gci.stack.len < moo->gci.stack.capa);
|
|||||||
if (moo->gci.stack.len > moo->gci.stack.max) moo->gci.stack.max = moo->gci.stack.len;
|
if (moo->gci.stack.len > moo->gci.stack.max) moo->gci.stack.max = moo->gci.stack.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void gc_scan_stack (moo_t* moo)
|
static MOO_INLINE void gc_ms_scan_stack (moo_t* moo)
|
||||||
{
|
{
|
||||||
moo_oop_t oop;
|
moo_oop_t oop;
|
||||||
|
|
||||||
@ -862,7 +862,7 @@ static MOO_INLINE void gc_scan_stack (moo_t* moo)
|
|||||||
{
|
{
|
||||||
oop = moo->gci.stack.ptr[--moo->gci.stack.len];
|
oop = moo->gci.stack.ptr[--moo->gci.stack.len];
|
||||||
|
|
||||||
gc_mark_object (moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop));
|
gc_ms_mark_object (moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop));
|
||||||
|
|
||||||
if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)
|
if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)
|
||||||
{
|
{
|
||||||
@ -885,20 +885,20 @@ static MOO_INLINE void gc_scan_stack (moo_t* moo)
|
|||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
gc_mark_object (moo, MOO_OBJ_GET_OOP_VAL(oop, i));
|
gc_ms_mark_object (moo, MOO_OBJ_GET_OOP_VAL(oop, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void gc_mark (moo_t* moo, moo_oop_t oop)
|
static MOO_INLINE void gc_ms_mark (moo_t* moo, moo_oop_t oop)
|
||||||
{
|
{
|
||||||
gc_mark_object (moo, oop);
|
gc_ms_mark_object (moo, oop);
|
||||||
gc_scan_stack (moo);
|
gc_ms_scan_stack (moo);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static MOO_INLINE void gc_mark_root (moo_t* moo)
|
static MOO_INLINE void gc_ms_mark_roots (moo_t* moo)
|
||||||
{
|
{
|
||||||
moo_oow_t i, gcfin_count;
|
moo_oow_t i, gcfin_count;
|
||||||
moo_evtcb_t* cb;
|
moo_evtcb_t* cb;
|
||||||
@ -913,57 +913,57 @@ static MOO_INLINE void gc_mark_root (moo_t* moo)
|
|||||||
moo->processor->active->sp = MOO_SMOOI_TO_OOP(moo->sp);
|
moo->processor->active->sp = MOO_SMOOI_TO_OOP(moo->sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_mark (moo, moo->_nil);
|
gc_ms_mark (moo, moo->_nil);
|
||||||
gc_mark (moo, moo->_true);
|
gc_ms_mark (moo, moo->_true);
|
||||||
gc_mark (moo, moo->_false);
|
gc_ms_mark (moo, moo->_false);
|
||||||
|
|
||||||
for (i = 0; i < MOO_COUNTOF(kernel_classes); i++)
|
for (i = 0; i < MOO_COUNTOF(kernel_classes); i++)
|
||||||
{
|
{
|
||||||
gc_mark (moo, *(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset));
|
gc_ms_mark (moo, *(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_mark (moo, (moo_oop_t)moo->sysdic);
|
gc_ms_mark (moo, (moo_oop_t)moo->sysdic);
|
||||||
gc_mark (moo, (moo_oop_t)moo->processor);
|
gc_ms_mark (moo, (moo_oop_t)moo->processor);
|
||||||
gc_mark (moo, (moo_oop_t)moo->nil_process);
|
gc_ms_mark (moo, (moo_oop_t)moo->nil_process);
|
||||||
gc_mark (moo, (moo_oop_t)moo->dicnewsym);
|
gc_ms_mark (moo, (moo_oop_t)moo->dicnewsym);
|
||||||
gc_mark (moo, (moo_oop_t)moo->dicputassocsym);
|
gc_ms_mark (moo, (moo_oop_t)moo->dicputassocsym);
|
||||||
gc_mark (moo, (moo_oop_t)moo->does_not_understand_sym);
|
gc_ms_mark (moo, (moo_oop_t)moo->does_not_understand_sym);
|
||||||
gc_mark (moo, (moo_oop_t)moo->primitive_failed_sym);
|
gc_ms_mark (moo, (moo_oop_t)moo->primitive_failed_sym);
|
||||||
gc_mark (moo, (moo_oop_t)moo->unwindto_return_sym);
|
gc_ms_mark (moo, (moo_oop_t)moo->unwindto_return_sym);
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_list_count; i++)
|
for (i = 0; i < moo->sem_list_count; i++)
|
||||||
{
|
{
|
||||||
gc_mark (moo, (moo_oop_t)moo->sem_list[i]);
|
gc_ms_mark (moo, (moo_oop_t)moo->sem_list[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_heap_count; i++)
|
for (i = 0; i < moo->sem_heap_count; i++)
|
||||||
{
|
{
|
||||||
gc_mark (moo, (moo_oop_t)moo->sem_heap[i]);
|
gc_ms_mark (moo, (moo_oop_t)moo->sem_heap[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_io_tuple_count; i++)
|
for (i = 0; i < moo->sem_io_tuple_count; i++)
|
||||||
{
|
{
|
||||||
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT])
|
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT])
|
||||||
gc_mark (moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT]);
|
gc_ms_mark (moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT]);
|
||||||
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT])
|
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT])
|
||||||
gc_mark (moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT]);
|
gc_ms_mark (moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT]);
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_mark (moo, (moo_oop_t)moo->sem_gcfin);
|
gc_ms_mark (moo, (moo_oop_t)moo->sem_gcfin);
|
||||||
|
|
||||||
for (i = 0; i < moo->proc_map_capa; i++)
|
for (i = 0; i < moo->proc_map_capa; i++)
|
||||||
{
|
{
|
||||||
gc_mark (moo, moo->proc_map[i]);
|
gc_ms_mark (moo, moo->proc_map[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < moo->volat_count; i++)
|
for (i = 0; i < moo->volat_count; i++)
|
||||||
{
|
{
|
||||||
gc_mark (moo, *moo->volat_stack[i]);
|
gc_ms_mark (moo, *moo->volat_stack[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moo->initial_context) gc_mark (moo, (moo_oop_t)moo->initial_context);
|
if (moo->initial_context) gc_ms_mark (moo, (moo_oop_t)moo->initial_context);
|
||||||
if (moo->active_context) gc_mark (moo, (moo_oop_t)moo->active_context);
|
if (moo->active_context) gc_ms_mark (moo, (moo_oop_t)moo->active_context);
|
||||||
if (moo->active_method) gc_mark (moo, (moo_oop_t)moo->active_method);
|
if (moo->active_method) gc_ms_mark (moo, (moo_oop_t)moo->active_method);
|
||||||
|
|
||||||
moo_rbt_walk (&moo->modtab, call_module_gc, moo);
|
moo_rbt_walk (&moo->modtab, call_module_gc, moo);
|
||||||
|
|
||||||
@ -978,7 +978,7 @@ static MOO_INLINE void gc_mark_root (moo_t* moo)
|
|||||||
{
|
{
|
||||||
compact_symbol_table (moo, moo->_nil); /* delete symbol table entries that are not marked */
|
compact_symbol_table (moo, moo->_nil); /* delete symbol table entries that are not marked */
|
||||||
#if 0
|
#if 0
|
||||||
gc_mark (moo, (moo_oop_t)moo->symtab); /* mark the symbol table */
|
gc_ms_mark (moo, (moo_oop_t)moo->symtab); /* mark the symbol table */
|
||||||
#else
|
#else
|
||||||
MOO_OBJ_SET_FLAGS_MOVED(moo->symtab, 1); /* mark */
|
MOO_OBJ_SET_FLAGS_MOVED(moo->symtab, 1); /* mark */
|
||||||
MOO_OBJ_SET_FLAGS_MOVED(moo->symtab->bucket, 1); /* mark */
|
MOO_OBJ_SET_FLAGS_MOVED(moo->symtab->bucket, 1); /* mark */
|
||||||
@ -993,7 +993,60 @@ static MOO_INLINE void gc_mark_root (moo_t* moo)
|
|||||||
moo_clearmethodcache (moo);
|
moo_clearmethodcache (moo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void gc_sweep (moo_t* moo)
|
void moo_gc_ms_sweep_lazy (moo_t* moo, moo_oow_t allocsize)
|
||||||
|
{
|
||||||
|
moo_gchdr_t* curr, * next, * prev;
|
||||||
|
moo_oop_t obj;
|
||||||
|
moo_oow_t freed_size;
|
||||||
|
|
||||||
|
if (!moo->gci.ls.curr) return;
|
||||||
|
|
||||||
|
freed_size = 0;
|
||||||
|
|
||||||
|
//printf ("starting lazy sweep...gci.ls.curr [%p]\n", moo->gci.ls.curr);
|
||||||
|
prev = moo->gci.ls.prev;
|
||||||
|
curr = moo->gci.ls.curr;
|
||||||
|
|
||||||
|
while (curr)
|
||||||
|
{
|
||||||
|
next = curr->next;
|
||||||
|
obj = (moo_oop_t)(curr + 1);
|
||||||
|
|
||||||
|
if (MOO_OBJ_GET_FLAGS_MOVED(obj)) /* if marked */
|
||||||
|
{
|
||||||
|
MOO_OBJ_SET_FLAGS_MOVED (obj, 0); /* unmark */
|
||||||
|
prev = curr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_oow_t objsize;
|
||||||
|
|
||||||
|
if (prev) prev->next = next;
|
||||||
|
else moo->gci.b = next;
|
||||||
|
|
||||||
|
objsize = MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, obj);
|
||||||
|
freed_size += objsize;
|
||||||
|
moo->gci.bsz -= objsize;
|
||||||
|
moo_freeheapmem (moo, moo->heap, curr); /* destroy */
|
||||||
|
|
||||||
|
if (freed_size > allocsize) /* TODO: can it secure large enough space? */
|
||||||
|
{
|
||||||
|
//printf ("stopping lazy sweeping after %lu free, allocsize %lu\n", (unsigned long int)freed_size, (unsigned long int)allocsize);
|
||||||
|
moo->gci.ls.curr = next; /* let the next lazy sweeping begin at this point */
|
||||||
|
moo->gci.ls.prev = prev;
|
||||||
|
//printf ("finished lazy sweep...\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
moo->gci.ls.curr = MOO_NULL;
|
||||||
|
//printf ("finished lazy sweep...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static MOO_INLINE void gc_ms_sweep (moo_t* moo)
|
||||||
{
|
{
|
||||||
moo_gchdr_t* curr, * next, * prev;
|
moo_gchdr_t* curr, * next, * prev;
|
||||||
moo_oop_t obj;
|
moo_oop_t obj;
|
||||||
@ -1005,30 +1058,31 @@ static MOO_INLINE void gc_sweep (moo_t* moo)
|
|||||||
next = curr->next;
|
next = curr->next;
|
||||||
obj = (moo_oop_t)(curr + 1);
|
obj = (moo_oop_t)(curr + 1);
|
||||||
|
|
||||||
if (MOO_OBJ_GET_FLAGS_MOVED(obj))
|
if (MOO_OBJ_GET_FLAGS_MOVED(obj)) /* if marked */
|
||||||
{
|
{
|
||||||
/* unmark */
|
MOO_OBJ_SET_FLAGS_MOVED (obj, 0); /* unmark */
|
||||||
MOO_OBJ_SET_FLAGS_MOVED (obj, 0);
|
|
||||||
prev = curr;
|
prev = curr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* destroy */
|
|
||||||
if (prev) prev->next = next;
|
if (prev) prev->next = next;
|
||||||
else moo->gci.b = next;
|
else moo->gci.b = next;
|
||||||
|
|
||||||
moo->gci.bsz -= MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, obj);
|
moo->gci.bsz -= MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, obj);
|
||||||
moo_freeheapmem (moo, moo->heap, curr);
|
moo_freeheapmem (moo, moo->heap, curr); /* destroy */
|
||||||
}
|
}
|
||||||
|
|
||||||
curr = next;
|
curr = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf ("finised full sweep...\n");
|
||||||
|
moo->gci.ls.curr = MOO_NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
static moo_oop_t move_oop_in_heap_space (moo_t* moo, moo_oop_t oop)
|
static moo_oop_t gc_ss_move_oop (moo_t* moo, moo_oop_t oop)
|
||||||
{
|
{
|
||||||
#if defined(MOO_SUPPORT_GC_DURING_IGNITION)
|
#if defined(MOO_SUPPORT_GC_DURING_IGNITION)
|
||||||
if (!oop) return oop;
|
if (!oop) return oop;
|
||||||
@ -1095,7 +1149,7 @@ static moo_oop_t move_oop_in_heap_space (moo_t* moo, moo_oop_t oop)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t** end)
|
static moo_uint8_t* gc_ss_scan_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t** end)
|
||||||
{
|
{
|
||||||
while (ptr < *end) /* the end pointer may get changed, especially the new space. so it's moo_int8_t** */
|
while (ptr < *end) /* the end pointer may get changed, especially the new space. so it's moo_int8_t** */
|
||||||
{
|
{
|
||||||
@ -1108,7 +1162,7 @@ static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t**
|
|||||||
|
|
||||||
nbytes_aligned = moo_getobjpayloadbytes(moo, oop);
|
nbytes_aligned = moo_getobjpayloadbytes(moo, oop);
|
||||||
|
|
||||||
tmp = moo_moveoop(moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop));
|
tmp = moo_updateoopforgc(moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop));
|
||||||
MOO_OBJ_SET_CLASS (oop, tmp);
|
MOO_OBJ_SET_CLASS (oop, tmp);
|
||||||
|
|
||||||
if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)
|
if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)
|
||||||
@ -1137,7 +1191,7 @@ static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t**
|
|||||||
{
|
{
|
||||||
/* i must not use MOO_STORE_OOP() as this operation is
|
/* i must not use MOO_STORE_OOP() as this operation is
|
||||||
* part of garbage collection. */
|
* part of garbage collection. */
|
||||||
tmp = moo_moveoop(moo, tmp);
|
tmp = moo_updateoopforgc(moo, tmp);
|
||||||
MOO_OBJ_SET_OOP_VAL (oop, i, tmp);
|
MOO_OBJ_SET_OOP_VAL (oop, i, tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1170,7 +1224,7 @@ static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t**
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void scan_roots (moo_t* moo)
|
static void gc_ss_scan_roots (moo_t* moo)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* move a referenced object to the new heap.
|
* move a referenced object to the new heap.
|
||||||
@ -1206,63 +1260,63 @@ static void scan_roots (moo_t* moo)
|
|||||||
old_nil = moo->_nil;
|
old_nil = moo->_nil;
|
||||||
|
|
||||||
/* move _nil and the root object table */
|
/* move _nil and the root object table */
|
||||||
moo->_nil = moo_moveoop(moo, moo->_nil);
|
moo->_nil = moo_updateoopforgc(moo, moo->_nil);
|
||||||
moo->_true = moo_moveoop(moo, moo->_true);
|
moo->_true = moo_updateoopforgc(moo, moo->_true);
|
||||||
moo->_false = moo_moveoop(moo, moo->_false);
|
moo->_false = moo_updateoopforgc(moo, moo->_false);
|
||||||
|
|
||||||
for (i = 0; i < MOO_COUNTOF(kernel_classes); i++)
|
for (i = 0; i < MOO_COUNTOF(kernel_classes); i++)
|
||||||
{
|
{
|
||||||
moo_oop_t tmp;
|
moo_oop_t tmp;
|
||||||
tmp = *(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset);
|
tmp = *(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset);
|
||||||
tmp = moo_moveoop(moo, tmp);
|
tmp = moo_updateoopforgc(moo, tmp);
|
||||||
*(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset) = tmp;
|
*(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset) = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
moo->sysdic = (moo_oop_nsdic_t)moo_moveoop(moo, (moo_oop_t)moo->sysdic);
|
moo->sysdic = (moo_oop_nsdic_t)moo_updateoopforgc(moo, (moo_oop_t)moo->sysdic);
|
||||||
moo->processor = (moo_oop_process_scheduler_t)moo_moveoop(moo, (moo_oop_t)moo->processor);
|
moo->processor = (moo_oop_process_scheduler_t)moo_updateoopforgc(moo, (moo_oop_t)moo->processor);
|
||||||
moo->nil_process = (moo_oop_process_t)moo_moveoop(moo, (moo_oop_t)moo->nil_process);
|
moo->nil_process = (moo_oop_process_t)moo_updateoopforgc(moo, (moo_oop_t)moo->nil_process);
|
||||||
moo->dicnewsym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->dicnewsym);
|
moo->dicnewsym = (moo_oop_char_t)moo_updateoopforgc(moo, (moo_oop_t)moo->dicnewsym);
|
||||||
moo->dicputassocsym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->dicputassocsym);
|
moo->dicputassocsym = (moo_oop_char_t)moo_updateoopforgc(moo, (moo_oop_t)moo->dicputassocsym);
|
||||||
moo->does_not_understand_sym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->does_not_understand_sym);
|
moo->does_not_understand_sym = (moo_oop_char_t)moo_updateoopforgc(moo, (moo_oop_t)moo->does_not_understand_sym);
|
||||||
moo->primitive_failed_sym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->primitive_failed_sym);
|
moo->primitive_failed_sym = (moo_oop_char_t)moo_updateoopforgc(moo, (moo_oop_t)moo->primitive_failed_sym);
|
||||||
moo->unwindto_return_sym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->unwindto_return_sym);
|
moo->unwindto_return_sym = (moo_oop_char_t)moo_updateoopforgc(moo, (moo_oop_t)moo->unwindto_return_sym);
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_list_count; i++)
|
for (i = 0; i < moo->sem_list_count; i++)
|
||||||
{
|
{
|
||||||
moo->sem_list[i] = (moo_oop_semaphore_t)moo_moveoop(moo, (moo_oop_t)moo->sem_list[i]);
|
moo->sem_list[i] = (moo_oop_semaphore_t)moo_updateoopforgc(moo, (moo_oop_t)moo->sem_list[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_heap_count; i++)
|
for (i = 0; i < moo->sem_heap_count; i++)
|
||||||
{
|
{
|
||||||
moo->sem_heap[i] = (moo_oop_semaphore_t)moo_moveoop(moo, (moo_oop_t)moo->sem_heap[i]);
|
moo->sem_heap[i] = (moo_oop_semaphore_t)moo_updateoopforgc(moo, (moo_oop_t)moo->sem_heap[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_io_tuple_count; i++)
|
for (i = 0; i < moo->sem_io_tuple_count; i++)
|
||||||
{
|
{
|
||||||
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT])
|
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT])
|
||||||
moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT] = (moo_oop_semaphore_t)moo_moveoop(moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT]);
|
moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT] = (moo_oop_semaphore_t)moo_updateoopforgc(moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_INPUT]);
|
||||||
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT])
|
if (moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT])
|
||||||
moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT] = (moo_oop_semaphore_t)moo_moveoop(moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT]);
|
moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT] = (moo_oop_semaphore_t)moo_updateoopforgc(moo, (moo_oop_t)moo->sem_io_tuple[i].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT]);
|
||||||
}
|
}
|
||||||
|
|
||||||
moo->sem_gcfin = (moo_oop_semaphore_t)moo_moveoop(moo, (moo_oop_t)moo->sem_gcfin);
|
moo->sem_gcfin = (moo_oop_semaphore_t)moo_updateoopforgc(moo, (moo_oop_t)moo->sem_gcfin);
|
||||||
|
|
||||||
for (i = 0; i < moo->proc_map_capa; i++)
|
for (i = 0; i < moo->proc_map_capa; i++)
|
||||||
{
|
{
|
||||||
moo->proc_map[i] = moo_moveoop(moo, moo->proc_map[i]);
|
moo->proc_map[i] = moo_updateoopforgc(moo, moo->proc_map[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < moo->volat_count; i++)
|
for (i = 0; i < moo->volat_count; i++)
|
||||||
{
|
{
|
||||||
*moo->volat_stack[i] = moo_moveoop(moo, *moo->volat_stack[i]);
|
*moo->volat_stack[i] = moo_updateoopforgc(moo, *moo->volat_stack[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moo->initial_context)
|
if (moo->initial_context)
|
||||||
moo->initial_context = (moo_oop_context_t)moo_moveoop(moo, (moo_oop_t)moo->initial_context);
|
moo->initial_context = (moo_oop_context_t)moo_updateoopforgc(moo, (moo_oop_t)moo->initial_context);
|
||||||
if (moo->active_context)
|
if (moo->active_context)
|
||||||
moo->active_context = (moo_oop_context_t)moo_moveoop(moo, (moo_oop_t)moo->active_context);
|
moo->active_context = (moo_oop_context_t)moo_updateoopforgc(moo, (moo_oop_t)moo->active_context);
|
||||||
if (moo->active_method)
|
if (moo->active_method)
|
||||||
moo->active_method = (moo_oop_method_t)moo_moveoop(moo, (moo_oop_t)moo->active_method);
|
moo->active_method = (moo_oop_method_t)moo_updateoopforgc(moo, (moo_oop_t)moo->active_method);
|
||||||
|
|
||||||
moo_rbt_walk (&moo->modtab, call_module_gc, moo);
|
moo_rbt_walk (&moo->modtab, call_module_gc, moo);
|
||||||
|
|
||||||
@ -1272,16 +1326,16 @@ static void scan_roots (moo_t* moo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* scan the objects in the permspace in case an object there points to an object outside the permspace */
|
/* scan the objects in the permspace in case an object there points to an object outside the permspace */
|
||||||
scan_heap_space (moo, (moo_uint8_t*)MOO_ALIGN((moo_uintptr_t)moo->heap->permspace.base, MOO_SIZEOF(moo_oop_t)), &moo->heap->permspace.ptr);
|
gc_ss_scan_space (moo, (moo_uint8_t*)MOO_ALIGN((moo_uintptr_t)moo->heap->permspace.base, MOO_SIZEOF(moo_oop_t)), &moo->heap->permspace.ptr);
|
||||||
|
|
||||||
/* scan the new heap to move referenced objects */
|
/* scan the new heap to move referenced objects */
|
||||||
newspace_scan_ptr = scan_heap_space(moo, newspace_scan_ptr, &moo->heap->newspace.ptr);
|
newspace_scan_ptr = gc_ss_scan_space(moo, newspace_scan_ptr, &moo->heap->newspace.ptr);
|
||||||
|
|
||||||
/* check finalizable objects registered and scan the heap again.
|
/* check finalizable objects registered and scan the heap again.
|
||||||
* symbol table compation is placed after this phase assuming that
|
* symbol table compation is placed after this phase assuming that
|
||||||
* no symbol is added to be finalized. */
|
* no symbol is added to be finalized. */
|
||||||
gcfin_count = move_finalizable_objects(moo);
|
gcfin_count = move_finalizable_objects(moo);
|
||||||
newspace_scan_ptr = scan_heap_space(moo, newspace_scan_ptr, &moo->heap->newspace.ptr);
|
newspace_scan_ptr = gc_ss_scan_space(moo, newspace_scan_ptr, &moo->heap->newspace.ptr);
|
||||||
|
|
||||||
/* traverse the symbol table for unreferenced symbols.
|
/* traverse the symbol table for unreferenced symbols.
|
||||||
* if the symbol has not moved to the new heap, the symbol
|
* if the symbol has not moved to the new heap, the symbol
|
||||||
@ -1290,12 +1344,12 @@ static void scan_roots (moo_t* moo)
|
|||||||
/*if (!moo->igniting) */ compact_symbol_table (moo, old_nil);
|
/*if (!moo->igniting) */ compact_symbol_table (moo, old_nil);
|
||||||
|
|
||||||
/* move the symbol table itself */
|
/* move the symbol table itself */
|
||||||
moo->symtab = (moo_oop_dic_t)moo_moveoop(moo, (moo_oop_t)moo->symtab);
|
moo->symtab = (moo_oop_dic_t)moo_updateoopforgc(moo, (moo_oop_t)moo->symtab);
|
||||||
|
|
||||||
/* scan the new heap again from the end position of
|
/* scan the new heap again from the end position of
|
||||||
* the previous scan to move referenced objects by
|
* the previous scan to move referenced objects by
|
||||||
* the symbol table. */
|
* the symbol table. */
|
||||||
newspace_scan_ptr = scan_heap_space(moo, newspace_scan_ptr, &moo->heap->newspace.ptr);
|
newspace_scan_ptr = gc_ss_scan_space(moo, newspace_scan_ptr, &moo->heap->newspace.ptr);
|
||||||
|
|
||||||
/* the contents of the current heap is not needed any more.
|
/* the contents of the current heap is not needed any more.
|
||||||
* reset the upper bound to the base. don't forget to align the heap
|
* reset the upper bound to the base. don't forget to align the heap
|
||||||
@ -1338,37 +1392,48 @@ static void scan_roots (moo_t* moo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void moo_gc (moo_t* moo)
|
void moo_gc (moo_t* moo, int full)
|
||||||
{
|
{
|
||||||
#if defined(MOO_ENABLE_GC_MARK_SWEEP)
|
#if defined(MOO_ENABLE_GC_MARK_SWEEP)
|
||||||
if (moo->gc_type == MOO_GC_TYPE_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_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.len = 0;
|
||||||
/*moo->gci.stack.max = 0;*/
|
/*moo->gci.stack.max = 0;*/
|
||||||
gc_mark_root (moo);
|
gc_ms_mark_roots (moo);
|
||||||
gc_sweep (moo);
|
|
||||||
|
if (!full && moo->gci.lazy_sweep)
|
||||||
|
{
|
||||||
|
moo->gci.ls.prev = MOO_NULL;
|
||||||
|
moo->gci.ls.curr = moo->gci.b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gc_ms_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);
|
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
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
scan_roots (moo);
|
gc_ss_scan_roots (moo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop)
|
moo_oop_t moo_updateoopforgc (moo_t* moo, moo_oop_t oop)
|
||||||
{
|
{
|
||||||
#if defined(MOO_ENABLE_GC_MARK_SWEEP)
|
#if defined(MOO_ENABLE_GC_MARK_SWEEP)
|
||||||
if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP)
|
if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP)
|
||||||
{
|
{
|
||||||
gc_mark (moo, oop);
|
gc_ms_mark (moo, oop);
|
||||||
return oop;
|
return oop;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return move_oop_in_heap_space(moo, oop);
|
return gc_ss_move_oop(moo, oop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1502,7 +1567,7 @@ static moo_oow_t move_finalizable_objects (moo_t* moo)
|
|||||||
for (x = moo->collectable.first; x; x = x->next)
|
for (x = moo->collectable.first; x; x = x->next)
|
||||||
{
|
{
|
||||||
MOO_ASSERT (moo, (MOO_OBJ_GET_FLAGS_GCFIN(x->oop) & (MOO_GCFIN_FINALIZABLE | MOO_GCFIN_FINALIZED)) == MOO_GCFIN_FINALIZABLE);
|
MOO_ASSERT (moo, (MOO_OBJ_GET_FLAGS_GCFIN(x->oop) & (MOO_GCFIN_FINALIZABLE | MOO_GCFIN_FINALIZED)) == MOO_GCFIN_FINALIZABLE);
|
||||||
x->oop = moo_moveoop(moo, x->oop);
|
x->oop = moo_updateoopforgc(moo, x->oop);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = moo->finalizable.first; x; )
|
for (x = moo->finalizable.first; x; )
|
||||||
@ -1522,7 +1587,7 @@ static moo_oow_t move_finalizable_objects (moo_t* moo)
|
|||||||
* however this is quite unlikely because some key objects for VM execution
|
* however this is quite unlikely because some key objects for VM execution
|
||||||
* like context objects doesn't require finalization. */
|
* like context objects doesn't require finalization. */
|
||||||
|
|
||||||
x->oop = moo_moveoop(moo, x->oop);
|
x->oop = moo_updateoopforgc(moo, x->oop);
|
||||||
|
|
||||||
/* remove it from the finalizable list */
|
/* remove it from the finalizable list */
|
||||||
MOO_DELETE_FROM_LIST (&moo->finalizable, x);
|
MOO_DELETE_FROM_LIST (&moo->finalizable, x);
|
||||||
@ -1534,7 +1599,7 @@ static moo_oow_t move_finalizable_objects (moo_t* moo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x->oop = moo_moveoop(moo, x->oop);
|
x->oop = moo_updateoopforgc(moo, x->oop);
|
||||||
}
|
}
|
||||||
|
|
||||||
x = y;
|
x = y;
|
||||||
|
@ -55,7 +55,7 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size)
|
|||||||
if (MOO_UNLIKELY(!heap))
|
if (MOO_UNLIKELY(!heap))
|
||||||
{
|
{
|
||||||
const moo_ooch_t* oldmsg = moo_backuperrmsg(moo);
|
const moo_ooch_t* oldmsg = moo_backuperrmsg(moo);
|
||||||
moo_seterrbfmt (moo, moo_geterrnum(moo), "unable to allocate heap - %js", oldmsg);
|
moo_seterrbfmt (moo, moo_geterrnum(moo), "unable to allocate a heap - %js", oldmsg);
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1816,15 +1816,20 @@ struct moo_t
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
moo_gchdr_t* b; /* object blocks allocated */
|
moo_gchdr_t* b; /* object blocks allocated */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
moo_gchdr_t* curr;
|
||||||
|
moo_gchdr_t* prev;
|
||||||
|
} ls;
|
||||||
moo_oow_t bsz; /* total size of object blocks allocated */
|
moo_oow_t bsz; /* total size of object blocks allocated */
|
||||||
moo_oow_t threshold;
|
moo_oow_t threshold;
|
||||||
|
int lazy_sweep;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
moo_oop_t* ptr;
|
moo_oop_t* ptr;
|
||||||
moo_oow_t capa;
|
moo_oow_t capa;
|
||||||
moo_oow_t len;
|
moo_oow_t len;
|
||||||
|
|
||||||
moo_oow_t max;
|
moo_oow_t max;
|
||||||
} stack;
|
} stack;
|
||||||
} gci;
|
} gci;
|
||||||
@ -2219,15 +2224,16 @@ MOO_EXPORT void moo_deregevtcb (
|
|||||||
* It is not affected by #MOO_TRAIT_NOGC.
|
* It is not affected by #MOO_TRAIT_NOGC.
|
||||||
*/
|
*/
|
||||||
MOO_EXPORT void moo_gc (
|
MOO_EXPORT void moo_gc (
|
||||||
moo_t* moo
|
moo_t* moo,
|
||||||
|
int full
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The moo_moveoop() function moves an object and returns an updated pointer
|
* The moo_updateoopforgc() function moves an object and returns an updated pointer
|
||||||
* after having moved. it must be called in the GC callback context only.
|
* after having moved. It must be called in the GC callback context only.
|
||||||
*/
|
*/
|
||||||
MOO_EXPORT moo_oop_t moo_moveoop (
|
MOO_EXPORT moo_oop_t moo_updateoopforgc (
|
||||||
moo_t* moo,
|
moo_t* moo,
|
||||||
moo_oop_t oop
|
moo_oop_t oop
|
||||||
);
|
);
|
||||||
|
@ -30,7 +30,7 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size)
|
|||||||
{
|
{
|
||||||
#if defined(MOO_BUILD_DEBUG)
|
#if defined(MOO_BUILD_DEBUG)
|
||||||
/* DEBUG_GC is set but NOGC is not set */
|
/* 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);
|
if ((moo->option.trait & (MOO_TRAIT_DEBUG_GC | MOO_TRAIT_NOGC)) == MOO_TRAIT_DEBUG_GC) moo_gc (moo, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MOO_ENABLE_GC_MARK_SWEEP)
|
#if defined(MOO_ENABLE_GC_MARK_SWEEP)
|
||||||
@ -45,19 +45,37 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
moo_oow_t allocsize;
|
||||||
|
|
||||||
if (moo->gci.bsz >= moo->gci.threshold)
|
if (moo->gci.bsz >= moo->gci.threshold)
|
||||||
{
|
{
|
||||||
moo_gc (moo);
|
moo_gc (moo, 0);
|
||||||
moo->gci.threshold = moo->gci.bsz + 100000; /* TODO: change this fomula */
|
moo->gci.threshold = moo->gci.bsz + 100000; /* TODO: change this fomula */
|
||||||
}
|
}
|
||||||
|
|
||||||
gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, MOO_SIZEOF(*gch) + size);
|
allocsize = MOO_SIZEOF(*gch) + size;
|
||||||
|
if (moo->gci.lazy_sweep) moo_gc_ms_sweep_lazy (moo, allocsize);
|
||||||
|
|
||||||
|
gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, allocsize);
|
||||||
if (!gch && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC))
|
if (!gch && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC))
|
||||||
{
|
{
|
||||||
moo_gc (moo);
|
moo_gc (moo, 0);
|
||||||
MOO_LOG0 (moo, MOO_LOG_GC | MOO_LOG_INFO, "GC completed\n"); /* TODO: add more inforamtion */
|
if (moo->gci.lazy_sweep) moo_gc_ms_sweep_lazy (moo, allocsize);
|
||||||
gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, MOO_SIZEOF(*gch) + size);
|
|
||||||
if (MOO_UNLIKELY(!gch)) return MOO_NULL;
|
gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, allocsize);
|
||||||
|
if (MOO_UNLIKELY(!gch))
|
||||||
|
{
|
||||||
|
if (moo->gci.lazy_sweep)
|
||||||
|
{
|
||||||
|
moo_gc_ms_sweep_lazy (moo, MOO_TYPE_MAX(moo_oow_t)); /* sweep the rest */
|
||||||
|
gch = (moo_gchdr_t*)moo_callocheapmem(moo, moo->heap, allocsize);
|
||||||
|
if (MOO_UNLIKELY(!gch)) return MOO_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MOO_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +100,7 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size)
|
|||||||
ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size);
|
ptr = (moo_uint8_t*)moo_allocheapspace(moo, &moo->heap->curspace, size);
|
||||||
if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC))
|
if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_TRAIT_NOGC))
|
||||||
{
|
{
|
||||||
moo_gc (moo);
|
moo_gc (moo, 1);
|
||||||
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
||||||
"GC completed - current heap ptr %p limit %p size %zd free %zd\n",
|
"GC completed - current heap ptr %p limit %p size %zd free %zd\n",
|
||||||
moo->heap->curspace.ptr, moo->heap->curspace.limit,
|
moo->heap->curspace.ptr, moo->heap->curspace.limit,
|
||||||
|
@ -239,7 +239,7 @@ moo_pfrc_t moo_pf_system_find_next_process (moo_t* moo, moo_mod_t* mod, moo_ooi_
|
|||||||
|
|
||||||
moo_pfrc_t moo_pf_system_collect_garbage (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
moo_pfrc_t moo_pf_system_collect_garbage (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
moo_gc (moo);
|
moo_gc (moo, 1);
|
||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ static void gc_mod_sck (moo_t* moo, moo_mod_t* mod)
|
|||||||
MOO_ASSERT (moo, ctx != MOO_NULL);
|
MOO_ASSERT (moo, ctx != MOO_NULL);
|
||||||
if (ctx->sck_class)
|
if (ctx->sck_class)
|
||||||
{
|
{
|
||||||
ctx->sck_class = (moo_oop_class_t)moo_moveoop(moo, (moo_oop_t)ctx->sck_class);
|
ctx->sck_class = (moo_oop_class_t)moo_updateoopforgc(moo, (moo_oop_t)ctx->sck_class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +834,7 @@ static void gc_mod_x11 (moo_t* moo, moo_mod_t* mod)
|
|||||||
x11_modctx_t* ctx = mod->ctx;
|
x11_modctx_t* ctx = mod->ctx;
|
||||||
|
|
||||||
MOO_ASSERT (moo, ctx != MOO_NULL);
|
MOO_ASSERT (moo, ctx != MOO_NULL);
|
||||||
ctx->x11_class = (moo_oop_class_t)moo_moveoop(moo, (moo_oop_t)ctx->x11_class);
|
ctx->x11_class = (moo_oop_class_t)moo_updateoopforgc(moo, (moo_oop_t)ctx->x11_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
|
int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
|
||||||
|
Loading…
Reference in New Issue
Block a user