From 7298884d09ffaf85db23fba1542e41775fc6feaf Mon Sep 17 00:00:00 2001 From: paladin-t Date: Mon, 28 Dec 2015 15:59:10 +0800 Subject: [PATCH] *fixed a gc bug. --- HISTORY | 1 + core/my_basic.c | 46 ++++++++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/HISTORY b/HISTORY index c83d00a..516a07a 100755 --- a/HISTORY +++ b/HISTORY @@ -1,4 +1,5 @@ Dec. 28 2015 +Fixed a GC bug Improved threshold algorithm for the memory pool Polished code diff --git a/core/my_basic.c b/core/my_basic.c index 8242f2d..1fd2dba 100755 --- a/core/my_basic.c +++ b/core/my_basic.c @@ -1208,8 +1208,9 @@ static int _gc_destroy_garbage_in_dict(void* data, void* extra, void* gc); static int _gc_destroy_garbage_in_class(void* data, void* extra, void* gc); #endif /* MB_ENABLE_CLASS */ static int _gc_destroy_garbage(void* data, void* extra); +static void _gc_swap_tables(mb_interpreter_t* s); static void _gc_try_trigger(mb_interpreter_t* s); -static void _gc_collect_garbage(mb_interpreter_t* s); +static void _gc_collect_garbage(mb_interpreter_t* s, bool_t all); #endif /* MB_ENABLE_GC */ static _usertype_ref_t* _create_usertype_ref(mb_interpreter_t* s, void* val, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft); @@ -4313,9 +4314,6 @@ void _gc_add(_ref_t* ref, void* data, _gc_t* gc) { if(!ref->s->gc.table) return; - if(ref->s->gc.collecting > 1) - return; - if(ref->s->gc.collecting) table = ref->s->gc.recursive_table; else @@ -4558,15 +4556,26 @@ int _gc_destroy_garbage(void* data, void* extra) { return result; } +void _gc_swap_tables(mb_interpreter_t* s) { + /* Swap garbage tables */ + _ht_node_t* tmp = 0; + + mb_assert(s); + + tmp = s->gc.table; + s->gc.table = s->gc.recursive_table; + s->gc.recursive_table = tmp; +} + void _gc_try_trigger(mb_interpreter_t* s) { /* Try trigger garbage collection */ mb_assert(s); if(s->gc.table->count >= MB_GC_GARBAGE_THRESHOLD) - _gc_collect_garbage(s); + _gc_collect_garbage(s, false); } -void _gc_collect_garbage(mb_interpreter_t* s) { +void _gc_collect_garbage(mb_interpreter_t* s, bool_t all) { /* Collect all garbage */ _ht_node_t* valid = 0; @@ -4581,19 +4590,24 @@ void _gc_collect_garbage(mb_interpreter_t* s) { /* Get unreachable information */ _HT_FOREACH(valid, _do_nothing_on_object, _ht_remove_exist, s->gc.table); /* Collect garbage */ - _ht_foreach(s->gc.table, _gc_destroy_garbage); - _ht_clear(s->gc.table); - if(s->gc.recursive_table->count) { + do { + _ht_foreach(s->gc.table, _gc_destroy_garbage); + _ht_clear(s->gc.table); + if(s->gc.collecting > 1) + s->gc.collecting--; + + if(!all || !s->gc.recursive_table->count) + break; + + _gc_swap_tables(s); s->gc.collecting++; - _ht_foreach(s->gc.recursive_table, _gc_destroy_garbage); - _ht_clear(s->gc.recursive_table); - s->gc.collecting--; - } + } while(true); /* Tidy */ _ht_clear(s->gc.collected_table); _ht_clear(valid); _ht_destroy(valid); s->gc.collecting--; + mb_assert(!s->gc.collecting); } #endif /* MB_ENABLE_GC */ @@ -7789,15 +7803,11 @@ int mb_close(struct mb_interpreter_t** s) { _ls_destroy((*s)->sub_stack); -#ifdef MB_ENABLE_GC - _gc_collect_garbage(*s); -#endif /* MB_ENABLE_GC */ - _tidy_scope_chain(*s); _dispose_scope_chain(*s); #ifdef MB_ENABLE_GC - _gc_collect_garbage(*s); + _gc_collect_garbage(*s, true); _ht_destroy((*s)->gc.table); _ht_destroy((*s)->gc.recursive_table); _ht_destroy((*s)->gc.collected_table);