فهرست منبع

`grayagain' list

Roberto Ierusalimschy 21 سال پیش
والد
کامیت
fe595a45c2
3فایلهای تغییر یافته به همراه19 افزوده شده و 3 حذف شده
  1. 15 1
      lgc.c
  2. 2 1
      lstate.c
  3. 2 1
      lstate.h

+ 15 - 1
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 1.184 2003/12/03 20:03:07 roberto Exp roberto $
+** $Id: lgc.c,v 1.185 2003/12/04 17:22:42 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -38,6 +38,7 @@
 
 
 #define isgray(x)	(!isblack(x) && !iswhite(x))
 #define isgray(x)	(!isblack(x) && !iswhite(x))
 #define white2gray(x)	reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
 #define white2gray(x)	reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
+#define black2gray(x)	resetbit((x)->gch.marked, BLACKBIT)
 
 
 #define stringmark(s)	reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
 #define stringmark(s)	reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
 
 
@@ -323,6 +324,9 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
       case LUA_TTHREAD: {
       case LUA_TTHREAD: {
         lua_State *th = gcototh(o);
         lua_State *th = gcototh(o);
         g->gray = th->gclist;
         g->gray = th->gclist;
+        th->gclist = g->grayagain;
+        g->grayagain = o;
+        black2gray(o);
         traversestack(g, th);
         traversestack(g, th);
         break;
         break;
       }
       }
@@ -335,6 +339,11 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
       case LUA_TUPVAL: {
       case LUA_TUPVAL: {
         UpVal *uv = gcotouv(o);
         UpVal *uv = gcotouv(o);
         g->gray = uv->gclist;
         g->gray = uv->gclist;
+        if (uv->v != &uv->value) {  /* open? */
+          uv->gclist = g->grayagain;
+          g->grayagain = o;
+          black2gray(o);
+        }
         markvalue(g, &uv->value);
         markvalue(g, &uv->value);
         break;
         break;
       }
       }
@@ -553,6 +562,10 @@ static void markroot (lua_State *L) {
 
 
 static void atomic (lua_State *L) {
 static void atomic (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
+  lua_assert(g->gray == NULL);
+  g->gray = g->grayagain;
+  g->grayagain = NULL;
+  propagatemarks(g, MAXLMEM);
   g->GCthreshold = luaC_separateudata(L);  /* separate userdata to be preserved */
   g->GCthreshold = luaC_separateudata(L);  /* separate userdata to be preserved */
   marktmu(g);  /* mark `preserved' userdata */
   marktmu(g);  /* mark `preserved' userdata */
   propagatemarks(g, MAXLMEM);  /* remark, to propagate `preserveness' */
   propagatemarks(g, MAXLMEM);  /* remark, to propagate `preserveness' */
@@ -565,6 +578,7 @@ static void atomic (lua_State *L) {
   g->sweepgc = &g->rootgc->gch.next;
   g->sweepgc = &g->rootgc->gch.next;
   g->sweepstrgc = 0;
   g->sweepstrgc = 0;
   g->gcstate = GCSsweepstring;
   g->gcstate = GCSsweepstring;
+  g->grayagain = NULL;
 }
 }
 
 
 
 

+ 2 - 1
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 1.132 2003/12/03 20:03:07 roberto Exp roberto $
+** $Id: lstate.c,v 1.133 2003/12/04 17:22:42 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -172,6 +172,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->currentwhite = bitmask(WHITE0BIT);
   g->currentwhite = bitmask(WHITE0BIT);
   g->firstudata = NULL;
   g->firstudata = NULL;
   g->gray = NULL;
   g->gray = NULL;
+  g->grayagain = NULL;
   g->weak = NULL;
   g->weak = NULL;
   g->tmudata = NULL;
   g->tmudata = NULL;
   setnilvalue(gkey(g->dummynode));
   setnilvalue(gkey(g->dummynode));

+ 2 - 1
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 1.117 2003/12/03 20:03:07 roberto Exp roberto $
+** $Id: lstate.h,v 1.118 2003/12/04 17:22:42 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -103,6 +103,7 @@ typedef struct global_State {
   GCObject **sweepgc;  /* position of sweep in `rootgc' */
   GCObject **sweepgc;  /* position of sweep in `rootgc' */
   int sweepstrgc;  /* position of sweep in `strt' */
   int sweepstrgc;  /* position of sweep in `strt' */
   GCObject *gray;  /* list of gray objects */
   GCObject *gray;  /* list of gray objects */
+  GCObject *grayagain;  /* list of objects to be traversed atomically */
   GCObject *weak;  /* list of weak tables (to be cleared) */
   GCObject *weak;  /* list of weak tables (to be cleared) */
   GCObject *tmudata;  /* list of userdata to be GC */
   GCObject *tmudata;  /* list of userdata to be GC */
   int gcstate;  /* state of garbage collector */
   int gcstate;  /* state of garbage collector */