فهرست منبع

change in the way 'collectgarbage("step", size)' interprets 'size'
(mimicking the way the GC itself behaves when Lua allocates 'size'
Kbytes)

Roberto Ierusalimschy 11 سال پیش
والد
کامیت
1cce3e6842
3فایلهای تغییر یافته به همراه23 افزوده شده و 24 حذف شده
  1. 15 7
      lapi.c
  2. 7 15
      lgc.c
  3. 1 2
      lgc.h

+ 15 - 7
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.194 2014/02/13 12:11:34 roberto Exp roberto $
+** $Id: lapi.c,v 2.195 2014/02/13 17:25:20 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -1070,12 +1070,20 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
       break;
     }
     case LUA_GCSTEP: {
-      lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;
-      if (g->gcrunning)
-        debt += g->GCdebt;  /* include current debt */
-      luaE_setdebt(g, debt);
-      luaC_forcestep(L);
-      if (g->gcstate == GCSpause)  /* end of cycle? */
+      l_mem debt = 1;  /* =1 to signal that it did an actual step */
+      int oldrunning = g->gcrunning;
+      g->gcrunning = 1;  /* force GC to run */
+      if (data == 0) {
+        luaE_setdebt(g, -GCSTEPSIZE);  /* to do a "small" step */
+        luaC_step(L);
+      }
+      else {  /* add 'data' to total debt */
+        debt = cast(l_mem, data) * 1024 + g->GCdebt;
+        luaE_setdebt(g, debt);
+        luaC_checkGC(L);
+      }
+      g->gcrunning = oldrunning;  /* restore previous state */
+      if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
         res = 1;  /* signal it */
       break;
     }

+ 7 - 15
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.172 2014/02/13 14:46:38 roberto Exp roberto $
+** $Id: lgc.c,v 2.173 2014/02/13 17:25:20 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -1087,11 +1087,15 @@ static l_mem getdebt (global_State *g) {
 }
 
 /*
-** performs a basic GC step
+** performs a basic GC step when collector is running
 */
-void luaC_forcestep (lua_State *L) {
+void luaC_step (lua_State *L) {
   global_State *g = G(L);
   l_mem debt = getdebt(g);
+  if (!g->gcrunning) {  /* not running? */
+    luaE_setdebt(g, -GCSTEPSIZE * 10);  /* avoid being called too often */
+    return;
+  }
   do {
     if (g->gcstate == GCScallfin && g->tobefnz) {
       unsigned int n = runafewfinalizers(L);
@@ -1112,18 +1116,6 @@ void luaC_forcestep (lua_State *L) {
 }
 
 
-/*
-** performs a basic GC step when collector is running
-*/
-void luaC_step (lua_State *L) {
-  if (!G(L)->gcrunning)
-    luaE_setdebt(G(L), -GCSTEPSIZE);  /* avoid being called too often */
-  else
-    luaC_forcestep(L);
-}
-
-
-
 /*
 ** performs a full GC cycle; if "isemergency", does not call
 ** finalizers (which could change stack positions)

+ 1 - 2
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 2.78 2014/02/13 12:11:34 roberto Exp roberto $
+** $Id: lgc.h,v 2.79 2014/02/13 14:46:38 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -126,7 +126,6 @@
 LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
 LUAI_FUNC void luaC_freeallobjects (lua_State *L);
 LUAI_FUNC void luaC_step (lua_State *L);
-LUAI_FUNC void luaC_forcestep (lua_State *L);
 LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
 LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
 LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);