소스 검색

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
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -265,7 +265,8 @@ static void markbeingfnz (global_State *g) {
   GCObject *o;
   GCObject *o;
   for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
   for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
     lua_assert(testbit(gch(o)->marked, SEPARATED));
     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) {
 static Udata *udata2finalize (global_State *g) {
   GCObject *o = g->tobefnz;  /* get first element */
   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;
   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;
         return GCSWEEPMAX*GCSWEEPCOST;
       }
       }
       else {
       else {
-        sweepwholelist(L, &g->tobefnz);  /* sweep 'to-be-finalized' list */
         g->sweepgc = &g->allgc;  /* go to next phase */
         g->sweepgc = &g->allgc;  /* go to next phase */
         g->gcstate = GCSsweep;
         g->gcstate = GCSsweep;
         return GCSWEEPCOST;
         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
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -412,6 +412,9 @@ int lua_checkmemory (lua_State *L) {
                testbit(o->gch.marked, SEPARATED));
                testbit(o->gch.marked, SEPARATED));
     checkobject(g, o);
     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) {
   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->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 */
     lua_assert(uv->v != &uv->u.value);  /* must be open */