Bläddra i källkod

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

Roberto Ierusalimschy 28 år sedan
förälder
incheckning
907368ead5
8 ändrade filer med 54 tillägg och 34 borttagningar
  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
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** 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
 ** and luaD_Cstack.num is the number of parameters. Returns an index
 ** to the first result from C.
 ** 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;
   luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base;
   /* incorporate parameters on the luaD_stack.stack */
   /* incorporate parameters on the luaD_stack.stack */
   luaD_Cstack.lua2C = base;
   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)
   if (lua_callhook)
     luaD_callHook(base, LUA_T_CMARK, 0);
     luaD_callHook(base, LUA_T_CMARK, 0);
   (*func)();
   (*func)();
@@ -347,12 +347,12 @@ static int do_main (ZIO *z, char *chunkname, int bin)
 {
 {
   int status;
   int status;
   do {
   do {
-    long old_entities = (luaC_checkGC(), luaO_nentities);
+    long old_blocks = (luaC_checkGC(), luaO_nblocks);
     status = protectedparser(z, chunkname, bin);
     status = protectedparser(z, chunkname, bin);
     if (status == 1) return 1;  /* error */
     if (status == 1) return 1;  /* error */
     else if (status == 2) return 0;  /* 'natural' end */
     else if (status == 2) return 0;  /* 'natural' end */
     else {
     else {
-      long newelems2 = 2*(luaO_nentities-old_entities);
+      unsigned long newelems2 = 2*(luaO_nblocks-old_blocks);
       luaC_threshold += newelems2;
       luaC_threshold += newelems2;
       status = luaD_protectedrun(MULT_RET);
       status = luaD_protectedrun(MULT_RET);
       luaC_threshold -= newelems2;
       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
 ** Lua Funcion auxiliar
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -10,6 +10,8 @@
 #include "lfunc.h"
 #include "lfunc.h"
 #include "lmem.h"
 #include "lmem.h"
 
 
+#define gcsizeproto(p)	5
+#define gcsizeclosure(c) 1
 
 
 GCnode luaF_root = {NULL, 0};
 GCnode luaF_root = {NULL, 0};
 GCnode luaF_rootcl = {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));
   Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
   luaO_insertlist(&luaF_rootcl, (GCnode *)c);
   luaO_insertlist(&luaF_rootcl, (GCnode *)c);
+  luaO_nblocks += gcsizeclosure(c);
   return c;
   return c;
 }
 }
 
 
@@ -34,6 +37,7 @@ TProtoFunc *luaF_newproto (void)
   f->nconsts = 0;
   f->nconsts = 0;
   f->locvars = NULL;
   f->locvars = NULL;
   luaO_insertlist(&luaF_root, (GCnode *)f);
   luaO_insertlist(&luaF_root, (GCnode *)f);
+  luaO_nblocks += gcsizeproto(f);
   return f;
   return f;
 }
 }
 
 
@@ -52,6 +56,7 @@ void luaF_freeproto (TProtoFunc *l)
 {
 {
   while (l) {
   while (l) {
     TProtoFunc *next = (TProtoFunc *)l->head.next;
     TProtoFunc *next = (TProtoFunc *)l->head.next;
+    luaO_nblocks -= gcsizeproto(l);
     freefunc(l);
     freefunc(l);
     l = next;
     l = next;
   }
   }
@@ -62,6 +67,7 @@ void luaF_freeclosure (Closure *l)
 {
 {
   while (l) {
   while (l) {
     Closure *next = (Closure *)l->head.next;
     Closure *next = (Closure *)l->head.next;
+    luaO_nblocks -= gcsizeclosure(l);
     luaM_free(l);
     luaM_free(l);
     l = next;
     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
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -148,7 +148,6 @@ static GCnode *listcollect (GCnode *l)
       next->next = frees;
       next->next = frees;
       frees = next;
       frees = next;
       next = l->next;
       next = l->next;
-      --luaO_nentities;
     }
     }
     l = next;
     l = next;
   }
   }
@@ -252,7 +251,7 @@ static void call_nilIM (void)
 
 
 #define GARBAGE_BLOCK 150
 #define GARBAGE_BLOCK 150
 
 
-long luaC_threshold = GARBAGE_BLOCK;
+unsigned long luaC_threshold = GARBAGE_BLOCK;
 
 
 
 
 static void markall (void)
 static void markall (void)
@@ -266,7 +265,7 @@ static void markall (void)
 
 
 long lua_collectgarbage (long limit)
 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;
   Hash *freetable;
   TaggedString *freestr;
   TaggedString *freestr;
   TProtoFunc *freefunc;
   TProtoFunc *freefunc;
@@ -277,24 +276,25 @@ long lua_collectgarbage (long limit)
   freetable = (Hash *)listcollect(&luaH_root);
   freetable = (Hash *)listcollect(&luaH_root);
   freefunc = (TProtoFunc *)listcollect(&luaF_root);
   freefunc = (TProtoFunc *)listcollect(&luaF_root);
   freeclos = (Closure *)listcollect(&luaF_rootcl);
   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);
   luaH_free(freetable);
   luaS_free(freestr);
   luaS_free(freestr);
   luaF_freeproto(freefunc);
   luaF_freeproto(freefunc);
   luaF_freeclosure(freeclos);
   luaF_freeclosure(freeclos);
   luaM_clearbuffer();
   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;
   return recovered;
 }
 }
 
 
 
 
 void luaC_checkGC (void)
 void luaC_checkGC (void)
 {
 {
-  if (luaO_nentities >= luaC_threshold)
+  if (luaO_nblocks >= luaC_threshold)
     lua_collectgarbage(0);
     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
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -11,7 +11,7 @@
 #include "lobject.h"
 #include "lobject.h"
 
 
 
 
-extern long luaC_threshold;
+extern unsigned long luaC_threshold;
 
 
 void luaC_checkGC (void);
 void luaC_checkGC (void);
 TObject* luaC_getref (int ref);
 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
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 ** 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 */
 /* hash dimensions values */
@@ -68,7 +68,6 @@ int luaO_findstring (char *name, char *list[])
 
 
 void luaO_insertlist (GCnode *root, GCnode *node)
 void luaO_insertlist (GCnode *root, GCnode *node)
 {
 {
-  ++luaO_nentities;
   node->next = root->next;
   node->next = root->next;
   root->next = node;
   root->next = node;
   node->marked = 0;
   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
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -158,7 +158,12 @@ typedef struct Hash {
 } 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[];
 extern char *luaO_typenames[];
 
 
 int luaO_equalObj (TObject *t1, TObject *t2);
 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)
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -16,6 +16,9 @@
 #define NUM_HASHS  61
 #define NUM_HASHS  61
 
 
 
 
+#define gcsizestring(l)	(1+(l/64))
+
+
 GCnode luaS_root = {NULL, 0};  /* list of global variables */
 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;
   TaggedString *ts;
   if (tag == LUA_T_STRING) {
   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);
     strcpy(ts->str, buff);
     ts->u.globalval.ttype = LUA_T_NIL;  /* initialize global value */
     ts->u.globalval.ttype = LUA_T_NIL;  /* initialize global value */
     ts->constindex = 0;
     ts->constindex = 0;
+    luaO_nblocks += gcsizestring(l);
   }
   }
   else {
   else {
     ts = (TaggedString *)luaM_malloc(sizeof(TaggedString));
     ts = (TaggedString *)luaM_malloc(sizeof(TaggedString));
     ts->u.d.v = buff;
     ts->u.d.v = buff;
     ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
     ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
     ts->constindex = -1;  /* tag -> this is a userdata */
     ts->constindex = -1;  /* tag -> this is a userdata */
+    luaO_nblocks++;
   }
   }
   ts->head.marked = 0;
   ts->head.marked = 0;
   ts->head.next = (GCnode *)ts;  /* signal it is in no list */
   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;
     i = (i+1)%tb->size;
   }
   }
   /* not found */
   /* not found */
-  ++luaO_nentities;
   if (j != -1)  /* is there an EMPTY space? */
   if (j != -1)  /* is there an EMPTY space? */
     i = j;
     i = j;
   else
   else
@@ -158,6 +163,7 @@ void luaS_free (TaggedString *l)
 {
 {
   while (l) {
   while (l) {
     TaggedString *next = (TaggedString *)l->head.next;
     TaggedString *next = (TaggedString *)l->head.next;
+    luaO_nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str));
     luaM_free(l);
     luaM_free(l);
     l = next;
     l = next;
   }
   }
@@ -196,7 +202,6 @@ TaggedString *luaS_collector (void)
         t->head.next = (GCnode *)frees;
         t->head.next = (GCnode *)frees;
         frees = t;
         frees = t;
         tb->hash[j] = ∅
         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)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -13,6 +13,8 @@
 #include "lua.h"
 #include "lua.h"
 
 
 
 
+#define gcsize(n)	(1+(n/16))
+
 #define nuse(t)		((t)->nuse)
 #define nuse(t)		((t)->nuse)
 #define nodevector(t)	((t)->node)
 #define nodevector(t)	((t)->node)
 
 
@@ -75,11 +77,11 @@ static int present (Hash *t, TObject *key)
 */
 */
 static Node *hashnodecreate (int nhash)
 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) {
   while (frees) {
     Hash *next = (Hash *)frees->head.next;
     Hash *next = (Hash *)frees->head.next;
+    luaO_nblocks -= gcsize(frees->nhash);
     hashdelete(frees);
     hashdelete(frees);
     frees = next;
     frees = next;
   }
   }
@@ -111,6 +114,7 @@ Hash *luaH_new (int nhash)
   nuse(t) = 0;
   nuse(t) = 0;
   t->htag = TagDefault;
   t->htag = TagDefault;
   luaO_insertlist(&luaH_root, (GCnode *)t);
   luaO_insertlist(&luaH_root, (GCnode *)t);
+  luaO_nblocks += gcsize(nhash);
   return t;
   return t;
 }
 }
 
 
@@ -144,6 +148,7 @@ static void rehash (Hash *t)
     if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
     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 */
       *node(t, present(t, ref(n))) = *n;  /* copy old node to luaM_new hash */
   }
   }
+  luaO_nblocks += gcsize(t->nhash)-gcsize(nold);
   luaM_free(vold);
   luaM_free(vold);
 }
 }