fixed serious memory management bugs
This commit is contained in:
parent
60c94ad5e6
commit
8477a5662f
|
@ -116,22 +116,109 @@ struct gc_unit
|
||||||
return;
|
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;i<block_num;++i)
|
||||||
|
ptr=ptr->next;
|
||||||
|
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
|
class gc_manager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// free_space list is used to store space that is not in use.
|
// free_space list is used to store space that is not in use.
|
||||||
std::list<int> free_space;
|
std::list<int> free_space;
|
||||||
std::vector<gc_unit> 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;
|
bool error_occurred;
|
||||||
public:
|
public:
|
||||||
void gc_init()
|
void gc_init()
|
||||||
{
|
{
|
||||||
// this function must be called in class nasal_runtime before running any codes
|
// this function must be called in class nasal_runtime before running any codes
|
||||||
std::vector<gc_unit> tmp_vec;
|
|
||||||
memory.clear();
|
memory.clear();
|
||||||
memory.swap(tmp_vec);
|
|
||||||
// clear the memory capacity by using tmp_vec.~vector<gc_unit>()
|
|
||||||
free_space.clear();
|
free_space.clear();
|
||||||
error_occurred=false;
|
error_occurred=false;
|
||||||
return;
|
return;
|
||||||
|
@ -144,8 +231,7 @@ class gc_manager
|
||||||
// by this way it can manage memory efficiently.
|
// by this way it can manage memory efficiently.
|
||||||
if(free_space.empty())
|
if(free_space.empty())
|
||||||
{
|
{
|
||||||
gc_unit new_unit;
|
memory.push_back();
|
||||||
memory.push_back(new_unit);
|
|
||||||
free_space.push_back(memory.size()-1);
|
free_space.push_back(memory.size()-1);
|
||||||
}
|
}
|
||||||
int alloc_plc=free_space.front();
|
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
|
// this function is often used when an identifier is calling a space in memory
|
||||||
return (0<=addr) && (addr<memory.size()) && (!memory[addr].collected);
|
return (0<=addr) && (addr<memory.size()) && (!memory[addr].collected);
|
||||||
}
|
}
|
||||||
void reference_add(const int addr)
|
bool reference_add(const int addr)
|
||||||
{
|
{
|
||||||
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
||||||
++memory[addr].refcnt;
|
++memory[addr].refcnt;
|
||||||
|
@ -180,11 +266,11 @@ class gc_manager
|
||||||
std::cout<<">> [Gc] fatal error: reference unexpected memory place ";
|
std::cout<<">> [Gc] fatal error: reference unexpected memory place ";
|
||||||
prt_hex(addr);
|
prt_hex(addr);
|
||||||
std::cout<<" ."<<std::endl;
|
std::cout<<" ."<<std::endl;
|
||||||
error_occurred=true;
|
return false;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
void reference_delete(const int addr)
|
bool reference_delete(const int addr)
|
||||||
{
|
{
|
||||||
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
if((0<=addr) && (addr<memory.size()) && (!memory[addr].collected))
|
||||||
{
|
{
|
||||||
|
@ -212,9 +298,9 @@ class gc_manager
|
||||||
std::cout<<">> [Gc] fatal error: delete unexpected memory address: ";
|
std::cout<<">> [Gc] fatal error: delete unexpected memory address: ";
|
||||||
prt_hex(addr);
|
prt_hex(addr);
|
||||||
std::cout<<" ."<<std::endl;
|
std::cout<<" ."<<std::endl;
|
||||||
error_occurred=true;
|
return false;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
void info_print()
|
void info_print()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#ifndef __NASAL_RUNTIME_H__
|
#ifndef __NASAL_RUNTIME_H__
|
||||||
#define __NASAL_RUNTIME_H__
|
#define __NASAL_RUNTIME_H__
|
||||||
#define nas_lib_func_num 31
|
#define nas_lib_func_num 32
|
||||||
std::string inline_func_name[nas_lib_func_num]=
|
std::string inline_func_name[nas_lib_func_num]=
|
||||||
{
|
{
|
||||||
|
"nasal_call_inline_scalar_type",
|
||||||
//base.nas
|
//base.nas
|
||||||
"nasal_call_inline_push_back",
|
"nasal_call_inline_push_back",
|
||||||
"nasal_call_inline_push_null",
|
"nasal_call_inline_push_null",
|
||||||
|
@ -3352,6 +3353,13 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
for(std::list<std::map<std::string,int> >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter)
|
||||||
if(iter->find(tmp_id_name)!=iter->end())
|
if(iter->find(tmp_id_name)!=iter->end())
|
||||||
addr=(*iter)[tmp_id_name];
|
addr=(*iter)[tmp_id_name];
|
||||||
|
if(addr>0 && !nasal_gc.get_reference(addr))
|
||||||
|
{
|
||||||
|
std::cout<<">> [Runtime] line "<<node.get_node_line()<<": \'"<<tmp_id_name<<"\' has 0 reference ,address: ";
|
||||||
|
prt_hex(addr);
|
||||||
|
std::cout<<std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(addr<0)
|
if(addr<0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -3958,6 +3966,7 @@ int nasal_runtime::call_identifier(std::list<std::map<std::string,int> >& local_
|
||||||
last_hash_addr);
|
last_hash_addr);
|
||||||
if(addr<0)
|
if(addr<0)
|
||||||
return -1;
|
return -1;
|
||||||
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
|
@ -4122,19 +4131,20 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
std::map<std::string,int> new_scope;
|
std::map<std::string,int> new_scope;
|
||||||
local_scope.push_back(new_scope);
|
local_scope.push_back(new_scope);
|
||||||
int loop_type=node.get_node_type();
|
int loop_type=node.get_node_type();
|
||||||
|
int state=__state_no_operation;
|
||||||
if(loop_type==__while)
|
if(loop_type==__while)
|
||||||
{
|
{
|
||||||
while(check_condition(local_scope,node.get_children().front()))
|
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)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
else if(state==__state_continue)
|
else if(state==__state_continue)
|
||||||
;
|
;
|
||||||
else if(state==__state_return)
|
else if(state==__state_return)
|
||||||
return __state_return;
|
break;
|
||||||
else if(state==__state_error)
|
else if(state==__state_error)
|
||||||
return __state_error;
|
break;
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -4171,15 +4181,15 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
int tmp_val=assignment(local_scope,assignment_ast,now_step_elem_addr);
|
int tmp_val=assignment(local_scope,assignment_ast,now_step_elem_addr);
|
||||||
if(tmp_val>=0)
|
if(tmp_val>=0)
|
||||||
nasal_gc.reference_delete(tmp_val);
|
nasal_gc.reference_delete(tmp_val);
|
||||||
int state=block_proc(local_scope,*iter);
|
state=block_proc(local_scope,*iter);
|
||||||
if(state==__state_break)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
else if(state==__state_continue)
|
else if(state==__state_continue)
|
||||||
;
|
;
|
||||||
else if(state==__state_return)
|
else if(state==__state_return)
|
||||||
return __state_return;
|
break;
|
||||||
else if(state==__state_error)
|
else if(state==__state_error)
|
||||||
return __state_error;
|
break;
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -4222,15 +4232,15 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
if(tmp_val>=0)
|
if(tmp_val>=0)
|
||||||
nasal_gc.reference_delete(tmp_val);
|
nasal_gc.reference_delete(tmp_val);
|
||||||
nasal_gc.reference_delete(tmp_addr);
|
nasal_gc.reference_delete(tmp_addr);
|
||||||
int state=block_proc(local_scope,*iter);
|
state=block_proc(local_scope,*iter);
|
||||||
if(state==__state_break)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
else if(state==__state_continue)
|
else if(state==__state_continue)
|
||||||
;
|
;
|
||||||
else if(state==__state_return)
|
else if(state==__state_return)
|
||||||
return __state_return;
|
break;
|
||||||
else if(state==__state_error)
|
else if(state==__state_error)
|
||||||
return __state_error;
|
break;
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -4250,16 +4260,15 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
// run block
|
// run block
|
||||||
while(check_condition(local_scope,*condition_iterator))
|
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)
|
if(state==__state_break)
|
||||||
break;
|
break;
|
||||||
else if(state==__state_continue)
|
else if(state==__state_continue)
|
||||||
;
|
;
|
||||||
else if(state==__state_return)
|
else if(state==__state_return)
|
||||||
return __state_return;
|
break;
|
||||||
else if(state==__state_error)
|
else if(state==__state_error)
|
||||||
return __state_error;
|
break;
|
||||||
else if(state==__state_no_operation)
|
else if(state==__state_no_operation)
|
||||||
;
|
;
|
||||||
// step update here
|
// step update here
|
||||||
|
@ -4267,7 +4276,10 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
{
|
{
|
||||||
int assign_addr=calculation(local_scope,*step_iterator);
|
int assign_addr=calculation(local_scope,*step_iterator);
|
||||||
if(assign_addr<0)
|
if(assign_addr<0)
|
||||||
return __state_error;
|
{
|
||||||
|
state=__state_error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
nasal_gc.reference_delete(assign_addr);
|
nasal_gc.reference_delete(assign_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4275,7 +4287,7 @@ int nasal_runtime::loop_expr(std::list<std::map<std::string,int> >& local_scope,
|
||||||
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
for(std::map<std::string,int>::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i)
|
||||||
nasal_gc.reference_delete(i->second);
|
nasal_gc.reference_delete(i->second);
|
||||||
local_scope.pop_back();
|
local_scope.pop_back();
|
||||||
return __state_no_operation;
|
return state;
|
||||||
}
|
}
|
||||||
int nasal_runtime::conditional(std::list<std::map<std::string,int> >& local_scope,abstract_syntax_tree& node)
|
int nasal_runtime::conditional(std::list<std::map<std::string,int> >& 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
|
// 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)
|
if(called_hash_addr>=0)
|
||||||
|
{
|
||||||
new_scope["me"]=called_hash_addr;
|
new_scope["me"]=called_hash_addr;
|
||||||
|
nasal_gc.reference_add(called_hash_addr);
|
||||||
|
}
|
||||||
// loading parameters
|
// loading parameters
|
||||||
std::vector<std::string> para_name_list;
|
std::vector<std::string> para_name_list;
|
||||||
int dynamic_args=-1;
|
int dynamic_args=-1;
|
||||||
|
@ -4668,6 +4683,18 @@ int nasal_runtime::inline_function(std::list<std::map<std::string,int> >& local_
|
||||||
case scalar_function:std::cout<<"func(...){...}";break;
|
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<std::map<std::string,int> >::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<<std::endl;
|
std::cout<<std::endl;
|
||||||
ret_addr=nasal_gc.gc_alloc();
|
ret_addr=nasal_gc.gc_alloc();
|
||||||
nasal_gc.get_scalar(ret_addr).set_type(scalar_nil);
|
nasal_gc.get_scalar(ret_addr).set_type(scalar_nil);
|
||||||
|
|
Loading…
Reference in New Issue