2
0
Эх сурвалжийг харах

Simplification in handling of GC debt

Each incremental step has always the same size (stepsize), and the
debt for next step also is always the same.
Roberto Ierusalimschy 2 жил өмнө
parent
commit
0270c204c2
2 өөрчлөгдсөн 22 нэмэгдсэн , 20 устгасан
  1. 17 13
      lapi.c
  2. 5 7
      lgc.c

+ 17 - 13
lapi.c

@@ -1145,7 +1145,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
     }
     case LUA_GCRESTART: {
       luaE_setdebt(g, 0);
-      g->gcstp = 0;  /* (GCSTPGC must be already zero here) */
+      g->gcstp = 0;  /* (bit GCSTPGC must be zero here) */
       break;
     }
     case LUA_GCCOLLECT: {
@@ -1162,21 +1162,25 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
       break;
     }
     case LUA_GCSTEP: {
-      int data = va_arg(argp, int);
-      l_obj debt = 1;  /* =1 to signal that it did an actual step */
+      int todo = va_arg(argp, int);  /* work to be done */
+      int didsomething = 0;
       lu_byte oldstp = g->gcstp;
-      g->gcstp = 0;  /* allow GC to run (GCSTPGC must be zero here) */
-      if (data == 0) {
-        luaE_setdebt(g, 0);  /* do a basic step */
-        luaC_step(L);
-      }
-      else {  /* add 'data' to total debt */
-        debt = data + g->GCdebt;
-        luaE_setdebt(g, debt);
-        luaC_checkGC(L);
+      g->gcstp = 0;  /* allow GC to run (bit GCSTPGC must be zero here) */
+      if (todo == 0)
+        todo = 1 << g->gcstepsize;  /* standard step size */
+      while (todo + g->GCdebt > 0) {  /* enough to run a step? */
+        todo += g->GCdebt;  /* decrement 'todo' (debt is usually negative) */
+        luaC_step(L);  /* run one basic step */
+        didsomething = 1;
+        if (g->gckind == KGC_GEN)  /* minor collections? */
+          todo = 0;  /* doesn't make sense to repeat in this case */
+        else if (g->gcstate == GCSpause)
+          break;  /* don't run more than one cycle */
       }
+      /* add remaining 'todo' to total debt */
+      luaE_setdebt(g, todo + g->GCdebt);
       g->gcstp = oldstp;  /* restore previous state */
-      if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
+      if (didsomething && g->gcstate == GCSpause)  /* end of cycle? */
         res = 1;  /* signal it */
       break;
     }

+ 5 - 7
lgc.c

@@ -1037,7 +1037,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
 */
 static void setpause (global_State *g) {
   unsigned int pause = getgcparam(g->gcpause);
-  lu_mem threshold = g->marked / 8 * pause / 12;
+  l_obj threshold = g->marked / 8 * pause / 12;
   l_obj debt = gettotalobjs(g) - threshold;
   if (debt > 0) debt = 0;
   luaE_setdebt(g, debt);
@@ -1600,18 +1600,16 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
 ** controls when next step will be performed.
 */
 static void incstep (lua_State *L, global_State *g) {
-  int stepmul = (getgcparam(g->gcstepmul) | 1);  /* avoid division by 0 */
-  l_obj debt = (g->GCdebt / 100) * stepmul;
   l_obj stepsize = cast(l_obj, 1) << g->gcstepsize;
+  l_obj work2do = stepsize * getgcparam(g->gcstepmul) / 100;
   do {  /* repeat until pause or enough "credit" (negative debt) */
     l_obj work = singlestep(L);  /* perform one single step */
-    debt -= work;
-  } while (debt > -stepsize && g->gcstate != GCSpause);
+    work2do -= work;
+  } while (work2do > 0 && g->gcstate != GCSpause);
   if (g->gcstate == GCSpause)
     setpause(g);  /* pause until next cycle */
   else {
-    debt = (debt / stepmul) * 100;  /* apply step multiplier */
-    luaE_setdebt(g, debt);
+    luaE_setdebt(g, -stepsize);
   }
 }