From 8477a5662f97f0e6216c6894605ce810549a16e3 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Sat, 4 Apr 2020 19:03:09 +0800 Subject: [PATCH] fixed serious memory management bugs --- version2.0/nasal_gc.h | 110 +++++++++++++++++++++++++++++++++---- version2.0/nasal_runtime.h | 59 ++++++++++++++------ 2 files changed, 141 insertions(+), 28 deletions(-) diff --git a/version2.0/nasal_gc.h b/version2.0/nasal_gc.h index 699334c..0bc8529 100644 --- a/version2.0/nasal_gc.h +++ b/version2.0/nasal_gc.h @@ -116,22 +116,109 @@ struct gc_unit return; } }; +#ifndef NAS_POOL_SIZE +#define NAS_POOL_SIZE 128 +struct memory_block +{ + gc_unit space[NAS_POOL_SIZE]; + memory_block* next; +}; + +class memory_block_list +{ + private: + memory_block* head; + int mem_size; + int blk_size; + public: + memory_block_list() + { + mem_size=0; + blk_size=1; + head=new memory_block; + head->next=NULL; + return; + } + ~memory_block_list() + { + mem_size=0; + blk_size=0; + memory_block* ptr=head; + while(ptr) + { + memory_block* tmp_ptr=ptr; + ptr=ptr->next; + delete tmp_ptr; + } + return; + } + void clear() + { + memory_block* ptr=head; + while(ptr) + { + memory_block* tmp_ptr=ptr; + ptr=ptr->next; + delete tmp_ptr; + } + mem_size=0; + blk_size=1; + head=new memory_block; + head->next=NULL; + return; + } + gc_unit& operator[](int address) + { + int block_num=address/NAS_POOL_SIZE; + int block_plc=address%NAS_POOL_SIZE; + memory_block* ptr=head; + for(int i=0;inext; + return ptr->space[block_plc]; + } + void push_back() + { + ++mem_size; + if(mem_size>blk_size*NAS_POOL_SIZE) + { + memory_block* ptr=head; + while(ptr->next) + ptr=ptr->next; + ptr->next=new memory_block; + ptr->next->next=NULL; + ++blk_size; + } + return; + } + int size() + { + return mem_size; + } + int capacity() + { + return NAS_POOL_SIZE*blk_size; + } +}; +#endif class gc_manager { private: // free_space list is used to store space that is not in use. std::list free_space; - std::vector memory; + /* + cannot use std::vector to simulate memory + because if vector memory is not enough,vector will use another larger memory as it's main memory + then all the things will be moved to a new space, + at this time if you reference a member in it,this will cause segmentation error. + */ + memory_block_list memory; bool error_occurred; public: void gc_init() { // this function must be called in class nasal_runtime before running any codes - std::vector tmp_vec; memory.clear(); - memory.swap(tmp_vec); - // clear the memory capacity by using tmp_vec.~vector() free_space.clear(); error_occurred=false; return; @@ -144,8 +231,7 @@ class gc_manager // by this way it can manage memory efficiently. if(free_space.empty()) { - gc_unit new_unit; - memory.push_back(new_unit); + memory.push_back(); free_space.push_back(memory.size()-1); } int alloc_plc=free_space.front(); @@ -171,7 +257,7 @@ class gc_manager // this function is often used when an identifier is calling a space in memory return (0<=addr) && (addr> [Gc] fatal error: reference unexpected memory place "; prt_hex(addr); std::cout<<" ."<> [Gc] fatal error: delete unexpected memory address: "; prt_hex(addr); std::cout<<" ."< >& local_ for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) if(iter->find(tmp_id_name)!=iter->end()) addr=(*iter)[tmp_id_name]; + if(addr>0 && !nasal_gc.get_reference(addr)) + { + std::cout<<">> [Runtime] line "< >& local_ last_hash_addr); if(addr<0) return -1; + nasal_gc.reference_delete(tmp_addr); } } return addr; @@ -4122,19 +4131,20 @@ int nasal_runtime::loop_expr(std::list >& local_scope, std::map new_scope; local_scope.push_back(new_scope); int loop_type=node.get_node_type(); + int state=__state_no_operation; if(loop_type==__while) { while(check_condition(local_scope,node.get_children().front())) { - int state=block_proc(local_scope,node.get_children().back()); + state=block_proc(local_scope,node.get_children().back()); if(state==__state_break) break; else if(state==__state_continue) ; else if(state==__state_return) - return __state_return; + break; else if(state==__state_error) - return __state_error; + break; else if(state==__state_no_operation) ; } @@ -4171,15 +4181,15 @@ int nasal_runtime::loop_expr(std::list >& local_scope, int tmp_val=assignment(local_scope,assignment_ast,now_step_elem_addr); if(tmp_val>=0) nasal_gc.reference_delete(tmp_val); - int state=block_proc(local_scope,*iter); + state=block_proc(local_scope,*iter); if(state==__state_break) break; else if(state==__state_continue) ; else if(state==__state_return) - return __state_return; + break; else if(state==__state_error) - return __state_error; + break; else if(state==__state_no_operation) ; } @@ -4222,15 +4232,15 @@ int nasal_runtime::loop_expr(std::list >& local_scope, if(tmp_val>=0) nasal_gc.reference_delete(tmp_val); nasal_gc.reference_delete(tmp_addr); - int state=block_proc(local_scope,*iter); + state=block_proc(local_scope,*iter); if(state==__state_break) break; else if(state==__state_continue) ; else if(state==__state_return) - return __state_return; + break; else if(state==__state_error) - return __state_error; + break; else if(state==__state_no_operation) ; } @@ -4250,16 +4260,15 @@ int nasal_runtime::loop_expr(std::list >& local_scope, // run block while(check_condition(local_scope,*condition_iterator)) { - int state=block_proc(local_scope,*block_proc_iterator); - + state=block_proc(local_scope,*block_proc_iterator); if(state==__state_break) break; else if(state==__state_continue) ; else if(state==__state_return) - return __state_return; + break; else if(state==__state_error) - return __state_error; + break; else if(state==__state_no_operation) ; // step update here @@ -4267,7 +4276,10 @@ int nasal_runtime::loop_expr(std::list >& local_scope, { int assign_addr=calculation(local_scope,*step_iterator); if(assign_addr<0) - return __state_error; + { + state=__state_error; + break; + } nasal_gc.reference_delete(assign_addr); } } @@ -4275,7 +4287,7 @@ int nasal_runtime::loop_expr(std::list >& local_scope, for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) nasal_gc.reference_delete(i->second); local_scope.pop_back(); - return __state_no_operation; + return state; } int nasal_runtime::conditional(std::list >& local_scope,abstract_syntax_tree& node) { @@ -4412,7 +4424,10 @@ int nasal_runtime::func_proc( // there may be an error if an identifier has the same name as one identifier in the local_scope before if(called_hash_addr>=0) + { new_scope["me"]=called_hash_addr; + nasal_gc.reference_add(called_hash_addr); + } // loading parameters std::vector para_name_list; int dynamic_args=-1; @@ -4668,6 +4683,18 @@ int nasal_runtime::inline_function(std::list >& local_ case scalar_function:std::cout<<"func(...){...}";break; } } + ret_addr=nasal_gc.gc_alloc(); + nasal_gc.get_scalar(ret_addr).set_type(scalar_nil); + } + else if(func_name=="nasal_call_inline_scalar_type") + { + int data=-1; + for(std::list >::iterator i=local_scope.begin();i!=local_scope.end();++i) + if(i->find("thing")!=i->end()) + data=(*i)["thing"]; + if(data<0) + return -1; + print_scalar_type(nasal_gc.get_scalar(data).get_type()); std::cout<