*fixed a memory leak with gc caused by meta class.

This commit is contained in:
paladin-t 2015-12-29 21:04:39 +08:00
parent a99a011c9a
commit 6d789b4f3d
2 changed files with 31 additions and 41 deletions

View File

@ -1,5 +1,6 @@
Dec. 29 2015 Dec. 29 2015
Fixed a multiple disposing bug with expression calculation Fixed a multiple disposing bug with expression calculation
Fixed a memory leak with GC caused by meta class
Improved GC with array and string Improved GC with array and string
Improved string duplication Improved string duplication
Improved array handling Improved array handling

View File

@ -1168,6 +1168,14 @@ static char* _extract_string(_object_t* obj);
# define _UNREF_CLASS(__o) ((void)(__o)); # define _UNREF_CLASS(__o) ((void)(__o));
# define _ADDGC_CLASS(__o, __g) ((void)(__o)); ((void)(__g)); # define _ADDGC_CLASS(__o, __g) ((void)(__o)); ((void)(__g));
#endif /* MB_ENABLE_CLASS */ #endif /* MB_ENABLE_CLASS */
#define _ADDGC_STRING(__o) \
case _DT_STRING: \
_dispose_object(__o); \
break;
#define _ADDGC_ROUTINE(__o) \
case _DT_ROUTINE: \
_dispose_object(__o); \
break;
#define _REF(__o) \ #define _REF(__o) \
switch((__o)->type) { \ switch((__o)->type) { \
_REF_USERTYPE_REF(__o) \ _REF_USERTYPE_REF(__o) \
@ -1190,6 +1198,8 @@ static char* _extract_string(_object_t* obj);
_ADDGC_ARRAY(__o, __g) \ _ADDGC_ARRAY(__o, __g) \
_ADDGC_COLL(__o, __g) \ _ADDGC_COLL(__o, __g) \
_ADDGC_CLASS(__o, __g) \ _ADDGC_CLASS(__o, __g) \
_ADDGC_STRING(__o) \
_ADDGC_ROUTINE(__o) \
default: break; \ default: break; \
} }
@ -1275,7 +1285,7 @@ static void _init_class(mb_interpreter_t* s, _class_t* instance, char* n);
static void _begin_class(mb_interpreter_t* s); static void _begin_class(mb_interpreter_t* s);
static bool_t _end_class(mb_interpreter_t* s); static bool_t _end_class(mb_interpreter_t* s);
static void _unref_class(_ref_t* ref, void* data); static void _unref_class(_ref_t* ref, void* data);
static void _destroy_class(_class_t* c, bool_t is_ref); static void _destroy_class(_class_t* c);
static bool_t _traverse_class(_class_t* c, _class_scope_walker scope_walker, _class_meta_walker meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret); static bool_t _traverse_class(_class_t* c, _class_scope_walker scope_walker, _class_meta_walker meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret);
static bool_t _link_meta_class(mb_interpreter_t* s, _class_t* derived, _class_t* base); static bool_t _link_meta_class(mb_interpreter_t* s, _class_t* derived, _class_t* base);
static void _unlink_meta_class(mb_interpreter_t* s, _class_t* derived); static void _unlink_meta_class(mb_interpreter_t* s, _class_t* derived);
@ -4448,13 +4458,9 @@ int _gc_destroy_garbage_in_list(void* data, void* extra, void* gc) {
mb_assert(data); mb_assert(data);
if(_is_string(data)) {
_destroy_object(data, extra);
} else {
obj = (_object_t*)data; obj = (_object_t*)data;
_ADDGC(obj, _gc); _ADDGC(obj, _gc);
safe_free(obj); safe_free(obj);
}
result = _OP_RESULT_DEL_NODE; result = _OP_RESULT_DEL_NODE;
@ -4469,21 +4475,13 @@ int _gc_destroy_garbage_in_dict(void* data, void* extra, void* gc) {
mb_assert(data); mb_assert(data);
if(_is_string(data)) {
_destroy_object(data, extra);
} else {
obj = (_object_t*)data; obj = (_object_t*)data;
_ADDGC(obj, _gc); _ADDGC(obj, _gc);
safe_free(obj); safe_free(obj);
}
if(_is_string(extra)) {
_destroy_object(extra, 0);
} else {
obj = (_object_t*)extra; obj = (_object_t*)extra;
_ADDGC(obj, _gc); _ADDGC(obj, _gc);
safe_free(obj); safe_free(obj);
}
result = _OP_RESULT_DEL_NODE; result = _OP_RESULT_DEL_NODE;
@ -4505,13 +4503,9 @@ int _gc_destroy_garbage_in_class(void* data, void* extra, void* gc) {
_gc_destroy_garbage_in_class(obj->data.variable->data, 0, gc); _gc_destroy_garbage_in_class(obj->data.variable->data, 0, gc);
safe_free(obj->data.variable->name); safe_free(obj->data.variable->name);
safe_free(obj->data.variable); safe_free(obj->data.variable);
} else if(_is_string(data)) {
_destroy_object(data, extra);
} else { } else {
if(gc) {
_ADDGC(obj, _gc); _ADDGC(obj, _gc);
} }
}
safe_free(obj); safe_free(obj);
result = _OP_RESULT_DEL_NODE; result = _OP_RESULT_DEL_NODE;
@ -5577,19 +5571,15 @@ bool_t _end_class(mb_interpreter_t* s) {
void _unref_class(_ref_t* ref, void* data) { void _unref_class(_ref_t* ref, void* data) {
/* Unreference a class instance */ /* Unreference a class instance */
if(!(*(ref->count))) if(!(*(ref->count)))
_destroy_class((_class_t*)data, false); _destroy_class((_class_t*)data);
} }
void _destroy_class(_class_t* c, bool_t is_ref) { void _destroy_class(_class_t* c) {
/* Destroy a class instance */ /* Destroy a class instance */
if(*c->ref.count)
return;
if(c->meta_list) { if(c->meta_list) {
_unlink_meta_class(c->ref.s, c); _unlink_meta_class(c->ref.s, c);
_ls_destroy(c->meta_list); _ls_destroy(c->meta_list);
} }
if(!is_ref) {
if(c->scope->var_dict) { if(c->scope->var_dict) {
_ht_foreach(c->scope->var_dict, _destroy_object); _ht_foreach(c->scope->var_dict, _destroy_object);
_ht_destroy(c->scope->var_dict); _ht_destroy(c->scope->var_dict);
@ -5599,7 +5589,6 @@ void _destroy_class(_class_t* c, bool_t is_ref) {
safe_free(c->name); safe_free(c->name);
safe_free(c); safe_free(c);
} }
}
bool_t _traverse_class(_class_t* c, _class_scope_walker scope_walker, _class_meta_walker meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret) { bool_t _traverse_class(_class_t* c, _class_scope_walker scope_walker, _class_meta_walker meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret) {
/* Traverse all fields of a class instance, and its meta class instances recursively as well */ /* Traverse all fields of a class instance, and its meta class instances recursively as well */