Ver código fonte

less conservative write barrier for tables

Roberto Ierusalimschy 21 anos atrás
pai
commit
26ae992129
5 arquivos alterados com 38 adições e 18 exclusões
  1. 3 3
      lapi.c
  2. 25 9
      lgc.c
  3. 5 1
      lgc.h
  4. 2 2
      ltable.c
  5. 3 3
      lvm.c

+ 3 - 3
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.13 2004/06/30 14:15:23 roberto Exp roberto $
+** $Id: lapi.c,v 2.14 2004/07/09 14:20:22 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -613,7 +613,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
   t = luaA_index(L, idx);
   api_check(L, ttistable(t));
   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
-  luaC_barrier(L, hvalue(t), L->top-1);
+  luaC_barriert(L, hvalue(t), L->top-1);
   L->top -= 2;
   lua_unlock(L);
 }
@@ -626,7 +626,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
   o = luaA_index(L, idx);
   api_check(L, ttistable(o));
   setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
-  luaC_barrier(L, hvalue(o), L->top-1);
+  luaC_barriert(L, hvalue(o), L->top-1);
   L->top--;
   lua_unlock(L);
 }

+ 25 - 9
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.6 2004/03/23 12:57:12 roberto Exp roberto $
+** $Id: lgc.c,v 2.7 2004/04/30 20:13:38 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -24,9 +24,11 @@
 
 
 #define GCSTEPSIZE	(40*sizeof(TValue))
-#define GCFREECOST	(sizeof(TValue)/2)
-#define GCSWEEPCOST	sizeof(TValue)
+#define STEPMUL		2
+#define GCFREECOST	(sizeof(TValue)/10)
+#define GCSWEEPCOST	(sizeof(TValue)/20)
 #define GCFINALIZECOST	(10*sizeof(TValue))
+#define WAITNEXTCYCLE	(10 * GCSTEPSIZE)
 
 
 #define FIXEDMASK	bitmask(FIXEDBIT)
@@ -531,8 +533,10 @@ static void remarkupvals (global_State *g) {
     if (iswhite(o)) {
       GCObject *curr;
       for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) {
-        if (isgray(curr))
-          markvalue(g, gco2uv(curr)->v);
+        if (isgray(curr)) {
+          UpVal *uv = gco2uv(curr);
+          markvalue(g, uv->v);
+        }
       }
     }
   }
@@ -612,14 +616,16 @@ static l_mem singlestep (lua_State *L, l_mem lim) {
 
 void luaC_step (lua_State *L) {
   global_State *g = G(L);
-  l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2;
+  l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * STEPMUL;
   do {
     lim = singlestep(L, lim);
-    if (g->gcstate == GCSfinalize && g->tmudata == NULL)
+    if (g->gcstate == GCSfinalize && g->tmudata == NULL) {
+      lim = -WAITNEXTCYCLE;
       break;  /* do not start new collection */
+    }
   } while (lim > 0);
-  g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2;
-  lua_assert((long)g->nblocks + (long)GCSTEPSIZE >= lim/2);
+  g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/STEPMUL;
+  lua_assert((long)g->nblocks + (long)GCSTEPSIZE >= lim/STEPMUL);
 }
 
 
@@ -648,6 +654,16 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
 }
 
 
+void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) {
+  global_State *g = G(L);
+  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
+  lua_assert(g->gcstate != GCSfinalize);
+  black2gray(o);  /* make table gray (again) */
+  gco2h(o)->gclist = g->grayagain;
+  g->grayagain = o;
+}
+
+
 void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
   global_State *g = G(L);
   o->gch.next = g->rootgc;

+ 5 - 1
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 2.4 2004/03/09 17:34:35 roberto Exp roberto $
+** $Id: lgc.h,v 2.5 2004/03/15 21:04:33 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -77,6 +77,9 @@
 #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p)))  \
 	luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
 
+#define luaC_barriert(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p)))  \
+	luaC_barrierback(L,obj2gco(p),gcvalue(v)); }
+
 #define luaC_objbarrier(L,p,o)  \
 	{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
 		luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
@@ -89,6 +92,7 @@ void luaC_fullgc (lua_State *L);
 void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
 void luaC_linkupval (lua_State *L, UpVal *uv);
 void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
+void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v);
 
 
 #endif

+ 2 - 2
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 2.2 2004/03/26 14:02:41 roberto Exp roberto $
+** $Id: ltable.c,v 2.3 2004/04/30 20:13:38 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -375,7 +375,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
     }
   }
   setobj2t(L, gkey(mp), key);
-  luaC_barrier(L, t, key);
+  luaC_barriert(L, t, key);
   lua_assert(ttisnil(gval(mp)));
   for (;;) {  /* correct `firstfree' */
     if (ttisnil(gkey(t->firstfree)))

+ 3 - 3
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.10 2004/06/29 17:05:00 roberto Exp roberto $
+** $Id: lvm.c,v 2.11 2004/06/29 18:49:02 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -150,7 +150,7 @@ StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
       if (!ttisnil(oldval) ||  /* result is no nil? */
           (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
         setobj2t(L, oldval, val);
-        luaC_barrier(L, h, val);
+        luaC_barriert(L, h, val);
         return L->base;
       }
       /* else will try the tag method */
@@ -729,7 +729,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         for (; n > 0; n--) {
           TValue *val = ra+n;
           setobj2t(L, luaH_setnum(L, h, last--), val);
-          luaC_barrier(L, h, val);
+          luaC_barriert(L, h, val);
         }
         continue;
       }