diff --git a/lapi.c b/lapi.c index 05640ef9..0fcb6eaa 100644 --- a/lapi.c +++ b/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; diff --git a/lbaselib.c b/lbaselib.c index 9e3c5c87..0b51b743 100644 --- a/lbaselib.c +++ b/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); diff --git a/lfunc.c b/lfunc.c index 3727b6cf..3381e437 100644 --- a/lfunc.c +++ b/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; diff --git a/lgc.c b/lgc.c index 4fb65ef3..61162d42 100644 --- a/lgc.c +++ b/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); } diff --git a/lgc.h b/lgc.h index 43cfb851..c4e1f3b0 100644 --- a/lgc.h +++ b/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) \ diff --git a/lstate.c b/lstate.c index 2f21f98e..3a33390d 100644 --- a/lstate.c +++ b/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) { diff --git a/lstate.h b/lstate.h index 49b5d24e..13b2108c 100644 --- a/lstate.h +++ b/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; diff --git a/ltests.c b/ltests.c index 6923cef5..7ec2aac2 100644 --- a/ltests.c +++ b/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 + diff --git a/lua.h b/lua.h index d40d1956..95fb3f9c 100644 --- a/lua.h +++ b/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); diff --git a/lundump.c b/lundump.c index be77d98e..7194d82a 100644 --- a/lundump.c +++ b/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; } }