Przeglądaj źródła

no more local collection

Roberto Ierusalimschy 11 lat temu
rodzic
commit
733c58595b
10 zmienionych plików z 69 dodań i 263 usunięć
  1. 1 8
      lapi.c
  2. 3 3
      lbaselib.c
  3. 1 2
      lfunc.c
  4. 27 157
      lgc.c
  5. 11 20
      lgc.h
  6. 4 14
      lstate.c
  7. 2 6
      lstate.h
  8. 18 49
      ltests.c
  9. 1 2
      lua.h
  10. 1 2
      lundump.c

+ 1 - 8
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.192 2013/12/30 20:47:58 roberto Exp roberto $
+** $Id: lapi.c,v 2.193 2014/01/27 13:34:32 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -589,7 +589,6 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     while (n--) {
       setobj2n(L, &cl->c.upvalue[n], L->top + n);
       /* does not need barrier because closure is white */
-      valnolocal(L->top + n);  /* but needs 'local barrier' */
     }
     setclCvalue(L, L->top, cl);
   }
@@ -864,7 +863,6 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
     }
     default: {
       G(L)->mt[ttnov(obj)] = mt;
-      if (mt) nolocal(obj2gco(mt));
       break;
     }
   }
@@ -1086,11 +1084,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
       g->gcpause = data;
       break;
     }
-    case LUA_GCSETLOCALPAUSE: {
-      res = g->gclocalpause;
-      g->gclocalpause = data;
-      break;
-    }
     case LUA_GCSETSTEPMUL: {
       res = g->gcstepmul;
       g->gcstepmul = data;

+ 3 - 3
lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.281 2013/08/05 16:58:28 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.282 2013/09/13 16:21:52 roberto Exp roberto $
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -175,10 +175,10 @@ static int luaB_rawset (lua_State *L) {
 static int luaB_collectgarbage (lua_State *L) {
   static const char *const opts[] = {"stop", "restart", "collect",
     "count", "step", "setpause", "setstepmul",
-    "setlocalpause", "isrunning", NULL};
+    "isrunning", NULL};
   static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
     LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
-    LUA_GCSETLOCALPAUSE, LUA_GCISRUNNING};
+    LUA_GCISRUNNING};
   int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
   int ex = luaL_optint(L, 2, 0);
   int res = lua_gc(L, o, ex);

+ 1 - 2
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 2.37 2013/08/27 20:04:00 roberto Exp roberto $
+** $Id: lfunc.c,v 2.38 2013/09/11 12:26:14 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -86,7 +86,6 @@ void luaF_close (lua_State *L, StkId level) {
 
 Proto *luaF_newproto (lua_State *L) {
   Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto))->p;
-  nolocal(obj2gco(f));  /* prototypes are never local */
   f->k = NULL;
   f->sizek = 0;
   f->p = NULL;

+ 27 - 157
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.169 2014/02/11 12:18:12 roberto Exp roberto $
+** $Id: lgc.c,v 2.170 2014/02/11 12:28:47 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -72,18 +72,11 @@
   lua_longassert(!iscollectable(obj) || righttt(obj))
 
 
-#define marklocalvalue(g,o) { checkconsistency(o); \
+#define markvalue(g,o) { checkconsistency(o); \
   if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
 
-#define markvalue(g,o) {  \
-  lua_longassert(!(iscollectable(o) && islocal(gcvalue(o)))); \
-  marklocalvalue(g,o); }
-
-#define marklocalobject(g,t) \
-  { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
-
 #define markobject(g,t) \
-  { lua_assert((t) == NULL || !islocal(obj2gco(t))); marklocalobject(g,t); }
+  { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
 
 static void reallymarkobject (global_State *g, GCObject *o);
 
@@ -178,7 +171,6 @@ LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
   global_State *g = G(L);
   GCObject *o = gcvalue(uv->v);
   lua_assert(!upisopen(uv));  /* ensured by macro luaC_upvalbarrier */
-  nolocal(o);
   if (keepinvariant(g))
     markobject(g, o);
 }
@@ -186,9 +178,9 @@ LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
 
 void luaC_fix (lua_State *L, GCObject *o) {
   global_State *g = G(L);
-  lua_assert(g->localgc == o);
-  white2gray(o);
-  g->localgc = o->gch.next;  /* remove object from 'localgc' list */
+  lua_assert(g->allgc == o);  /* object must be 1st in 'allgc' list! */
+  white2gray(o);  /* they will be gray forever */
+  g->allgc = o->gch.next;  /* remove object from 'allgc' list */
   o->gch.next = g->fixedgc;  /* link it to 'fixedgc' list */
   g->fixedgc = o;
 }
@@ -196,15 +188,15 @@ void luaC_fix (lua_State *L, GCObject *o) {
 
 /*
 ** create a new collectable object (with given type and size) and link
-** it to 'localgc' list.
+** it to 'allgc' list.
 */
 GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
   global_State *g = G(L);
   GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
   gch(o)->marked = luaC_white(g);
   gch(o)->tt = tt;
-  gch(o)->next = g->localgc;
-  g->localgc = o;
+  gch(o)->next = g->allgc;
+  g->allgc = o;
   return o;
 }
 
@@ -289,7 +281,7 @@ static void markmt (global_State *g) {
 static void markbeingfnz (global_State *g) {
   GCObject *o;
   for (o = g->tobefnz; o != NULL; o = gch(o)->next)
-    marklocalobject(g, o);
+    markobject(g, o);
 }
 
 
@@ -306,7 +298,7 @@ static void remarkupvals (global_State *g) {
       UpVal *uv = gco2th(thread)->openupval;
       for (; uv != NULL; uv = uv->u.op.next) {
         if (uv->u.op.touched) {
-          marklocalvalue(g, uv->v);  /* remark upvalue's value */
+          markvalue(g, uv->v);  /* remark upvalue's value */
           uv->u.op.touched = 0;
         }
       }
@@ -463,7 +455,7 @@ static int traverseproto (global_State *g, Proto *f) {
 static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
   int i;
   for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
-    marklocalvalue(g, &cl->upvalue[i]);
+    markvalue(g, &cl->upvalue[i]);
   return sizeCclosure(cl->nupvalues);
 }
 
@@ -489,7 +481,7 @@ static lu_mem traversestack (global_State *g, lua_State *th) {
   if (o == NULL)
     return 1;  /* stack not completely built yet */
   for (; o < th->top; o++)  /* mark live elements in the stack */
-    marklocalvalue(g, o);
+    markvalue(g, o);
   if (g->gcstate == GCSatomic) {  /* final traversal? */
     StkId lim = th->stack + th->stacksize;  /* real end of stack */
     for (; o < lim; o++)  /* clear not-marked stack slice */
@@ -769,16 +761,8 @@ static GCObject *udata2finalize (global_State *g) {
   GCObject *o = g->tobefnz;  /* get first element */
   lua_assert(tofinalize(o));
   g->tobefnz = gch(o)->next;  /* remove it from 'tobefnz' list */
-  if (islocal(o)) {
-    gch(o)->next = g->localgc;  /* return it to 'localgc' list */
-    g->localgc = o;
-    resetbit(gch(o)->marked, LOCALMARK);
-  }
-  else {  /* return it to 'allgc' list */
-    gch(o)->next = g->allgc;
-    g->allgc = o;
-    l_setbit(gch(o)->marked, LOCALMARK);
-  }
+  gch(o)->next = g->allgc;  /* return it to 'allgc' list */
+  g->allgc = o;
   resetbit(gch(o)->marked, FINALIZEDBIT);  /* object is "normal" again */
   if (issweepphase(g))
     makewhite(g, o);  /* "sweep" object */
@@ -882,8 +866,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
       g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
     }
     /* search for pointer pointing to 'o' */
-    p = (testbit(o->gch.marked, LOCALMARK)) ? &g->allgc : &g->localgc;
-    for (; *p != o; p = &gch(*p)->next) { /* empty */ }
+    for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
     *p = o->gch.next;  /* remove 'o' from its list */
     o->gch.next = g->finobj;  /* link it in "fin" list */
     g->finobj = o;
@@ -896,105 +879,6 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
 /* }====================================================== */
 
 
-/*
-** {======================================================
-** Local Collection
-** =======================================================
-*/
-
-
-/*
-** Traverse a thread, local marking all its collectable objects
-*/
-static void localmarkthread (lua_State *l) {
-  StkId o = l->stack;
-  StkId lim = l->stack + l->stacksize;  /* real end of stack */
-  if (o == NULL)
-    return;  /* stack not completely built yet */
-  for (; o < l->top; o++) {  /* mark live elements in the stack */
-    if (iscollectable(o))
-      l_setbit(gcvalue(o)->gch.marked, LOCALMARK);
-  }
-  for (; o < lim; o++)  /* clear not-marked stack slice */
-    setnilvalue(o);
-}
-
-
-/*
-** Mark all that is locally accessible (accessible directly from
-** a thread)
-*/
-static void localmark (global_State *g) {
-  GCObject *thread = obj2gco(g->mainthread);
-  for (; thread != NULL; thread = gch(thread)->next)  /* traverse all threads */
-    localmarkthread(gco2th(thread));
-}
-
-
-static void localsweep (lua_State *L, global_State *g) {
-  GCObject **p = &g->localgc;
-  while (*p != NULL) {
-    GCObject *curr = *p;
-    if (!islocal(curr)) {  /* is 'curr' no more local? */
-      *p = curr->gch.next;  /* remove 'curr' from list */
-      curr->gch.next = g->allgc;  /* link 'curr' in 'allgc' list */
-      g->allgc = curr;
-      /* mark it as out of local list */
-      l_setbit(curr->gch.marked, LOCALMARK);
-    }
-    else {  /* still local */
-      if (testbit(curr->gch.marked, LOCALMARK)) {  /* locally alive? */
-        resetbit(curr->gch.marked, LOCALMARK);
-        p = &curr->gch.next;  /* go to next element */
-      }
-      else {  /* object is dead */
-        if (curr->gch.tt == LUA_TLCL) {  /* is it a Lua closure? */
-          if (gco2lcl(curr)->p->cache == gco2cl(curr))
-            gco2lcl(curr)->p->cache = NULL;  /* clear cache */
-        }
-        *p = curr->gch.next;  /* remove 'curr' from list */
-        freeobj(L, curr);  /* erase 'curr' */
-      }
-    }
-  }
-}
-
-
-static void separatelocal (global_State *g) {
-  GCObject **p = &g->finobj;
-  GCObject **lastnext = findlast(&g->tobefnz);
-  while (*p != NULL) {
-    GCObject *curr = *p;
-    if (!islocal(curr))  /* is 'curr' no more local? */
-      p = &curr->gch.next;  /* go to next element */
-    else {  /* still local */
-      if (testbit(curr->gch.marked, LOCALMARK)) {  /* locally alive? */
-        resetbit(curr->gch.marked, LOCALMARK);
-        p = &curr->gch.next;  /* go to next element */
-      }
-      else {  /* object is "dead" */
-        *p = curr->gch.next;  /* remove 'curr' from list */
-        curr->gch.next = *lastnext;  /* link at the end of 'tobefnz' list */
-        *lastnext = curr;
-        lastnext = &curr->gch.next;
-      }
-    }
-  }
-}
-
-
-static void luaC_localcollection (lua_State *L) {
-  global_State *g = G(L);
-  lua_assert(g->gcstate == GCSpause);
-  localmark(g);
-  localsweep(L, g);
-  separatelocal(g);
-  callallpendingfinalizers(L, 1);
-}
-
-/* }====================================================== */
-
-
 
 /*
 ** {======================================================
@@ -1008,13 +892,13 @@ static void luaC_localcollection (lua_State *L) {
 ** cycle will start when memory use hits threshold
 */
 static void setpause (global_State *g, l_mem estimate) {
-  l_mem threshold;
+  l_mem threshold, debt;
   estimate = estimate / PAUSEADJ;  /* adjust 'estimate' */
   threshold = (g->gcpause < MAX_LMEM / estimate)  /* overflow? */
             ? estimate * g->gcpause  /* no overflow */
             : MAX_LMEM;  /* overflow; truncate to maximum */
-  g->GCthreshold = threshold;
-  luaE_setdebt(g, -g->gclocalpause);
+  debt = gettotalbytes(g) - threshold;
+  luaE_setdebt(g, debt);
 }
 
 
@@ -1029,9 +913,9 @@ static void setpause (global_State *g, l_mem estimate) {
 static int entersweep (lua_State *L) {
   global_State *g = G(L);
   int n = 0;
-  g->gcstate = GCSswplocalgc;
+  g->gcstate = GCSswpallgc;
   lua_assert(g->sweepgc == NULL);
-  g->sweepgc = sweeptolive(L, &g->localgc, &n);
+  g->sweepgc = sweeptolive(L, &g->allgc, &n);
   return n;
 }
 
@@ -1044,7 +928,6 @@ void luaC_freeallobjects (lua_State *L) {
   lua_assert(g->tobefnz == NULL);
   g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
   g->gckind = KGC_NORMAL;
-  sweepwholelist(L, &g->localgc);
   sweepwholelist(L, &g->finobj);
   sweepwholelist(L, &g->allgc);
   sweepwholelist(L, &g->mainthread->next);
@@ -1136,10 +1019,7 @@ static lu_mem singlestep (lua_State *L) {
       sw = entersweep(L);
       return work + sw * GCSWEEPCOST;
     }
-    case GCSswplocalgc: {  /* sweep local objects */
-      return sweepstep(L, g, GCSswpallgc, &g->allgc);
-    }
-    case GCSswpallgc: {  /* sweep non-local objects */
+    case GCSswpallgc: {  /* sweep "regular" objects */
       return sweepstep(L, g, GCSswpthreads, &g->mainthread->next);
     }
     case GCSswpthreads: {  /* sweep threads */
@@ -1208,23 +1088,13 @@ void luaC_forcestep (lua_State *L) {
 
 
 /*
-** performs a basic GC step or a local collection when collector is running
+** performs a basic GC step when collector is running
 */
 void luaC_step (lua_State *L) {
-  global_State *g = G(L);
-  if (!g->gcrunning)
-    luaE_setdebt(g, -GCSTEPSIZE);  /* avoid being called too often */
-  else {
-    if (g->gcstate != GCSpause)  /* in the middle of a cycle? */
-      luaC_forcestep(L);  /* continue it */
-    else {
-      luaC_localcollection(L);  /* try a local collection */
-      if (gettotalbytes(g) <= g->GCthreshold)  /* enough? */
-        luaE_setdebt(g, -g->gclocalpause);
-      else  /* local collection did not collect enough memory */
-        luaC_forcestep(L);  /* start a full collection */
-    }
-  }
+  if (!G(L)->gcrunning)
+    luaE_setdebt(G(L), -GCSTEPSIZE);  /* avoid being called too often */
+  else
+    luaC_forcestep(L);
 }
 
 

+ 11 - 20
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 2.76 2013/09/11 20:15:31 roberto Exp roberto $
+** $Id: lgc.h,v 2.77 2014/02/11 12:18:12 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -38,17 +38,16 @@
 */
 #define GCSpropagate	0
 #define GCSatomic	1
-#define GCSswplocalgc	2
-#define GCSswpallgc	3
-#define GCSswpthreads	4
-#define GCSswpfinobj	5
-#define GCSswptobefnz	6
-#define GCSswpend	7
-#define GCSpause	8
+#define GCSswpallgc	2
+#define GCSswpthreads	3
+#define GCSswpfinobj	4
+#define GCSswptobefnz	5
+#define GCSswpend	6
+#define GCSpause	7
 
 
 #define issweepphase(g)  \
-	(GCSswplocalgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
+	(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
 
 
 /*
@@ -80,8 +79,6 @@
 #define WHITE1BIT	1  /* object is white (type 1) */
 #define BLACKBIT	2  /* object is black */
 #define FINALIZEDBIT	3  /* object has been marked for finalization */
-#define NOLOCALBIT	4  /* object is not local */
-#define LOCALMARK	5  /* object is 'locally marked' or out of local list */
 /* bit 7 is currently used by tests (luaL_checkmemory) */
 
 #define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
@@ -91,7 +88,6 @@
 #define isblack(x)      testbit((x)->gch.marked, BLACKBIT)
 #define isgray(x)  /* neither white nor black */  \
 	(!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
-#define islocal(x)	(!testbit((x)->gch.marked, NOLOCALBIT))
 
 #define tofinalize(x)	testbit((x)->gch.marked, FINALIZEDBIT)
 
@@ -102,9 +98,6 @@
 #define changewhite(x)	((x)->gch.marked ^= WHITEBITS)
 #define gray2black(x)	l_setbit((x)->gch.marked, BLACKBIT)
 
-#define nolocal(x)	l_setbit((x)->gch.marked, NOLOCALBIT)
-#define valnolocal(v)	{ if (iscollectable(v)) nolocal(gcvalue(v)); }
-
 #define luaC_white(g)	cast(lu_byte, (g)->currentwhite & WHITEBITS)
 
 
@@ -114,17 +107,15 @@
 
 
 #define luaC_barrier(L,p,v) {  \
-	if (iscollectable(v) && \
-          (nolocal(gcvalue(v)), isblack(obj2gco(p)) && iswhite(gcvalue(v))))  \
+	if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v)))  \
 	luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
 
 #define luaC_barrierback(L,p,v) {  \
-	if (iscollectable(v) && \
-          (nolocal(gcvalue(v)), isblack(obj2gco(p)) && iswhite(gcvalue(v))))  \
+	if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v)))  \
 	luaC_barrierback_(L,obj2gco(p)); }
 
 #define luaC_objbarrier(L,p,o) {  \
-	if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
+	if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
 		luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
 
 #define luaC_upvalbarrier(L,uv) \

+ 4 - 14
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.116 2013/11/08 17:34:22 roberto Exp roberto $
+** $Id: lstate.c,v 2.117 2014/02/11 12:18:12 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -30,10 +30,6 @@
 #define LUAI_GCPAUSE	200  /* 200% */
 #endif
 
-#if !defined(LUAI_GCLOCALPAUSE)
-#define LUAI_GCLOCALPAUSE	(1000 * sizeof(TString))
-#endif
-
 #if !defined(LUAI_GCMUL)
 #define LUAI_GCMUL	200 /* GC runs 'twice the speed' of memory allocation */
 #endif
@@ -187,14 +183,12 @@ static void init_registry (lua_State *L, global_State *g) {
   Table *registry = luaH_new(L);
   sethvalue(L, &g->l_registry, registry);
   luaH_resize(L, registry, LUA_RIDX_LAST, 0);
-  nolocal(obj2gco(registry));
   /* registry[LUA_RIDX_MAINTHREAD] = L */
   setthvalue(L, &temp, L);  /* temp = L */
   luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
   /* registry[LUA_RIDX_GLOBALS] = table of globals */
   sethvalue(L, &temp, luaH_new(L));  /* temp = new table (global table) */
   luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
-  valnolocal(&temp);  /* keep local invariant */
 }
 
 
@@ -263,7 +257,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
   luaC_checkGC(L);
   /* create new thread */
   L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
-  L1->marked = luaC_white(g) | bit2mask(NOLOCALBIT, LOCALMARK);
+  L1->marked = luaC_white(g);
   L1->tt = LUA_TTHREAD;
   /* link it on list of threads */
   L1->next = g->mainthread->next;
@@ -303,7 +297,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   L->next = NULL;
   L->tt = LUA_TTHREAD;
   g->currentwhite = bitmask(WHITE0BIT);
-  L->marked = luaC_white(g) | bit2mask(NOLOCALBIT, LOCALMARK);
+  L->marked = luaC_white(g);
   g->gckind = KGC_NORMAL;
   preinit_state(L, g);
   g->frealloc = f;
@@ -312,7 +306,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->seed = makeseed(L);
   g->gcrunning = 0;  /* no GC while building state */
   g->GCestimate = 0;
-  g->GCthreshold = 10000;
   g->strt.size = g->strt.nuse = 0;
   g->strt.hash = NULL;
   setnilvalue(&g->l_registry);
@@ -320,16 +313,13 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->panic = NULL;
   g->version = NULL;
   g->gcstate = GCSpause;
-  g->localgc = g->allgc = g->finobj = NULL;
-  g->tobefnz = NULL;
-  g->fixedgc = NULL;
+  g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
   g->sweepgc = NULL;
   g->gray = g->grayagain = NULL;
   g->weak = g->ephemeron = g->allweak = NULL;
   g->totalbytes = sizeof(LG);
   g->GCdebt = 0;
   g->gcpause = LUAI_GCPAUSE;
-  g->gclocalpause = LUAI_GCLOCALPAUSE;
   g->gcstepmul = LUAI_GCMUL;
   for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
   if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {

+ 2 - 6
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.97 2013/09/17 15:40:06 roberto Exp roberto $
+** $Id: lstate.h,v 2.98 2014/02/11 12:18:12 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -22,8 +22,7 @@
 ** the 'CommonHeader' for the link:
 **
 ** mainthread->next: all threads;
-** localgc: all local objects not marked for finalization;
-** allgc: all non local objects not marked for finalization;
+** allgc: all objects not marked for finalization;
 ** finobj: all objects marked for finalization;
 ** tobefnz: all objects ready to be finalized; 
 ** fixedgc: all objects that are not to be collected (currently
@@ -108,7 +107,6 @@ typedef struct global_State {
   l_mem GCdebt;  /* bytes allocated not yet compensated by the collector */
   lu_mem GCmemtrav;  /* memory traversed by the GC */
   lu_mem GCestimate;  /* an estimate of the non-garbage memory in use */
-  lu_mem GCthreshold;  /* threshold to start a new GC cycle */
   stringtable strt;  /* hash table for strings */
   TValue l_registry;
   unsigned int seed;  /* randomized seed for hashes */
@@ -117,7 +115,6 @@ typedef struct global_State {
   lu_byte gckind;  /* kind of GC running */
   lu_byte gcrunning;  /* true if GC is running */
   GCObject *allgc;  /* list of all collectable objects */
-  GCObject *localgc;  /* list of local objects */
   GCObject **sweepgc;  /* current position of sweep in list */
   GCObject *finobj;  /* list of collectable objects with finalizers */
   GCObject *gray;  /* list of gray objects */
@@ -129,7 +126,6 @@ typedef struct global_State {
   GCObject *fixedgc;  /* list of objects not to be collected */
   Mbuffer buff;  /* temporary buffer for string concatenation */
   int gcpause;  /* size of pause between successive GCs */
-  int gclocalpause;  /* size of pause between local collections */
   int gcstepmul;  /* GC `granularity' */
   lua_CFunction panic;  /* to be called in unprotected errors */
   struct lua_State *mainthread;

+ 18 - 49
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.162 2013/12/30 20:47:58 roberto Exp roberto $
+** $Id: ltests.c,v 2.163 2014/02/11 12:18:12 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -188,41 +188,23 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
 }
 
 
-/*
-** Check locality
-*/
-static int testobjref2 (GCObject *f, GCObject *t) {
-  /* not a local or pointed by a thread? */
-  if (!islocal(t) || gch(f)->tt == LUA_TTHREAD)
-    return 1;  /* ok */
-  if (gch(f)->tt == LUA_TPROTO && gch(t)->tt == LUA_TLCL)
-    return 1;  /* cache from a prototype */
-  return 0;
-}
-
-
 static void printobj (global_State *g, GCObject *o) {
-  printf("||%s(%p)-%s-%c(%02X)||",
+  printf("||%s(%p)-%c(%02X)||",
            ttypename(novariant(gch(o)->tt)), (void *)o,
-           islocal(o)?"L":"NL",
            isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked);
 }
 
 
 static int testobjref (global_State *g, GCObject *f, GCObject *t) {
-  int r1 = testobjref1(g,f,t);
-  int r2 = testobjref2(f,t);
-  if (!r1 || !r2) {
-    if (!r1)
-      printf("%d(%02X) - ", g->gcstate, g->currentwhite);
-    else
-      printf("local violation - ");
+  int r1 = testobjref1(g, f, t);
+  if (!r1) {
+    printf("%d(%02X) - ", g->gcstate, g->currentwhite);
     printobj(g, f);
     printf("  ->  ");
     printobj(g, t);
     printf("\n");
   }
-  return r1 && r2;
+  return r1;
 }
 
 #define checkobjref(g,f,t)	lua_assert(testobjref(g,f,obj2gco(t)))
@@ -349,7 +331,6 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) {
         break;
       }
       case LUA_TTHREAD: {
-        lua_assert(!islocal(o));
         checkstack(g, gco2th(o));
         break;
       }
@@ -366,7 +347,10 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) {
         break;
       }
       case LUA_TSHRSTR:
-      case LUA_TLNGSTR: break;
+      case LUA_TLNGSTR: {
+        lua_assert(!isgray(o));  /* strings are never gray */
+        break;
+      }
       default: lua_assert(0);
     }
   }
@@ -431,28 +415,23 @@ int lua_checkmemory (lua_State *L) {
   resetbit(g->mainthread->marked, TESTGRAYBIT);
   lua_assert(g->sweepgc == NULL || issweepphase(g));
   markgrays(g);
-  /* check 'localgc' list */
-  checkgray(g, g->localgc);
-  maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSswplocalgc);
-  for (o = g->localgc; o != NULL; o = gch(o)->next) {
-    checkobject(g, o, maybedead);
-    lua_assert(!tofinalize(o) && !testbit(o->gch.marked, LOCALMARK));
+  /* check 'fixedgc' list */
+  for (o = g->fixedgc; o != NULL; o = gch(o)->next) {
+    lua_assert(gch(o)->tt == LUA_TSHRSTR && isgray(o));
   }
   /* check 'allgc' list */
   checkgray(g, g->allgc);
   maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSswpallgc);
   for (o = g->allgc; o != NULL; o = gch(o)->next) {
     checkobject(g, o, maybedead);
-    lua_assert(!tofinalize(o) && testbit(o->gch.marked, LOCALMARK));
-    lua_assert(testbit(o->gch.marked, NOLOCALBIT));
+    lua_assert(!tofinalize(o));
   }
   /* check thread list */
   checkgray(g, obj2gco(g->mainthread));
   maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSswpthreads);
   for (o = obj2gco(g->mainthread); o != NULL; o = gch(o)->next) {
     checkobject(g, o, maybedead);
-    lua_assert(!tofinalize(o) && testbit(o->gch.marked, LOCALMARK));
-    lua_assert(testbit(o->gch.marked, NOLOCALBIT));
+    lua_assert(!tofinalize(o));
     lua_assert(gch(o)->tt == LUA_TTHREAD);
   }
   /* check 'finobj' list */
@@ -460,7 +439,6 @@ int lua_checkmemory (lua_State *L) {
   for (o = g->finobj; o != NULL; o = gch(o)->next) {
     checkobject(g, o, 0);
     lua_assert(tofinalize(o));
-    lua_assert(!islocal(o) || !testbit(gch(o)->marked, LOCALMARK));
     lua_assert(gch(o)->tt == LUA_TUSERDATA || gch(o)->tt == LUA_TTABLE);
   }
   /* check 'tobefnz' list */
@@ -636,21 +614,12 @@ static int gc_color (lua_State *L) {
 }
 
 
-static int gc_local (lua_State *L) {
-  TValue *o;
-  luaL_checkany(L, 1);
-  o = obj_at(L, 1);
-  lua_pushboolean(L, !iscollectable(o) || islocal(gcvalue(o)));
-  return 1;
-}
-
-
 static int gc_state (lua_State *L) {
   static const char *statenames[] = {"propagate", "atomic",
-    "sweeplocalgc", "sweepallgc", "sweepthreads", "sweepfinobj",
+    "sweepallgc", "sweepthreads", "sweepfinobj",
     "sweeptobefnz", "sweepend", "pause", ""};
   static const int states[] = {GCSpropagate, GCSatomic,
-    GCSswplocalgc, GCSswpallgc, GCSswpthreads, GCSswpfinobj,
+    GCSswpallgc, GCSswpthreads, GCSswpfinobj,
     GCSswptobefnz, GCSswpend, GCSpause, -1};
   int option = states[luaL_checkoption(L, 1, "", statenames)];
   if (option == -1) {
@@ -1459,7 +1428,6 @@ static const struct luaL_Reg tests_funcs[] = {
   {"doonnewstack", doonnewstack},
   {"doremote", doremote},
   {"gccolor", gc_color},
-  {"isgclocal", gc_local},
   {"gcstate", gc_state},
   {"getref", getref},
   {"hash", hash_query},
@@ -1509,3 +1477,4 @@ int luaB_opentests (lua_State *L) {
 }
 
 #endif
+

+ 1 - 2
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.297 2013/12/18 14:12:03 roberto Exp roberto $
+** $Id: lua.h,v 1.298 2013/12/30 20:47:58 roberto Exp roberto $
 ** Lua - A Scripting Language
 ** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
 ** See Copyright Notice at the end of this file
@@ -294,7 +294,6 @@ LUA_API int  (lua_status) (lua_State *L);
 #define LUA_GCSTEP		5
 #define LUA_GCSETPAUSE		6
 #define LUA_GCSETSTEPMUL	7
-#define LUA_GCSETLOCALPAUSE	8
 #define LUA_GCISRUNNING		9
 
 LUA_API int (lua_gc) (lua_State *L, int what, int data);

+ 1 - 2
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 2.23 2013/04/26 18:48:35 roberto Exp roberto $
+** $Id: lundump.c,v 2.24 2013/08/16 18:55:49 roberto Exp roberto $
 ** load precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -88,7 +88,6 @@ static TString* LoadString(LoadState* S)
   char* s=luaZ_openspace(S->L,S->b,size);
   LoadBlock(S,s,size*sizeof(char));
   ts = luaS_newlstr(S->L,s,size-1);		/* remove trailing '\0' */
-  nolocal(obj2gco(ts));  /* all strings here anchored in non-thread objects */
   return ts;
  }
 }