Просмотр исходного кода

more options for controling the GC

Roberto Ierusalimschy 20 лет назад
Родитель
Сommit
39a8082f50
7 измененных файлов с 49 добавлено и 32 удалено
  1. 11 1
      lapi.c
  2. 5 5
      lbaselib.c
  3. 15 17
      lgc.c
  4. 3 1
      lstate.c
  5. 3 1
      lstate.h
  6. 8 6
      lua.h
  7. 4 1
      luaconf.h

+ 11 - 1
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.20 2004/11/24 18:55:56 roberto Exp roberto $
+** $Id: lapi.c,v 2.21 2004/12/03 20:50:25 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -867,6 +867,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
       luaC_step(L);
       break;
     }
+    case LUA_GCSETSTEPMUL: {
+      res = g->stepmul;
+      g->stepmul = data;
+      break;
+    }
+    case LUA_GCSETINCMODE: {
+      res = g->incgc;
+      g->incgc = data;
+      break;
+    }
     default: res = -1;  /* invalid option */
   }
   lua_unlock(L);

+ 5 - 5
lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.159 2004/09/29 21:03:14 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.160 2004/11/18 19:53:49 roberto Exp roberto $
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -181,10 +181,10 @@ static int luaB_gcinfo (lua_State *L) {
 
 
 static int luaB_collectgarbage (lua_State *L) {
-  static const char *const opts[] = {"stop", "restart", "collect", "count",
-                                     "step", NULL};
-  static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART,
-                                LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP};
+  static const char *const opts[] = {"stop", "restart", "collect",
+    "count", "step", "setstepmul", "setincmode", NULL};
+  static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
+    LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETSTEPMUL, LUA_GCSETINCMODE};
   int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts);
   int ex = luaL_optint(L, 2, 0);
   luaL_argcheck(L, o >= 0, 1, "invalid option");

+ 15 - 17
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.16 2004/11/24 18:55:56 roberto Exp roberto $
+** $Id: lgc.c,v 2.17 2004/11/24 19:20:21 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -24,7 +24,6 @@
 
 
 #define GCSTEPSIZE	1000
-#define STEPMUL		2
 #define GCSWEEPMAX	10
 #define GCSWEEPCOST	30
 #define GCFINALIZECOST	100
@@ -65,7 +64,7 @@
 static void removeentry (Node *n) {
   setnilvalue(gval(n));  /* remove corresponding value ... */
   if (iscollectable(gkey(n)))
-    setttype(gkey(n), LUA_TNONE);  /* dead key; remove it */
+    setttype(gkey(n), LUA_TDEADKEY);  /* dead key; remove it */
 }
 
 
@@ -184,6 +183,7 @@ static int traversetable (global_State *g, Table *h) {
   i = sizenode(h);
   while (i--) {
     Node *n = gnode(h, i);
+    lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
     if (ttisnil(gval(n)))
       removeentry(n);  /* remove empty entries */
     else {
@@ -555,7 +555,7 @@ static void atomic (lua_State *L) {
   g->sweepgc = &g->rootgc;
   g->gcstate = GCSsweepstring;
   aux = g->gcgenerational;
-  g->gcgenerational = (g->estimate/2 <= g->prevestimate);
+  g->gcgenerational = g->incgc && (g->estimate/2 <= g->prevestimate);
   if (!aux)  /* last collection was full? */
     g->prevestimate = g->estimate;  /* keep estimate of last full collection */
   g->estimate = g->totalbytes - udsize;  /* first estimate */
@@ -587,6 +587,7 @@ static l_mem singlestep (lua_State *L) {
       sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
       if (g->sweepstrgc >= g->strt.size)  /* nothing more to sweep? */
         g->gcstate = GCSsweep;  /* end sweep-string phase */
+      lua_assert(old >= g->totalbytes);
       g->estimate -= old - g->totalbytes;
       return GCSWEEPCOST;
     }
@@ -597,6 +598,7 @@ static l_mem singlestep (lua_State *L) {
         checkSizes(L);
         g->gcstate = GCSfinalize;  /* end sweep phase */
       }
+      lua_assert(old >= g->totalbytes);
       g->estimate -= old - g->totalbytes;
       return GCSWEEPMAX*GCSWEEPCOST;
     }
@@ -619,23 +621,18 @@ static l_mem singlestep (lua_State *L) {
 
 void luaC_step (lua_State *L) {
   global_State *g = G(L);
-  l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * STEPMUL;
-/*printf("step(%c): ", g->gcgenerational?'g':' ');*/
+  l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * g->stepmul;
   do {
-    /*printf("%c", "_pswf"[g->gcstate]);*/
     lim -= singlestep(L);
     if (g->gcstate == GCSpause)
       break;
-  } while (lim > 0);
-/*printf("\n");*/
-  if (g->gcstate != GCSpause)
+  } while (lim > 0 || !g->incgc);
+  if (g->incgc)
     g->GCthreshold = g->totalbytes + GCSTEPSIZE;  /* - lim/STEPMUL; */
   else {
-/*printf("---\n");*/
     lua_assert(g->totalbytes >= g->estimate);
+    lua_assert(g->gcstate == GCSpause);
     g->GCthreshold = 2*g->estimate;
-    if (g->GCthreshold < g->totalbytes + GCSTEPSIZE)
-      g->GCthreshold = g->totalbytes + GCSTEPSIZE;
   }
 }
 
@@ -660,19 +657,19 @@ void luaC_fullgc (lua_State *L) {
   }
   markroot(L);
   lua_assert(!g->gcgenerational);
-  while (g->gcstate != GCSfinalize) {
+  while (g->gcstate != GCSpause) {
     singlestep(L);
     g->gcgenerational = 0;  /* keep it in this mode */
   }
   g->GCthreshold = 2*g->estimate;
-  luaC_callGCTM(L);  /* call finalizers */
 }
 
 
 void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
   global_State *g = G(L);
   lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
-  lua_assert(g->gcgenerational || g->gcstate != GCSfinalize);
+  lua_assert(g->gcgenerational ||
+             (g->gcstate != GCSfinalize && g->gcstate != GCSpause));
   lua_assert(ttype(&o->gch) != LUA_TTABLE);
   /* must keep invariant? */
   if (g->gcstate == GCSpropagate || g->gcgenerational)
@@ -685,7 +682,8 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
 void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) {
   global_State *g = G(L);
   lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
-  lua_assert(g->gcgenerational || g->gcstate != GCSfinalize);
+  lua_assert(g->gcgenerational ||
+             (g->gcstate != GCSfinalize && g->gcstate != GCSpause));
   black2gray(o);  /* make table gray (again) */
   gco2h(o)->gclist = g->grayagain;
   g->grayagain = o;

+ 3 - 1
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.16 2004/11/19 15:52:40 roberto Exp roberto $
+** $Id: lstate.c,v 2.17 2004/11/24 19:20:21 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -193,6 +193,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   setnilvalue(gval(g->dummynode));
   gnext(g->dummynode) = NULL;
   g->totalbytes = sizeof(LG);
+  g->stepmul = STEPMUL;
+  g->incgc = 1;
   if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
     /* memory allocation error: free partial state */
     close_state(L);

+ 3 - 1
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.7 2004/08/30 13:44:44 roberto Exp roberto $
+** $Id: lstate.h,v 2.8 2004/09/15 20:39:42 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -85,6 +85,8 @@ typedef struct global_State {
   lu_mem totalbytes;  /* number of bytes currently allocated */
   lu_mem estimate;  /* an estimate of number of bytes actually in use */
   lu_mem prevestimate;  /* previous estimate */
+  int stepmul;  /* relative `speed' of the GC */
+  int incgc;  /* 0 if GC is done non-incrementally */
   lua_CFunction panic;  /* to be called in unprotected errors */
   TValue _registry;
   struct lua_State *mainthread;

+ 8 - 6
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.194 2004/10/18 12:51:44 roberto Exp roberto $
+** $Id: lua.h,v 1.195 2004/12/01 15:50:18 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
 ** http://www.lua.org	mailto:[email protected]
@@ -220,11 +220,13 @@ LUA_API int  lua_threadstatus (lua_State *L);
 ** garbage-collection function and options
 */
 
-#define LUA_GCSTOP	0
-#define LUA_GCRESTART	1
-#define LUA_GCCOLLECT	2
-#define LUA_GCCOUNT	3
-#define LUA_GCSTEP	4
+#define LUA_GCSTOP		0
+#define LUA_GCRESTART		1
+#define LUA_GCCOLLECT		2
+#define LUA_GCCOUNT		3
+#define LUA_GCSTEP		4
+#define LUA_GCSETSTEPMUL	5
+#define LUA_GCSETINCMODE	6
 
 LUA_API int lua_gc (lua_State *L, int what, int data);
 

+ 4 - 1
luaconf.h

@@ -1,5 +1,5 @@
 /*
-** $Id: luaconf.h,v 1.18 2004/12/01 15:50:18 roberto Exp roberto $
+** $Id: luaconf.h,v 1.19 2004/12/01 15:52:54 roberto Exp roberto $
 ** Configuration file for Lua
 ** See Copyright Notice in lua.h
 */
@@ -273,6 +273,9 @@
 #define lua_userstateopen(L)	/* empty */
 
 
+/* initial GC parameters */
+#define STEPMUL		4
+
 #endif
 
 /* }====================================================== */