Przeglądaj źródła

atomic operations are not GC "states"

Roberto Ierusalimschy 21 lat temu
rodzic
commit
beb2aa5a46
3 zmienionych plików z 61 dodań i 77 usunięć
  1. 54 68
      lgc.c
  2. 5 7
      lgc.h
  3. 2 2
      lstate.c

+ 54 - 68
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.187 2003/12/09 16:56:11 roberto Exp roberto $
+** $Id: lgc.c,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -22,7 +22,7 @@
 #include "ltm.h"
 
 
-#define GCSTEPSIZE	(20*sizeof(TValue))
+#define GCSTEPSIZE	(40*sizeof(TValue))
 
 
 #define gray2black(x)	setbit((x)->gch.marked, BLACKBIT)
@@ -104,8 +104,7 @@ static size_t objsize (GCObject *o) {
 
 
 static void reallymarkobject (global_State *g, GCObject *o) {
-  lua_assert(iswhite(o));
-  lua_assert(!isdead(g, o));
+  lua_assert(iswhite(o) && !isdead(g, o));
   white2gray(o);
   switch (o->gch.tt) {
     case LUA_TSTRING: {
@@ -348,7 +347,6 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
     lim -= objsize(o);
     if (lim <= 0) return lim;
   }
-  g->gcstate = GCSatomic;
   return lim;
 }
 
@@ -499,26 +497,22 @@ static void checkSizes (lua_State *L) {
 
 static void GCTM (lua_State *L) {
   global_State *g = G(L);
-  if (g->tmudata == NULL)
-    g->gcstate = GCSroot;  /* will restart GC */
-  else {
-    GCObject *o = g->tmudata;
-    Udata *udata = rawgco2u(o);
-    const TValue *tm;
-    g->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
-    udata->uv.next = g->firstudata->uv.next;  /* return it to `root' list */
-    g->firstudata->uv.next = o;
-    makewhite(g, o);
-    tm = fasttm(L, udata->uv.metatable, TM_GC);
-    if (tm != NULL) {
-      lu_byte oldah = L->allowhook;
-      L->allowhook = 0;  /* stop debug hooks during GC tag method */
-      setobj2s(L, L->top, tm);
-      setuvalue(L, L->top+1, udata);
-      L->top += 2;
-      luaD_call(L, L->top - 2, 0);
-      L->allowhook = oldah;  /* restore hooks */
-    }
+  GCObject *o = g->tmudata;
+  Udata *udata = rawgco2u(o);
+  const TValue *tm;
+  g->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
+  udata->uv.next = g->firstudata->uv.next;  /* return it to `root' list */
+  g->firstudata->uv.next = o;
+  makewhite(g, o);
+  tm = fasttm(L, udata->uv.metatable, TM_GC);
+  if (tm != NULL) {
+    lu_byte oldah = L->allowhook;
+    L->allowhook = 0;  /* stop debug hooks during GC tag method */
+    setobj2s(L, L->top, tm);
+    setuvalue(L, L->top+1, udata);
+    L->top += 2;
+    luaD_call(L, L->top - 2, 0);
+    L->allowhook = oldah;  /* restore hooks */
   }
 }
 
@@ -543,7 +537,7 @@ void luaC_sweepall (lua_State *L) {
 /* mark root set */
 static void markroot (lua_State *L) {
   global_State *g = G(L);
-  lua_assert(g->gray == NULL);
+  lua_assert(g->gray == NULL && g->grayagain == NULL);
   g->weak = NULL;
   makewhite(g, obj2gco(g->mainthread));
   markobject(g, g->mainthread);
@@ -555,8 +549,6 @@ static void markroot (lua_State *L) {
 
 static void atomic (lua_State *L) {
   global_State *g = G(L);
-  /* there may be some gray elements due to the write barrier */
-  propagatemarks(g, MAXLMEM);  /* traverse them */
   lua_assert(g->gray == NULL);
   g->gray = g->grayagain;
   g->grayagain = NULL;
@@ -577,60 +569,54 @@ static void atomic (lua_State *L) {
 }
 
 
-static void sweepstringstep (lua_State *L) {
-  global_State *g = G(L);
-  l_mem lim = sweepstrings(L, 0, GCSTEPSIZE);
-  if (lim == GCSTEPSIZE) {  /* nothing more to sweep? */
-    lua_assert(g->sweepstrgc > g->strt.size);
-    g->sweepstrgc = 0;
-    g->gcstate = GCSsweep;  /* end sweep-string phase */
-  }
-}
-
-
-static void sweepstep (lua_State *L) {
-  global_State *g = G(L);
-  l_mem lim = GCSTEPSIZE;
-  g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
-  if (lim == GCSTEPSIZE) {  /* nothing more to sweep? */
-    g->gcstate = GCSfinalize;  /* end sweep phase */
-    checkSizes(L);
-  }
-}
-
-
 void luaC_step (lua_State *L) {
   global_State *g = G(L);
+  l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2;
   switch (g->gcstate) {
-    case GCSroot:
-      markroot(L);
-      break;
-    case GCSpropagate:
-      propagatemarks(g, GCSTEPSIZE);
-      break;
-    case GCSatomic:
-      atomic(L);
+    case GCSpropagate: {
+      if (g->gray)
+        lim = propagatemarks(g, lim);
+      else {  /* no more `gray' objects */
+        atomic(L);  /* finish mark phase */
+        lim = 0;
+      }
       break;
-    case GCSsweepstring:
-      sweepstringstep(L);
+    }
+    case GCSsweepstring: {
+      lim = sweepstrings(L, 0, lim);
+      if (g->sweepstrgc >= g->strt.size) {  /* nothing more to sweep? */
+        g->sweepstrgc = 0;
+        g->gcstate = GCSsweep;  /* end sweep-string phase */
+      }
       break;
-    case GCSsweep:
-      sweepstep(L);
+    }
+    case GCSsweep: {
+      g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
+      if (*g->sweepgc == NULL) {  /* nothing more to sweep? */
+        g->gcstate = GCSfinalize;  /* end sweep phase */
+        checkSizes(L);
+      }
       break;
-    case GCSfinalize:
-      GCTM(L);
+    }
+    case GCSfinalize: {
+      if (g->tmudata) {
+        GCTM(L);
+        lim = 0;
+      }
+      else  /* no more `udata' to finalize */
+        markroot(L);  /* may restart collection */
       break;
+    }
     default: lua_assert(0);
   }
-  g->GCthreshold = g->nblocks + GCSTEPSIZE;
+  g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2;
 }
 
 
 void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
   global_State *g = G(L);
-  lua_assert(isblack(o) && iswhite(v));
-  lua_assert(!isdead(g, v) && !isdead(g, o));
-  if (g->gcstate > GCSatomic)  /* sweeping phases? */
+  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
+  if (g->gcstate >= GCSsweepstring)  /* sweeping phases? */
     black2gray(o);  /* just mark as gray to avoid other barriers */
   else  /* breaking invariant! */
     reallymarkobject(g, v);  /* restore it */

+ 5 - 7
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 1.28 2003/12/09 16:56:11 roberto Exp roberto $
+** $Id: lgc.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -14,12 +14,10 @@
 /*
 ** Possible states of the Garbage Collector
 */
-#define GCSroot		0
-#define GCSpropagate	1
-#define GCSatomic	2
-#define GCSsweepstring	3
-#define GCSsweep	4
-#define GCSfinalize	5
+#define GCSpropagate	0
+#define GCSsweepstring	1
+#define GCSsweep	2
+#define GCSfinalize	3
 
 
 /*

+ 2 - 2
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.134 2003/12/04 18:52:23 roberto Exp roberto $
+** $Id: lstate.c,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -167,7 +167,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   setnilvalue(registry(L));
   luaZ_initbuffer(L, &g->buff);
   g->panic = NULL;
-  g->gcstate = 0;
+  g->gcstate = GCSfinalize;
   g->rootgc = NULL;
   g->sweepstrgc = 0;
   g->currentwhite = bitmask(WHITE0BIT);