commit bd9e68cfcdbbae2fd49ab51a9df4a93ec56eff45
parent 9747f3c87a205d9aa914a650686d6dc4accde1d9
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 14 May 1997 15:38:09 -0300
new implementation of gc: "Pre-collect" garbage in temporary lists and
then call fallbacks.
Diffstat:
M | func.c | | | 31 | ++++++++++++++++++++----------- |
M | func.h | | | 5 | +++-- |
M | hash.c | | | 70 | +++++++++++++++++++++++++++++++++++++--------------------------------- |
M | hash.h | | | 7 | ++++--- |
M | table.c | | | 46 | +++++++++++++++++++++++++++++----------------- |
M | tree.c | | | 41 | +++++++++++++++++++++++------------------ |
M | tree.h | | | 8 | +++++--- |
7 files changed, 121 insertions(+), 87 deletions(-)
diff --git 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
@@ -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
@@ -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);
+ }
}
-
-/*
-** 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)
- {
- Hash *next = curr_array->next;
- if (markarray(curr_array) != 1)
- {
- if (prev == NULL) listhead = next;
- else prev->next = next;
- hashdelete(curr_array);
- ++counter;
+ while (frees) {
+ Hash *next = frees->next;
+ hashdelete(frees);
+ frees = next;
}
- else
- {
- markarray(curr_array) = 0;
- prev = curr_array;
+}
+
+
+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;
+ curr_array->next = frees;
+ frees = curr_array;
+ ++counter;
+ }
+ else {
+ markarray(curr_array) = 0;
+ prev = curr_array;
+ }
+ curr_array = next;
}
- curr_array = next;
- }
- return counter;
+ *acum += counter;
+ return frees;
}
diff --git 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
@@ -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
@@ -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;
- 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; 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;
}
diff --git 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