فهرست منبع

GC now considers an "estimate" of object size, instead of just the number
of objects.

Roberto Ierusalimschy 28 سال پیش
والد
کامیت
907368ead5
8فایلهای تغییر یافته به همراه54 افزوده شده و 34 حذف شده
  1. 5 5
      ldo.c
  2. 7 1
      lfunc.c
  3. 11 11
      lgc.c
  4. 2 2
      lgc.h
  5. 2 3
      lobject.c
  6. 7 2
      lobject.h
  7. 9 4
      lstring.c
  8. 11 6
      ltable.c

+ 5 - 5
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $
+** $Id: ldo.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -140,7 +140,7 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn)
 
 
 /*
-** Call a C function. luaD_Cstack.base will point to the luaD_stack.top of the luaD_stack.stack,
+** Call a C function. luaD_Cstack.base will point to the top of the stack,
 ** and luaD_Cstack.num is the number of parameters. Returns an index
 ** to the first result from C.
 */
@@ -151,7 +151,7 @@ static StkId callC (lua_CFunction func, StkId base)
   luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base;
   /* incorporate parameters on the luaD_stack.stack */
   luaD_Cstack.lua2C = base;
-  luaD_Cstack.base = base+luaD_Cstack.num;  /* == luaD_stack.top-luaD_stack.stack */
+  luaD_Cstack.base = base+luaD_Cstack.num;  /* == top-stack */
   if (lua_callhook)
     luaD_callHook(base, LUA_T_CMARK, 0);
   (*func)();
@@ -347,12 +347,12 @@ static int do_main (ZIO *z, char *chunkname, int bin)
 {
   int status;
   do {
-    long old_entities = (luaC_checkGC(), luaO_nentities);
+    long old_blocks = (luaC_checkGC(), luaO_nblocks);
     status = protectedparser(z, chunkname, bin);
     if (status == 1) return 1;  /* error */
     else if (status == 2) return 0;  /* 'natural' end */
     else {
-      long newelems2 = 2*(luaO_nentities-old_entities);
+      unsigned long newelems2 = 2*(luaO_nblocks-old_blocks);
       luaC_threshold += newelems2;
       status = luaD_protectedrun(MULT_RET);
       luaC_threshold -= newelems2;

+ 7 - 1
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $
+** $Id: lfunc.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $
 ** Lua Funcion auxiliar
 ** See Copyright Notice in lua.h
 */
@@ -10,6 +10,8 @@
 #include "lfunc.h"
 #include "lmem.h"
 
+#define gcsizeproto(p)	5
+#define gcsizeclosure(c) 1
 
 GCnode luaF_root = {NULL, 0};
 GCnode luaF_rootcl = {NULL, 0};
@@ -20,6 +22,7 @@ Closure *luaF_newclosure (int nelems)
 {
   Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
   luaO_insertlist(&luaF_rootcl, (GCnode *)c);
+  luaO_nblocks += gcsizeclosure(c);
   return c;
 }
 
@@ -34,6 +37,7 @@ TProtoFunc *luaF_newproto (void)
   f->nconsts = 0;
   f->locvars = NULL;
   luaO_insertlist(&luaF_root, (GCnode *)f);
+  luaO_nblocks += gcsizeproto(f);
   return f;
 }
 
@@ -52,6 +56,7 @@ void luaF_freeproto (TProtoFunc *l)
 {
   while (l) {
     TProtoFunc *next = (TProtoFunc *)l->head.next;
+    luaO_nblocks -= gcsizeproto(l);
     freefunc(l);
     l = next;
   }
@@ -62,6 +67,7 @@ void luaF_freeclosure (Closure *l)
 {
   while (l) {
     Closure *next = (Closure *)l->head.next;
+    luaO_nblocks -= gcsizeclosure(l);
     luaM_free(l);
     l = next;
   }

+ 11 - 11
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.3 1997/09/26 16:46:20 roberto Exp roberto $
+** $Id: lgc.c,v 1.4 1997/10/16 10:59:34 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -148,7 +148,6 @@ static GCnode *listcollect (GCnode *l)
       next->next = frees;
       frees = next;
       next = l->next;
-      --luaO_nentities;
     }
     l = next;
   }
@@ -252,7 +251,7 @@ static void call_nilIM (void)
 
 #define GARBAGE_BLOCK 150
 
-long luaC_threshold = GARBAGE_BLOCK;
+unsigned long luaC_threshold = GARBAGE_BLOCK;
 
 
 static void markall (void)
@@ -266,7 +265,7 @@ static void markall (void)
 
 long lua_collectgarbage (long limit)
 {
-  long recovered = luaO_nentities;  /* to subtract luaM_new value after gc */
+  unsigned long recovered = luaO_nblocks;  /* to subtract nblocks after gc */
   Hash *freetable;
   TaggedString *freestr;
   TProtoFunc *freefunc;
@@ -277,24 +276,25 @@ long lua_collectgarbage (long limit)
   freetable = (Hash *)listcollect(&luaH_root);
   freefunc = (TProtoFunc *)listcollect(&luaF_root);
   freeclos = (Closure *)listcollect(&luaF_rootcl);
-  recovered = recovered-luaO_nentities;
-/*printf("==total %ld  coletados %ld\n", luaO_nentities+recovered, recovered);*/
-  luaC_threshold = (limit == 0) ? 2*luaO_nentities : luaO_nentities+limit;
-  hashcallIM(freetable);
-  strcallIM(freestr);
-  call_nilIM();
+  luaC_threshold *= 4;  /* to avoid GC during GC */
+  hashcallIM(freetable);  /* GC tag methods for tables */
+  strcallIM(freestr);  /* GC tag methods for userdata */
+  call_nilIM();  /* GC tag method for nil (signal end of GC) */
   luaH_free(freetable);
   luaS_free(freestr);
   luaF_freeproto(freefunc);
   luaF_freeclosure(freeclos);
   luaM_clearbuffer();
+  recovered = recovered-luaO_nblocks;
+/*printf("==total %ld  coletados %ld\n", luaO_nblocks+recovered, recovered);*/
+  luaC_threshold = (limit == 0) ? 2*luaO_nblocks : luaO_nblocks+limit;
   return recovered;
 }
 
 
 void luaC_checkGC (void)
 {
-  if (luaO_nentities >= luaC_threshold)
+  if (luaO_nblocks >= luaC_threshold)
     lua_collectgarbage(0);
 }
 

+ 2 - 2
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lgc.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -11,7 +11,7 @@
 #include "lobject.h"
 
 
-extern long luaC_threshold;
+extern unsigned long luaC_threshold;
 
 void luaC_checkGC (void);
 TObject* luaC_getref (int ref);

+ 2 - 3
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $
+** $Id: lobject.c,v 1.3 1997/10/16 20:07:40 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -17,7 +17,7 @@ char *luaO_typenames[] = { /* ORDER LUA_T */
 };
 
 
-long luaO_nentities = 0;
+unsigned long luaO_nblocks = 0;
 
 
 /* hash dimensions values */
@@ -68,7 +68,6 @@ int luaO_findstring (char *name, char *list[])
 
 void luaO_insertlist (GCnode *root, GCnode *node)
 {
-  ++luaO_nentities;
   node->next = root->next;
   root->next = node;
   node->marked = 0;

+ 7 - 2
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.4 1997/10/16 10:59:34 roberto Exp roberto $
+** $Id: lobject.h,v 1.5 1997/10/16 20:07:40 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -158,7 +158,12 @@ typedef struct Hash {
 } Hash;
 
 
-extern long luaO_nentities;
+/*
+** a gross estimation of number of memory "blocks" allocated
+** (a block is *roughly* 32 bytes)
+*/
+extern unsigned long luaO_nblocks;
+
 extern char *luaO_typenames[];
 
 int luaO_equalObj (TObject *t1, TObject *t2);

+ 9 - 4
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
+** $Id: lstring.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -16,6 +16,9 @@
 #define NUM_HASHS  61
 
 
+#define gcsizestring(l)	(1+(l/64))
+
+
 GCnode luaS_root = {NULL, 0};  /* list of global variables */
 
 
@@ -89,16 +92,19 @@ static TaggedString *newone(char *buff, int tag, unsigned long h)
 {
   TaggedString *ts;
   if (tag == LUA_T_STRING) {
-    ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+strlen(buff));
+    long l = strlen(buff);
+    ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
     strcpy(ts->str, buff);
     ts->u.globalval.ttype = LUA_T_NIL;  /* initialize global value */
     ts->constindex = 0;
+    luaO_nblocks += gcsizestring(l);
   }
   else {
     ts = (TaggedString *)luaM_malloc(sizeof(TaggedString));
     ts->u.d.v = buff;
     ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
     ts->constindex = -1;  /* tag -> this is a userdata */
+    luaO_nblocks++;
   }
   ts->head.marked = 0;
   ts->head.next = (GCnode *)ts;  /* signal it is in no list */
@@ -126,7 +132,6 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
     i = (i+1)%tb->size;
   }
   /* not found */
-  ++luaO_nentities;
   if (j != -1)  /* is there an EMPTY space? */
     i = j;
   else
@@ -158,6 +163,7 @@ void luaS_free (TaggedString *l)
 {
   while (l) {
     TaggedString *next = (TaggedString *)l->head.next;
+    luaO_nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str));
     luaM_free(l);
     l = next;
   }
@@ -196,7 +202,6 @@ TaggedString *luaS_collector (void)
         t->head.next = (GCnode *)frees;
         frees = t;
         tb->hash[j] = ∅
-        --luaO_nentities;
       }
     }
   }

+ 11 - 6
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $
+** $Id: ltable.c,v 1.3 1997/10/18 16:29:15 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -13,6 +13,8 @@
 #include "lua.h"
 
 
+#define gcsize(n)	(1+(n/16))
+
 #define nuse(t)		((t)->nuse)
 #define nodevector(t)	((t)->node)
 
@@ -75,11 +77,11 @@ static int present (Hash *t, TObject *key)
 */
 static Node *hashnodecreate (int nhash)
 {
- int i;
- Node *v = luaM_newvector (nhash, Node);
- for (i=0; i<nhash; i++)
-   ttype(ref(&v[i])) = LUA_T_NIL;
- return v;
+  Node *v = luaM_newvector(nhash, Node);
+  int i;
+  for (i=0; i<nhash; i++)
+    ttype(ref(&v[i])) = LUA_T_NIL;
+  return v;
 }
 
 /*
@@ -96,6 +98,7 @@ void luaH_free (Hash *frees)
 {
   while (frees) {
     Hash *next = (Hash *)frees->head.next;
+    luaO_nblocks -= gcsize(frees->nhash);
     hashdelete(frees);
     frees = next;
   }
@@ -111,6 +114,7 @@ Hash *luaH_new (int nhash)
   nuse(t) = 0;
   t->htag = TagDefault;
   luaO_insertlist(&luaH_root, (GCnode *)t);
+  luaO_nblocks += gcsize(nhash);
   return t;
 }
 
@@ -144,6 +148,7 @@ static void rehash (Hash *t)
     if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
       *node(t, present(t, ref(n))) = *n;  /* copy old node to luaM_new hash */
   }
+  luaO_nblocks += gcsize(t->nhash)-gcsize(nold);
   luaM_free(vold);
 }