*fixed a gc bug.
This commit is contained in:
parent
acfe0446ee
commit
7298884d09
1
HISTORY
1
HISTORY
@ -1,4 +1,5 @@
|
|||||||
Dec. 28 2015
|
Dec. 28 2015
|
||||||
|
Fixed a GC bug
|
||||||
Improved threshold algorithm for the memory pool
|
Improved threshold algorithm for the memory pool
|
||||||
Polished code
|
Polished code
|
||||||
|
|
||||||
|
@ -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);
|
static int _gc_destroy_garbage_in_class(void* data, void* extra, void* gc);
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
static int _gc_destroy_garbage(void* data, void* extra);
|
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_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 */
|
#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);
|
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)
|
if(!ref->s->gc.table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ref->s->gc.collecting > 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(ref->s->gc.collecting)
|
if(ref->s->gc.collecting)
|
||||||
table = ref->s->gc.recursive_table;
|
table = ref->s->gc.recursive_table;
|
||||||
else
|
else
|
||||||
@ -4558,15 +4556,26 @@ int _gc_destroy_garbage(void* data, void* extra) {
|
|||||||
return result;
|
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) {
|
void _gc_try_trigger(mb_interpreter_t* s) {
|
||||||
/* Try trigger garbage collection */
|
/* Try trigger garbage collection */
|
||||||
mb_assert(s);
|
mb_assert(s);
|
||||||
|
|
||||||
if(s->gc.table->count >= MB_GC_GARBAGE_THRESHOLD)
|
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 */
|
/* Collect all garbage */
|
||||||
_ht_node_t* valid = 0;
|
_ht_node_t* valid = 0;
|
||||||
|
|
||||||
@ -4581,19 +4590,24 @@ void _gc_collect_garbage(mb_interpreter_t* s) {
|
|||||||
/* Get unreachable information */
|
/* Get unreachable information */
|
||||||
_HT_FOREACH(valid, _do_nothing_on_object, _ht_remove_exist, s->gc.table);
|
_HT_FOREACH(valid, _do_nothing_on_object, _ht_remove_exist, s->gc.table);
|
||||||
/* Collect garbage */
|
/* Collect garbage */
|
||||||
_ht_foreach(s->gc.table, _gc_destroy_garbage);
|
do {
|
||||||
_ht_clear(s->gc.table);
|
_ht_foreach(s->gc.table, _gc_destroy_garbage);
|
||||||
if(s->gc.recursive_table->count) {
|
_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++;
|
s->gc.collecting++;
|
||||||
_ht_foreach(s->gc.recursive_table, _gc_destroy_garbage);
|
} while(true);
|
||||||
_ht_clear(s->gc.recursive_table);
|
|
||||||
s->gc.collecting--;
|
|
||||||
}
|
|
||||||
/* Tidy */
|
/* Tidy */
|
||||||
_ht_clear(s->gc.collected_table);
|
_ht_clear(s->gc.collected_table);
|
||||||
_ht_clear(valid);
|
_ht_clear(valid);
|
||||||
_ht_destroy(valid);
|
_ht_destroy(valid);
|
||||||
s->gc.collecting--;
|
s->gc.collecting--;
|
||||||
|
mb_assert(!s->gc.collecting);
|
||||||
}
|
}
|
||||||
#endif /* MB_ENABLE_GC */
|
#endif /* MB_ENABLE_GC */
|
||||||
|
|
||||||
@ -7789,15 +7803,11 @@ int mb_close(struct mb_interpreter_t** s) {
|
|||||||
|
|
||||||
_ls_destroy((*s)->sub_stack);
|
_ls_destroy((*s)->sub_stack);
|
||||||
|
|
||||||
#ifdef MB_ENABLE_GC
|
|
||||||
_gc_collect_garbage(*s);
|
|
||||||
#endif /* MB_ENABLE_GC */
|
|
||||||
|
|
||||||
_tidy_scope_chain(*s);
|
_tidy_scope_chain(*s);
|
||||||
_dispose_scope_chain(*s);
|
_dispose_scope_chain(*s);
|
||||||
|
|
||||||
#ifdef MB_ENABLE_GC
|
#ifdef MB_ENABLE_GC
|
||||||
_gc_collect_garbage(*s);
|
_gc_collect_garbage(*s, true);
|
||||||
_ht_destroy((*s)->gc.table);
|
_ht_destroy((*s)->gc.table);
|
||||||
_ht_destroy((*s)->gc.recursive_table);
|
_ht_destroy((*s)->gc.recursive_table);
|
||||||
_ht_destroy((*s)->gc.collected_table);
|
_ht_destroy((*s)->gc.collected_table);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user