working on lazy sweeping

This commit is contained in:
hyunghwan.chung 2020-11-27 05:13:02 +00:00
parent 1aa67bbc00
commit ebcb6215fb
10 changed files with 201 additions and 111 deletions

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }

View File

@ -276,7 +276,7 @@ void moo_fini (moo_t* moo)
} }
while (moo->gci.b); while (moo->gci.b);
MOO_ASSERT (moo, moo->gci.bsz == 0); MOO_ASSERT (moo, moo->gci.bsz == 0);
} }
if (moo->gci.stack.ptr) if (moo->gci.stack.ptr)

View File

@ -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
); );

View File

@ -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,

View File

@ -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;
} }

View File

@ -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);
} }
} }

View File

@ -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)