Browse Source

GC bits SEPARATED and FINALIZEDBIT mixed in FINALIZEDBIT (with simpler
control)

Roberto Ierusalimschy 12 years ago
parent
commit
8f6b80aa1d
4 changed files with 20 additions and 25 deletions
  1. 7 12
      lgc.c
  2. 5 5
      lgc.h
  3. 4 4
      lstate.h
  4. 4 4
      ltests.c

+ 7 - 12
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.146 2013/08/16 18:55:49 roberto Exp roberto $
+** $Id: lgc.c,v 2.147 2013/08/19 14:18:43 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -65,8 +65,6 @@
 
 #define valiswhite(x)   (iscollectable(x) && iswhite(gcvalue(x)))
 
-#define isfinalized(x)		testbit(gch(x)->marked, FINALIZEDBIT)
-
 #define checkdeadkey(n)	lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
 
 
@@ -764,11 +762,11 @@ static void checkSizes (lua_State *L) {
 
 static GCObject *udata2finalize (global_State *g) {
   GCObject *o = g->tobefnz;  /* get first element */
-  lua_assert(isfinalized(o));
+  lua_assert(tofinalize(o));
   g->tobefnz = gch(o)->next;  /* remove it from 'tobefnz' list */
   gch(o)->next = g->allgc;  /* return it to 'allgc' list */
   g->allgc = o;
-  resetbit(gch(o)->marked, SEPARATED);  /* mark that it is not in 'tobefnz' */
+  resetbit(gch(o)->marked, FINALIZEDBIT);  /* object is back in 'allgc' */
   if (!keepinvariant(g))  /* not keeping invariant? */
     makewhite(g, o);  /* "sweep" object */
   return o;
@@ -826,12 +824,10 @@ static void separatetobefnz (lua_State *L, int all) {
   while (*lastnext != NULL)
     lastnext = &gch(*lastnext)->next;
   while ((curr = *p) != NULL) {  /* traverse all finalizable objects */
-    lua_assert(!isfinalized(curr));
-    lua_assert(testbit(gch(curr)->marked, SEPARATED));
+    lua_assert(tofinalize(curr));
     if (!(iswhite(curr) || all))  /* not being collected? */
       p = &gch(curr)->next;  /* don't bother with it */
     else {
-      l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
       *p = gch(curr)->next;  /* remove 'curr' from 'finobj' list */
       gch(curr)->next = *lastnext;  /* link at the end of 'tobefnz' list */
       *lastnext = curr;
@@ -847,9 +843,8 @@ static void separatetobefnz (lua_State *L, int all) {
 */
 void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
   global_State *g = G(L);
-  if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */
-      isfinalized(o) ||                           /* ... or is finalized... */
-      gfasttm(g, mt, TM_GC) == NULL)                /* or has no finalizer? */
+  if (tofinalize(o) ||                 /* obj. is already marked... */
+      gfasttm(g, mt, TM_GC) == NULL)   /* or has no finalizer? */
     return;  /* nothing to be done */
   else {  /* move 'o' to 'finobj' list */
     GCObject **p;
@@ -863,7 +858,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
     *p = ho->next;  /* remove 'o' from root list */
     ho->next = g->finobj;  /* link it in list 'finobj' */
     g->finobj = o;
-    l_setbit(ho->marked, SEPARATED);  /* mark it as such */
+    l_setbit(ho->marked, FINALIZEDBIT);  /* mark it as such */
     if (!keepinvariant(g))  /* not keeping invariant? */
       makewhite(g, o);  /* "sweep" object */
   }

+ 5 - 5
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 2.61 2013/08/16 18:55:49 roberto Exp roberto $
+** $Id: lgc.h,v 2.62 2013/08/19 14:18:43 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -76,10 +76,9 @@
 #define WHITE0BIT	0  /* object is white (type 0) */
 #define WHITE1BIT	1  /* object is white (type 1) */
 #define BLACKBIT	2  /* object is black */
-#define FINALIZEDBIT	3  /* object has been separated for finalization */
-#define SEPARATED	4  /* object is in 'finobj' list or in 'tobefnz' */
-#define FIXEDBIT	5  /* object is fixed (should not be collected) */
-#define LOCALBIT	6  /* object is not local */
+#define FINALIZEDBIT	3  /* object has been marked for finalization */
+#define FIXEDBIT	4  /* object is fixed (should not be collected) */
+#define LOCALBIT	5  /* object is not local */
 /* bit 7 is currently used by tests (luaL_checkmemory) */
 
 #define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
@@ -91,6 +90,7 @@
 	(!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
 #define islocal(x)	(!testbit((x)->gch.marked, LOCALBIT))
 
+#define tofinalize(x)	testbit((x)->gch.marked, FINALIZEDBIT)
 
 #define otherwhite(g)	(g->currentwhite ^ WHITEBITS)
 #define isdeadm(ow,m)	(!(((m) ^ WHITEBITS) & (ow)))

+ 4 - 4
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.83 2013/08/05 16:58:28 roberto Exp roberto $
+** $Id: lstate.h,v 2.84 2013/08/07 12:18:11 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -33,9 +33,9 @@
 ** threads, but the thread may already be dead, while the upvalue is
 ** still accessible through closures.)
 **
-** Objects with finalizers are kept in the list g->finobj.
-**
-** The list g->tobefnz links all objects being finalized.
+** Live objects with finalizers are kept in the list g->finobj. The
+** list g->tobefnz links all objects being finalized. In particular, an
+** object has its FINALIZEDBIT set iff it is in one of these lists.
 
 */
 

+ 4 - 4
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.144 2013/08/18 16:12:18 roberto Exp roberto $
+** $Id: ltests.c,v 2.145 2013/08/19 14:16:33 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -466,12 +466,12 @@ int lua_checkmemory (lua_State *L) {
     if (gch(o)->tt == LUA_TTHREAD) isthread = 1;  /* now travesing threads... */
     else lua_assert(!isthread);  /* ... and only threads */
     checkobject(g, o, maybedead);
-    lua_assert(!testbit(o->gch.marked, SEPARATED));
+    lua_assert(!tofinalize(o));
   }
   /* check 'finobj' list */
   checkgray(g, g->finobj);
   for (o = g->finobj; o != NULL; o = gch(o)->next) {
-    lua_assert(testbit(o->gch.marked, SEPARATED));
+    lua_assert(tofinalize(o));
     lua_assert(gch(o)->tt == LUA_TUSERDATA ||
                gch(o)->tt == LUA_TTABLE);
     checkobject(g, o, 0);
@@ -480,7 +480,7 @@ int lua_checkmemory (lua_State *L) {
   checkgray(g, g->tobefnz);
   for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
     lua_assert(!iswhite(o) || g->gcstate == GCSpause);
-    lua_assert(!isdead(g, o) && testbit(o->gch.marked, SEPARATED));
+    lua_assert(!isdead(g, o) && tofinalize(o));
     lua_assert(gch(o)->tt == LUA_TUSERDATA ||
                gch(o)->tt == LUA_TTABLE);
   }