瀏覽代碼

items in 'tobefnz' are kept black (as before recent change) and changed
to white only when needed (being moved to 'allgc' when not keeping
invariant).

Roberto Ierusalimschy 15 年之前
父節點
當前提交
d25f7f9d78
共有 2 個文件被更改,包括 15 次插入9 次删除
  1. 11 8
      lgc.c
  2. 4 1
      ltests.c

+ 11 - 8
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.82 2010/04/29 21:43:36 roberto Exp roberto $
+** $Id: lgc.c,v 2.83 2010/04/30 18:37:14 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -265,7 +265,8 @@ static void markbeingfnz (global_State *g) {
   GCObject *o;
   for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
     lua_assert(testbit(gch(o)->marked, SEPARATED));
-    markobject(g, o);
+    makewhite(g, o);
+    reallymarkobject(g, o);
   }
 }
 
@@ -651,12 +652,15 @@ static void checkSizes (lua_State *L) {
 
 static Udata *udata2finalize (global_State *g) {
   GCObject *o = g->tobefnz;  /* get first element */
-  g->tobefnz = gch(o)->next;  /* remove it from 'tobefnz' list */
-  gch(o)->next = g->allgc;  /* return it to 'allgc' list */
+  Udata *u = rawgco2u(o);
+  lua_assert(isfinalized(&u->uv));
+  g->tobefnz = u->uv.next;  /* remove it from 'tobefnz' list */
+  u->uv.next = g->allgc;  /* return it to 'allgc' list */
   g->allgc = o;
-  lua_assert(isfinalized(gch(o)));
-  resetbit(gch(o)->marked, SEPARATED);  /* mark it as such */
-  return rawgco2u(o);
+  resetbit(u->uv.marked, SEPARATED);  /* mark that it is not in 'tobefnz' */
+  if (!keepinvariant(g))  /* not keeping invariant? */
+    makewhite(g, o);  /* "sweep" object */
+  return u;
 }
 
 
@@ -833,7 +837,6 @@ static l_mem singlestep (lua_State *L) {
         return GCSWEEPMAX*GCSWEEPCOST;
       }
       else {
-        sweepwholelist(L, &g->tobefnz);  /* sweep 'to-be-finalized' list */
         g->sweepgc = &g->allgc;  /* go to next phase */
         g->gcstate = GCSsweep;
         return GCSWEEPCOST;

+ 4 - 1
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.98 2010/04/29 21:42:33 roberto Exp roberto $
+** $Id: ltests.c,v 2.99 2010/04/30 18:37:14 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -412,6 +412,9 @@ int lua_checkmemory (lua_State *L) {
                testbit(o->gch.marked, SEPARATED));
     checkobject(g, o);
   }
+  for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
+    lua_assert(gch(o)->tt == LUA_TUSERDATA && isblack(o));
+  }
   for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
     lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
     lua_assert(uv->v != &uv->u.value);  /* must be open */