1
0
mirror of https://github.com/lua/lua.git synced 2025-02-04 06:13:04 +08:00

new implementation of gc: "Pre-collect" garbage in temporary lists and

then call fallbacks.
This commit is contained in:
Roberto Ierusalimschy 1997-05-14 15:38:29 -03:00
parent 9747f3c87a
commit bd9e68cfcd
7 changed files with 121 additions and 87 deletions

31
func.c
View File

@ -49,35 +49,44 @@ void luaI_freefunc (TFunc *f)
luaI_free (f); luaI_free (f);
} }
void luaI_funcfree (TFunc *l)
{
while (l) {
TFunc *next = l->next;
luaI_freefunc(l);
l = next;
}
}
/* /*
** Garbage collection function. ** 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 *curr = function_root;
TFunc *prev = NULL; TFunc *prev = NULL;
Long counter = 0; TFunc *frees = NULL;
while (curr) long counter = 0;
{ while (curr) {
TFunc *next = curr->next; TFunc *next = curr->next;
if (!curr->marked) if (!curr->marked) {
{
if (prev == NULL) if (prev == NULL)
function_root = next; function_root = next;
else else
prev->next = next; prev->next = next;
luaI_freefunc (curr); curr->next = frees;
frees = curr;
++counter; ++counter;
} }
else else {
{
curr->marked = 0; curr->marked = 0;
prev = curr; prev = curr;
} }
curr = next; curr = next;
} }
return counter; *acum += counter;
return frees;
} }

5
func.h
View File

@ -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 #ifndef func_h
@ -30,7 +30,8 @@ typedef struct TFunc
LocVar *locvars; LocVar *locvars;
} TFunc; } TFunc;
Long luaI_funccollector (void); TFunc *luaI_funccollector (long *cont);
void luaI_funcfree (TFunc *l);
void luaI_insertfunction (TFunc *f); void luaI_insertfunction (TFunc *f);
void luaI_initTFunc (TFunc *f); void luaI_initTFunc (TFunc *f);

70
hash.c
View File

@ -3,7 +3,7 @@
** hash manager for lua ** 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" #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; TObject t;
ttype(&t) = LUA_T_ARRAY; ttype(&t) = LUA_T_ARRAY;
for (curr_array = listhead; curr_array; curr_array = curr_array->next) for (; l; l=l->next) {
if (markarray(curr_array) != 1) avalue(&t) = l;
{ luaI_gcIM(&t);
avalue(&t) = curr_array; }
luaI_gcIM(&t); }
}
void luaI_hashfree (Hash *frees)
{
while (frees) {
Hash *next = frees->next;
hashdelete(frees);
frees = next;
}
} }
/* Hash *luaI_hashcollector (long *acum)
** Garbage collection to arrays
** Delete all unmarked arrays.
*/
Long lua_hashcollector (void)
{ {
Hash *curr_array = listhead, *prev = NULL; Hash *curr_array = listhead, *prev = NULL, *frees = NULL;
Long counter = 0; long counter = 0;
while (curr_array != NULL) while (curr_array != NULL) {
{ Hash *next = curr_array->next;
Hash *next = curr_array->next; if (markarray(curr_array) != 1) {
if (markarray(curr_array) != 1) if (prev == NULL)
{ listhead = next;
if (prev == NULL) listhead = next; else
else prev->next = next; prev->next = next;
hashdelete(curr_array); curr_array->next = frees;
++counter; frees = curr_array;
++counter;
}
else {
markarray(curr_array) = 0;
prev = curr_array;
}
curr_array = next;
} }
else *acum += counter;
{ return frees;
markarray(curr_array) = 0;
prev = curr_array;
}
curr_array = next;
}
return counter;
} }

7
hash.h
View File

@ -1,7 +1,7 @@
/* /*
** hash.h ** hash.h
** hash manager for lua ** 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 #ifndef hash_h
@ -29,8 +29,9 @@ int lua_equalObj (TObject *t1, TObject *t2);
int luaI_redimension (int nhash); int luaI_redimension (int nhash);
Hash *lua_createarray (int nhash); Hash *lua_createarray (int nhash);
void lua_hashmark (Hash *h); void lua_hashmark (Hash *h);
Long lua_hashcollector (void); Hash *luaI_hashcollector (long *count);
void luaI_hashcallIM (void); void luaI_hashcallIM (Hash *l);
void luaI_hashfree (Hash *frees);
TObject *lua_hashget (Hash *t, TObject *ref); TObject *lua_hashget (Hash *t, TObject *ref);
TObject *lua_hashdefine (Hash *t, TObject *ref); TObject *lua_hashdefine (Hash *t, TObject *ref);
void lua_next (void); void lua_next (void);

46
table.c
View File

@ -3,10 +3,11 @@
** Module to control static tables ** 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 "luamem.h"
#include "auxlib.h" #include "auxlib.h"
#include "func.h"
#include "opcode.h" #include "opcode.h"
#include "tree.h" #include "tree.h"
#include "hash.h" #include "hash.h"
@ -176,32 +177,43 @@ static void call_nilIM (void)
** Garbage collection. ** Garbage collection.
** Delete all unused strings and arrays. ** 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_travstack(lua_markobject); /* mark stack objects */
lua_travsymbol(lua_markobject); /* mark symbol table objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */ luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */ 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(); call_nilIM();
luaI_invalidaterefs(); luaI_hashfree(freetable);
recovered += lua_strcollector(); luaI_strfree(freestr);
recovered += lua_hashcollector(); luaI_funcfree(freefunc);
recovered += luaI_funccollector();
return recovered;
} }
void lua_pack (void) void lua_pack (void)
{ {
static unsigned long block = GARBAGE_BLOCK; if (gc_nentity++ >= gc_block)
static unsigned long nentity = 0; /* total of strings, arrays, etc */ lua_collectgarbage();
unsigned long recovered = 0;
if (nentity++ < block) return;
recovered = luaI_collectgarbage();
block = 2*(block-recovered);
nentity -= recovered;
} }

41
tree.c
View File

@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio ** 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 <string.h> #include <string.h>
@ -29,7 +29,8 @@ static int initialized = 0;
static stringtable string_root[NUM_HASHS]; 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) 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; TObject o;
ttype(&o) = LUA_T_USERDATA; ttype(&o) = LUA_T_USERDATA;
for (i=0; i<NUM_HASHS; i++) { for (; l; l=l->next) {
stringtable *tb = &string_root[i]; tsvalue(&o) = l;
int j; luaI_gcIM(&o);
for (j=0; j<tb->size; j++) { }
TaggedString *t = tb->hash[j]; }
if (t != NULL && t->tag != LUA_T_STRING && t->marked == 0) {
tsvalue(&o) = t;
luaI_gcIM(&o); void luaI_strfree (TaggedString *l)
} {
} while (l) {
TaggedString *next = l->next;
luaI_free(l);
l = next;
} }
} }
/* /*
** Garbage collection function. ** Garbage collection function.
** This function traverse the string list freeing unindexed strings
*/ */
Long lua_strcollector (void) TaggedString *luaI_strcollector (long *acum)
{ {
Long counter = 0; Long counter = 0;
TaggedString *frees = NULL;
int i; int i;
for (i=0; i<NUM_HASHS; i++) for (i=0; i<NUM_HASHS; i++)
{ {
@ -174,13 +177,15 @@ Long lua_strcollector (void)
t->marked = 0; t->marked = 0;
else else
{ {
luaI_free(t); t->next = frees;
frees = t;
tb->hash[j] = &EMPTY; tb->hash[j] = &EMPTY;
counter++; counter++;
} }
} }
} }
} }
return counter; *acum += counter;
return frees;
} }

8
tree.h
View File

@ -1,7 +1,7 @@
/* /*
** tree.h ** tree.h
** TecCGraf - PUC-Rio ** 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 #ifndef tree_h
@ -15,6 +15,7 @@
typedef struct TaggedString typedef struct TaggedString
{ {
int tag; /* if != LUA_T_STRING, this is a userdata */ int tag; /* if != LUA_T_STRING, this is a userdata */
struct TaggedString *next;
long size; long size;
Word varindex; /* != NOT_USED if this is a symbol */ Word varindex; /* != NOT_USED if this is a symbol */
Word constindex; /* != NOT_USED if this is a constant */ Word constindex; /* != NOT_USED if this is a constant */
@ -26,7 +27,8 @@ typedef struct TaggedString
TaggedString *lua_createstring (char *str); TaggedString *lua_createstring (char *str);
TaggedString *luaI_createuserdata (char *buff, long size, int tag); TaggedString *luaI_createuserdata (char *buff, long size, int tag);
Long lua_strcollector (void); TaggedString *luaI_strcollector (long *cont);
void luaI_strcallIM (void); void luaI_strfree (TaggedString *l);
void luaI_strcallIM (TaggedString *l);
#endif #endif