浏览代码

new implementation of gc: "Pre-collect" garbage in temporary lists and
then call fallbacks.

Roberto Ierusalimschy 28 年之前
父节点
当前提交
bd9e68cfcd
共有 7 个文件被更改,包括 121 次插入87 次删除
  1. 20 11
      func.c
  2. 3 2
      func.h
  3. 37 33
      hash.c
  4. 4 3
      hash.h
  5. 29 17
      table.c
  6. 23 18
      tree.c
  7. 5 3
      tree.h

+ 20 - 11
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;
 }
 
 

+ 3 - 2
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);

+ 37 - 33
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;
 }
 
 

+ 4 - 3
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);

+ 29 - 17
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();
 } 
 
 

+ 23 - 18
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;
 }
 

+ 5 - 3
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