Explorar o código

major collections in generational mode

Roberto Ierusalimschy %!s(int64=15) %!d(string=hai) anos
pai
achega
5c87f61e6b
Modificáronse 4 ficheiros con 39 adicións e 23 borrados
  1. 15 9
      lapi.c
  2. 14 6
      lgc.c
  3. 2 1
      lstate.c
  4. 8 7
      lstate.h

+ 15 - 9
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.114 2010/03/08 16:55:52 roberto Exp roberto $
+** $Id: lapi.c,v 2.115 2010/03/22 18:28:03 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -928,7 +928,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
       break;
     }
     case LUA_GCRESTART: {
-      g->gckind = KGC_NORMAL;
       g->GCthreshold = g->totalbytes;
       break;
     }
@@ -947,13 +946,19 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
     }
     case LUA_GCSTEP: {
       lu_mem oldts = g->GCthreshold;
-      lu_mem a = (cast(lu_mem, data) << 10);
-      g->GCthreshold = (a <= g->totalbytes) ? g->totalbytes - a : 0;
-      while (g->GCthreshold <= g->totalbytes) {
-        luaC_step(L);
-        if (g->gcstate == GCSpause) {  /* end of cycle? */
-          res = 1;  /* signal it */
-          break;
+      if (g->gckind == KGC_GEN) {  /* generational mode? */
+        res = (g->lastmajormem == 0);  /* 1 if will do major collection */
+        luaC_step(L);  /* do a single step */
+      }
+      else {
+        lu_mem a = (cast(lu_mem, data) << 10);
+        g->GCthreshold = (a <= g->totalbytes) ? g->totalbytes - a : 0;
+        while (g->GCthreshold <= g->totalbytes) {
+          luaC_step(L);
+          if (g->gcstate == GCSpause) {  /* end of cycle? */
+            res = 1;  /* signal it */
+            break;
+          }
         }
       }
       if (oldts == MAX_LUMEM)  /* collector was stopped? */
@@ -976,6 +981,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
     }
     case LUA_GCGEN: {  /* change collector to generational mode */
       luaC_runtilstate(L, bitmask(GCSpropagate));
+      g->lastmajormem = g->totalbytes;
       g->gckind = KGC_GEN;
       break;
     }

+ 14 - 6
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.71 2010/03/24 15:51:10 roberto Exp roberto $
+** $Id: lgc.c,v 2.72 2010/03/25 13:06:36 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -835,11 +835,19 @@ static int prev = 0;
   global_State *g = G(L);
 int a = g->totalbytes;
   lua_assert(g->gcstate == GCSpropagate);
-  luaC_runtilstate(L, bitmask(GCSpause));
-  g->gcstate = GCSpropagate;  /* do not run 'markroot' */
+  if (g->lastmajormem == 0) {  /* signal for another major collection? */
+    luaC_fullgc(L, 0);  /* perform a full regular collection */
+    g->lastmajormem = g->totalbytes;  /* update control */
+  }
+  else {
+    luaC_runtilstate(L, bitmask(GCSpause));
+    g->gcstate = GCSpropagate;  /* do not run 'markroot' */
+    if (g->totalbytes > g->lastmajormem/100 * g->gcpause)
+      g->lastmajormem = 0;  /* signal for a major collection */
+  }
   g->GCthreshold = (g->totalbytes/100) * g->gcpause;
-/*printf("count: %d  old: %d  new: %d  dif: %d\n", c++, a, g->totalbytes,
-g->totalbytes - prev);*/
+/*printf("count: %d  old: %d  new: %d  dif: %d  lim: %d  threshold: %d\n",
+c++, a, g->totalbytes, g->totalbytes - prev, g->lastmajormem, g->GCthreshold);*/
 prev = g->totalbytes;
 }
 
@@ -890,7 +898,7 @@ void luaC_fullgc (lua_State *L, int isemergency) {
   if (!isemergency)   /* do not run finalizers during emergency GC */
     luaC_runtilstate(L, bitmask(GCSpause));
   if (origkind == KGC_GEN) {  /* generational mode? */
-    g->gckind = GCSpause;  /* collector must be always in... */
+    g->gcstate = GCSpause;  /* collector must be always in... */
     luaC_runtilstate(L, bitmask(GCSpropagate));  /* ...propagate phase */
   }
   g->GCthreshold = (g->totalbytes/100) * g->gcpause;

+ 2 - 1
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.72 2010/03/24 13:07:01 roberto Exp roberto $
+** $Id: lstate.c,v 2.73 2010/03/25 13:06:36 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -254,6 +254,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->uvhead.u.l.prev = &g->uvhead;
   g->uvhead.u.l.next = &g->uvhead;
   g->GCthreshold = MAX_LUMEM;  /* no GC while building state */
+  g->lastmajormem = 0;
   g->strt.size = 0;
   g->strt.nuse = 0;
   g->strt.hash = NULL;

+ 8 - 7
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.55 2010/03/22 18:28:03 roberto Exp roberto $
+** $Id: lstate.h,v 2.56 2010/03/24 13:07:01 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -114,9 +114,14 @@ typedef struct CallInfo {
 ** `global state', shared by all threads of this state
 */
 typedef struct global_State {
-  stringtable strt;  /* hash table for strings */
   lua_Alloc frealloc;  /* function to reallocate memory */
   void *ud;         /* auxiliary data to `frealloc' */
+  lu_mem totalbytes;  /* number of bytes currently allocated */
+  lu_mem GCthreshold;  /* when totalbytes > GCthreshold, run GC step */
+  lu_mem lastmajormem;  /* memory in use after last major collection */
+  stringtable strt;  /* hash table for strings */
+  TValue l_registry;
+  struct Table *l_gt;  /* table of globals */
   unsigned short nCcalls;  /* number of nested C calls */
   lu_byte currentwhite;
   lu_byte gcstate;  /* state of garbage collector */
@@ -131,16 +136,12 @@ typedef struct global_State {
   GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
   GCObject *allweak;  /* list of all-weak tables */
   GCObject *tobefnz;  /* list of userdata to be GC */
+  UpVal uvhead;  /* head of double-linked list of all open upvalues */
   Mbuffer buff;  /* temporary buffer for string concatenation */
-  lu_mem GCthreshold;  /* when totalbytes > GCthreshold, run GC step */
-  lu_mem totalbytes;  /* number of bytes currently allocated */
   int gcpause;  /* size of pause between successive GCs */
   int gcstepmul;  /* GC `granularity' */
   lua_CFunction panic;  /* to be called in unprotected errors */
-  TValue l_registry;
-  struct Table *l_gt;  /* table of globals */
   struct lua_State *mainthread;
-  UpVal uvhead;  /* head of double-linked list of all open upvalues */
   const lua_Number *version;  /* pointer to version number */
   TString *envn;  /* environment variable name */
   TString *tmname[TM_N];  /* array with tag-method names */