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);
}
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;
}

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
@ -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);

52
hash.c
View File

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

7
hash.h
View File

@ -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);

48
table.c
View File

@ -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();
call_nilIM();
luaI_invalidaterefs();
recovered += lua_strcollector();
recovered += lua_hashcollector();
recovered += luaI_funccollector();
return recovered;
}
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_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();
}

37
tree.c
View File

@ -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 <string.h>
@ -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; i<NUM_HASHS; i++) {
stringtable *tb = &string_root[i];
int j;
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;
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; i<NUM_HASHS; i++)
{
@ -174,13 +177,15 @@ Long lua_strcollector (void)
t->marked = 0;
else
{
luaI_free(t);
t->next = frees;
frees = t;
tb->hash[j] = &EMPTY;
counter++;
}
}
}
}
return counter;
*acum += counter;
return frees;
}

8
tree.h
View File

@ -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