diff --git a/func.c b/func.c index 5b15228e..3c922043 100644 --- a/func.c +++ b/func.c @@ -49,35 +49,44 @@ void luaI_freefunc (TFunc *f) luaI_free (f); } + +void luaI_funcfree (TFunc *l) +{ + while (l) { + TFunc *next = l->next; + luaI_freefunc(l); + l = next; + } +} + /* ** Garbage collection function. -** This function traverse the function list freeing unindexed functions */ -Long luaI_funccollector (void) +TFunc *luaI_funccollector (long *acum) { TFunc *curr = function_root; TFunc *prev = NULL; - Long counter = 0; - while (curr) - { + TFunc *frees = NULL; + long counter = 0; + while (curr) { TFunc *next = curr->next; - if (!curr->marked) - { + if (!curr->marked) { if (prev == NULL) function_root = next; else prev->next = next; - luaI_freefunc (curr); + curr->next = frees; + frees = curr; ++counter; } - else - { + else { curr->marked = 0; prev = curr; } curr = next; } - return counter; + *acum += counter; + return frees; } diff --git a/func.h b/func.h index 74e954c7..97185b9e 100644 --- a/func.h +++ b/func.h @@ -1,5 +1,5 @@ /* -** $Id: func.h,v 1.7 1996/03/08 12:04:04 roberto Exp roberto $ +** $Id: func.h,v 1.8 1996/03/14 15:54:20 roberto Exp roberto $ */ #ifndef func_h @@ -30,7 +30,8 @@ typedef struct TFunc LocVar *locvars; } TFunc; -Long luaI_funccollector (void); +TFunc *luaI_funccollector (long *cont); +void luaI_funcfree (TFunc *l); void luaI_insertfunction (TFunc *f); void luaI_initTFunc (TFunc *f); diff --git a/hash.c b/hash.c index 9c543955..5ff64c84 100644 --- a/hash.c +++ b/hash.c @@ -3,7 +3,7 @@ ** hash manager for lua */ -char *rcs_hash="$Id: hash.c,v 2.41 1997/04/06 14:08:08 roberto Exp roberto $"; +char *rcs_hash="$Id: hash.c,v 2.42 1997/05/08 20:43:30 roberto Exp roberto $"; #include "luamem.h" @@ -167,46 +167,50 @@ void lua_hashmark (Hash *h) } -void luaI_hashcallIM (void) +void luaI_hashcallIM (Hash *l) { - Hash *curr_array; TObject t; ttype(&t) = LUA_T_ARRAY; - for (curr_array = listhead; curr_array; curr_array = curr_array->next) - if (markarray(curr_array) != 1) - { - avalue(&t) = curr_array; - luaI_gcIM(&t); - } + for (; l; l=l->next) { + avalue(&t) = l; + luaI_gcIM(&t); + } +} + + +void luaI_hashfree (Hash *frees) +{ + while (frees) { + Hash *next = frees->next; + hashdelete(frees); + frees = next; + } } -/* -** Garbage collection to arrays -** Delete all unmarked arrays. -*/ -Long lua_hashcollector (void) +Hash *luaI_hashcollector (long *acum) { - Hash *curr_array = listhead, *prev = NULL; - Long counter = 0; - while (curr_array != NULL) - { - Hash *next = curr_array->next; - if (markarray(curr_array) != 1) - { - if (prev == NULL) listhead = next; - else prev->next = next; - hashdelete(curr_array); - ++counter; + Hash *curr_array = listhead, *prev = NULL, *frees = NULL; + long counter = 0; + while (curr_array != NULL) { + Hash *next = curr_array->next; + if (markarray(curr_array) != 1) { + if (prev == NULL) + listhead = next; + else + prev->next = next; + curr_array->next = frees; + frees = curr_array; + ++counter; + } + else { + markarray(curr_array) = 0; + prev = curr_array; + } + curr_array = next; } - else - { - markarray(curr_array) = 0; - prev = curr_array; - } - curr_array = next; - } - return counter; + *acum += counter; + return frees; } diff --git a/hash.h b/hash.h index a91e1e15..4fbde55c 100644 --- a/hash.h +++ b/hash.h @@ -1,7 +1,7 @@ /* ** hash.h ** hash manager for lua -** $Id: hash.h,v 2.14 1997/03/19 19:41:10 roberto Exp roberto $ +** $Id: hash.h,v 2.15 1997/03/31 14:02:58 roberto Exp roberto $ */ #ifndef hash_h @@ -29,8 +29,9 @@ int lua_equalObj (TObject *t1, TObject *t2); int luaI_redimension (int nhash); Hash *lua_createarray (int nhash); void lua_hashmark (Hash *h); -Long lua_hashcollector (void); -void luaI_hashcallIM (void); +Hash *luaI_hashcollector (long *count); +void luaI_hashcallIM (Hash *l); +void luaI_hashfree (Hash *frees); TObject *lua_hashget (Hash *t, TObject *ref); TObject *lua_hashdefine (Hash *t, TObject *ref); void lua_next (void); diff --git a/table.c b/table.c index 1d6afbfc..86266a96 100644 --- a/table.c +++ b/table.c @@ -3,10 +3,11 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.67 1997/04/06 14:08:08 roberto Exp roberto $"; +char *rcs_table="$Id: table.c,v 2.68 1997/04/07 14:48:53 roberto Exp roberto $"; #include "luamem.h" #include "auxlib.h" +#include "func.h" #include "opcode.h" #include "tree.h" #include "hash.h" @@ -176,32 +177,43 @@ static void call_nilIM (void) ** Garbage collection. ** Delete all unused strings and arrays. */ -Long luaI_collectgarbage (void) +static long gc_block = GARBAGE_BLOCK; +static long gc_nentity = 0; /* total of strings, arrays, etc */ + +static void markall (void) { - Long recovered = 0; lua_travstack(lua_markobject); /* mark stack objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */ luaI_travlock(lua_markobject); /* mark locked objects */ luaI_travfallbacks(lua_markobject); /* mark fallbacks */ - luaI_hashcallIM(); - luaI_strcallIM(); +} + + +static void lua_collectgarbage (void) +{ + long recovered = 0; + Hash *freetable; + TaggedString *freestr; + TFunc *freefunc; + markall(); + freetable = luaI_hashcollector(&recovered); + freestr = luaI_strcollector(&recovered); + freefunc = luaI_funccollector(&recovered); + gc_block = 2*(gc_block-recovered); + gc_nentity -= recovered; + luaI_hashcallIM(freetable); + luaI_strcallIM(freestr); call_nilIM(); - luaI_invalidaterefs(); - recovered += lua_strcollector(); - recovered += lua_hashcollector(); - recovered += luaI_funccollector(); - return recovered; + luaI_hashfree(freetable); + luaI_strfree(freestr); + luaI_funcfree(freefunc); } + void lua_pack (void) { - static unsigned long block = GARBAGE_BLOCK; - static unsigned long nentity = 0; /* total of strings, arrays, etc */ - unsigned long recovered = 0; - if (nentity++ < block) return; - recovered = luaI_collectgarbage(); - block = 2*(block-recovered); - nentity -= recovered; + if (gc_nentity++ >= gc_block) + lua_collectgarbage(); } diff --git a/tree.c b/tree.c index 0141a99c..ea2b2dec 100644 --- a/tree.c +++ b/tree.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_tree="$Id: tree.c,v 1.24 1997/03/31 14:17:09 roberto Exp roberto $"; +char *rcs_tree="$Id: tree.c,v 1.25 1997/05/05 20:21:23 roberto Exp roberto $"; #include @@ -29,7 +29,8 @@ static int initialized = 0; static stringtable string_root[NUM_HASHS]; -static TaggedString EMPTY = {LUA_T_STRING, 0, NOT_USED, NOT_USED, 0, 2, {0}}; +static TaggedString EMPTY = {LUA_T_STRING, NULL, 0, NOT_USED, NOT_USED, + 0, 2, {0}}; static unsigned long hash (char *buff, long size) @@ -134,32 +135,34 @@ TaggedString *lua_createstring (char *str) } -void luaI_strcallIM (void) +void luaI_strcallIM (TaggedString *l) { - int i; TObject o; ttype(&o) = LUA_T_USERDATA; - for (i=0; isize; j++) { - TaggedString *t = tb->hash[j]; - if (t != NULL && t->tag != LUA_T_STRING && t->marked == 0) { - tsvalue(&o) = t; - luaI_gcIM(&o); - } - } + for (; l; l=l->next) { + tsvalue(&o) = l; + luaI_gcIM(&o); + } +} + + +void luaI_strfree (TaggedString *l) +{ + while (l) { + TaggedString *next = l->next; + luaI_free(l); + l = next; } } /* ** Garbage collection function. -** This function traverse the string list freeing unindexed strings */ -Long lua_strcollector (void) +TaggedString *luaI_strcollector (long *acum) { Long counter = 0; + TaggedString *frees = NULL; int i; for (i=0; imarked = 0; else { - luaI_free(t); + t->next = frees; + frees = t; tb->hash[j] = &EMPTY; counter++; } } } } - return counter; + *acum += counter; + return frees; } diff --git a/tree.h b/tree.h index ea9422ea..15b77b5f 100644 --- a/tree.h +++ b/tree.h @@ -1,7 +1,7 @@ /* ** tree.h ** TecCGraf - PUC-Rio -** $Id: tree.h,v 1.15 1997/02/11 11:35:05 roberto Exp roberto $ +** $Id: tree.h,v 1.16 1997/03/19 19:41:10 roberto Exp roberto $ */ #ifndef tree_h @@ -15,6 +15,7 @@ typedef struct TaggedString { int tag; /* if != LUA_T_STRING, this is a userdata */ + struct TaggedString *next; long size; Word varindex; /* != NOT_USED if this is a symbol */ Word constindex; /* != NOT_USED if this is a constant */ @@ -26,7 +27,8 @@ typedef struct TaggedString TaggedString *lua_createstring (char *str); TaggedString *luaI_createuserdata (char *buff, long size, int tag); -Long lua_strcollector (void); -void luaI_strcallIM (void); +TaggedString *luaI_strcollector (long *cont); +void luaI_strfree (TaggedString *l); +void luaI_strcallIM (TaggedString *l); #endif