diff --git a/lapi.c b/lapi.c index a4cb91aa..9447f929 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.20 2004/11/24 18:55:56 roberto Exp roberto $ +** $Id: lapi.c,v 2.21 2004/12/03 20:50:25 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -867,6 +867,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { luaC_step(L); break; } + case LUA_GCSETSTEPMUL: { + res = g->stepmul; + g->stepmul = data; + break; + } + case LUA_GCSETINCMODE: { + res = g->incgc; + g->incgc = data; + break; + } default: res = -1; /* invalid option */ } lua_unlock(L); diff --git a/lbaselib.c b/lbaselib.c index 58d43ece..f087c977 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.159 2004/09/29 21:03:14 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.160 2004/11/18 19:53:49 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -181,10 +181,10 @@ static int luaB_gcinfo (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { - static const char *const opts[] = {"stop", "restart", "collect", "count", - "step", NULL}; - static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, - LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP}; + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setstepmul", "setincmode", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETSTEPMUL, LUA_GCSETINCMODE}; int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); int ex = luaL_optint(L, 2, 0); luaL_argcheck(L, o >= 0, 1, "invalid option"); diff --git a/lgc.c b/lgc.c index 61f7a55a..ae6af687 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.16 2004/11/24 18:55:56 roberto Exp roberto $ +** $Id: lgc.c,v 2.17 2004/11/24 19:20:21 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -24,7 +24,6 @@ #define GCSTEPSIZE 1000 -#define STEPMUL 2 #define GCSWEEPMAX 10 #define GCSWEEPCOST 30 #define GCFINALIZECOST 100 @@ -65,7 +64,7 @@ static void removeentry (Node *n) { setnilvalue(gval(n)); /* remove corresponding value ... */ if (iscollectable(gkey(n))) - setttype(gkey(n), LUA_TNONE); /* dead key; remove it */ + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ } @@ -184,6 +183,7 @@ static int traversetable (global_State *g, Table *h) { i = sizenode(h); while (i--) { Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); if (ttisnil(gval(n))) removeentry(n); /* remove empty entries */ else { @@ -555,7 +555,7 @@ static void atomic (lua_State *L) { g->sweepgc = &g->rootgc; g->gcstate = GCSsweepstring; aux = g->gcgenerational; - g->gcgenerational = (g->estimate/2 <= g->prevestimate); + g->gcgenerational = g->incgc && (g->estimate/2 <= g->prevestimate); if (!aux) /* last collection was full? */ g->prevestimate = g->estimate; /* keep estimate of last full collection */ g->estimate = g->totalbytes - udsize; /* first estimate */ @@ -587,6 +587,7 @@ static l_mem singlestep (lua_State *L) { sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPCOST; } @@ -597,6 +598,7 @@ static l_mem singlestep (lua_State *L) { checkSizes(L); g->gcstate = GCSfinalize; /* end sweep phase */ } + lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPMAX*GCSWEEPCOST; } @@ -619,23 +621,18 @@ static l_mem singlestep (lua_State *L) { void luaC_step (lua_State *L) { global_State *g = G(L); - l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * STEPMUL; -/*printf("step(%c): ", g->gcgenerational?'g':' ');*/ + l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * g->stepmul; do { - /*printf("%c", "_pswf"[g->gcstate]);*/ lim -= singlestep(L); if (g->gcstate == GCSpause) break; - } while (lim > 0); -/*printf("\n");*/ - if (g->gcstate != GCSpause) + } while (lim > 0 || !g->incgc); + if (g->incgc) g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ else { -/*printf("---\n");*/ lua_assert(g->totalbytes >= g->estimate); + lua_assert(g->gcstate == GCSpause); g->GCthreshold = 2*g->estimate; - if (g->GCthreshold < g->totalbytes + GCSTEPSIZE) - g->GCthreshold = g->totalbytes + GCSTEPSIZE; } } @@ -660,19 +657,19 @@ void luaC_fullgc (lua_State *L) { } markroot(L); lua_assert(!g->gcgenerational); - while (g->gcstate != GCSfinalize) { + while (g->gcstate != GCSpause) { singlestep(L); g->gcgenerational = 0; /* keep it in this mode */ } g->GCthreshold = 2*g->estimate; - luaC_callGCTM(L); /* call finalizers */ } void luaC_barrierf (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->gcgenerational || g->gcstate != GCSfinalize); + lua_assert(g->gcgenerational || + (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); lua_assert(ttype(&o->gch) != LUA_TTABLE); /* must keep invariant? */ if (g->gcstate == GCSpropagate || g->gcgenerational) @@ -685,7 +682,8 @@ 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->gcgenerational || g->gcstate != GCSfinalize); + lua_assert(g->gcgenerational || + (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); black2gray(o); /* make table gray (again) */ gco2h(o)->gclist = g->grayagain; g->grayagain = o; diff --git a/lstate.c b/lstate.c index ff5d0376..021b8a68 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.16 2004/11/19 15:52:40 roberto Exp roberto $ +** $Id: lstate.c,v 2.17 2004/11/24 19:20:21 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -193,6 +193,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { setnilvalue(gval(g->dummynode)); gnext(g->dummynode) = NULL; g->totalbytes = sizeof(LG); + g->stepmul = STEPMUL; + g->incgc = 1; if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { /* memory allocation error: free partial state */ close_state(L); diff --git a/lstate.h b/lstate.h index 836e3df5..612a785e 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.7 2004/08/30 13:44:44 roberto Exp roberto $ +** $Id: lstate.h,v 2.8 2004/09/15 20:39:42 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -85,6 +85,8 @@ typedef struct global_State { lu_mem totalbytes; /* number of bytes currently allocated */ lu_mem estimate; /* an estimate of number of bytes actually in use */ lu_mem prevestimate; /* previous estimate */ + int stepmul; /* relative `speed' of the GC */ + int incgc; /* 0 if GC is done non-incrementally */ lua_CFunction panic; /* to be called in unprotected errors */ TValue _registry; struct lua_State *mainthread; diff --git a/lua.h b/lua.h index 8e005d09..80c7f1b3 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.194 2004/10/18 12:51:44 roberto Exp roberto $ +** $Id: lua.h,v 1.195 2004/12/01 15:50:18 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil ** http://www.lua.org mailto:info@lua.org @@ -220,11 +220,13 @@ LUA_API int lua_threadstatus (lua_State *L); ** garbage-collection function and options */ -#define LUA_GCSTOP 0 -#define LUA_GCRESTART 1 -#define LUA_GCCOLLECT 2 -#define LUA_GCCOUNT 3 -#define LUA_GCSTEP 4 +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCSTEP 4 +#define LUA_GCSETSTEPMUL 5 +#define LUA_GCSETINCMODE 6 LUA_API int lua_gc (lua_State *L, int what, int data); diff --git a/luaconf.h b/luaconf.h index 8c3aa080..c7c2ee98 100644 --- a/luaconf.h +++ b/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.18 2004/12/01 15:50:18 roberto Exp roberto $ +** $Id: luaconf.h,v 1.19 2004/12/01 15:52:54 roberto Exp roberto $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -273,6 +273,9 @@ #define lua_userstateopen(L) /* empty */ +/* initial GC parameters */ +#define STEPMUL 4 + #endif /* }====================================================== */