From 5be517602e5334573297fe8d421a92eb0184ce86 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 14 Jan 2005 12:19:42 -0200 Subject: no more generational collector (and no more `noinc' mode) --- lapi.c | 8 ++++---- lbaselib.c | 13 +++++-------- lgc.c | 57 ++++++++++++++++++++++++--------------------------------- llimits.h | 4 +--- lstate.c | 9 ++++----- lstate.h | 9 ++++----- ltests.c | 11 +++++------ lua.h | 4 ++-- 8 files changed, 49 insertions(+), 66 deletions(-) diff --git a/lapi.c b/lapi.c index 9212b7d1..f82b00dc 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.24 2005/01/04 15:55:12 roberto Exp roberto $ +** $Id: lapi.c,v 2.25 2005/01/07 19:53:32 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -872,9 +872,9 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->gcpace = data; break; } - case LUA_GCSETINCMODE: { - res = g->incgc; - g->incgc = data; + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; break; } default: res = -1; /* invalid option */ diff --git a/lbaselib.c b/lbaselib.c index 042556b9..1d7004b1 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.163 2004/12/13 12:15:11 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.164 2005/01/07 19:53:32 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -182,13 +182,13 @@ static int luaB_gcinfo (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpace", "setincmode", NULL}; + "count", "step", "setpace", "setstepmul", NULL}; static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPACE, LUA_GCSETINCMODE}; + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPACE, LUA_GCSETSTEPMUL}; int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); - int ex = luaL_optint(L, 2, 0); + lua_Number ex = luaL_optnumber(L, 2, 0); luaL_argcheck(L, o >= 0, 1, "invalid option"); - lua_pushinteger(L, lua_gc(L, optsnum[o], ex)); + lua_pushinteger(L, lua_gc(L, optsnum[o], ex * 100)); return 1; } @@ -620,9 +620,6 @@ static void base_open (lua_State *L) { /* create register._LOADED to track loaded modules */ lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "_LOADED"); - /* create register._PRELOAD to allow pre-loaded modules */ - lua_newtable(L); - lua_setfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); lua_setglobal(L, "_G"); diff --git a/lgc.c b/lgc.c index 0d76d2b1..af16e882 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.19 2004/12/13 12:15:11 roberto Exp roberto $ +** $Id: lgc.c,v 2.20 2005/01/05 18:20:51 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -23,11 +23,10 @@ #include "ltm.h" -#define GCSTEPSIZE 1000 -#define GCSWEEPMAX 10 -#define GCSWEEPCOST 30 +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 #define GCFINALIZECOST 100 -#define GCSTEPMUL 8 #define FIXEDMASK bitmask(FIXEDBIT) @@ -411,12 +410,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) { global_State *g = G(L); int whitebit = otherwhite(g); int deadmask = whitebit | FIXEDMASK; - int generational = g->gcgenerational; while ((curr = *p) != NULL && count-- > 0) { if ((curr->gch.marked ^ whitebit) & deadmask) { lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); - if (!generational || isdead(g, curr)) - makewhite(g, curr); + makewhite(g, curr); if (curr->gch.tt == LUA_TTHREAD) sweepwholelist(L, &gco2th(curr)->openupval); p = &curr->gch.next; @@ -532,7 +529,6 @@ static void remarkupvals (global_State *g) { static void atomic (lua_State *L) { global_State *g = G(L); size_t udsize; /* total size of userdata to be finalized */ - int aux; /* remark objects cautch by write barrier */ propagateall(g); /* remark occasional upvalues of (maybe) dead threads */ @@ -556,10 +552,6 @@ static void atomic (lua_State *L) { g->sweepstrgc = 0; g->sweepgc = &g->rootgc; g->gcstate = GCSsweepstring; - aux = g->gcgenerational; - 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 */ } @@ -569,11 +561,7 @@ static l_mem singlestep (lua_State *L) { /*lua_checkmemory(L);*/ switch (g->gcstate) { case GCSpause: { - /* start a new collection */ - if (g->gcgenerational) - atomic(L); - else - markroot(L); + markroot(L); /* start a new collection */ return 0; } case GCSpropagate: { @@ -613,6 +601,7 @@ static l_mem singlestep (lua_State *L) { } else { g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; return 0; } } @@ -623,25 +612,31 @@ 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)) * GCSTEPMUL; + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; + g->gcdept += g->totalbytes - g->GCthreshold; do { lim -= singlestep(L); if (g->gcstate == GCSpause) break; - } while (lim > 0 || !g->incgc); - if (g->gcstate != GCSpause) - g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ + } while (lim > 0); + if (g->gcstate != GCSpause) { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } + } else { lua_assert(g->totalbytes >= g->estimate); - g->GCthreshold = g->estimate + ((g->estimate/GCDIV) * g->gcpace); + g->GCthreshold = (g->estimate/100) * g->gcpace; } } void luaC_fullgc (lua_State *L) { global_State *g = G(L); - if (g->gcstate <= GCSpropagate || g->gcgenerational) { - g->gcgenerational = 0; + if (g->gcstate <= GCSpropagate) { /* reset sweep marks to sweep all elements (returning them to white) */ g->sweepstrgc = 0; g->sweepgc = &g->rootgc; @@ -657,10 +652,8 @@ void luaC_fullgc (lua_State *L) { singlestep(L); } markroot(L); - lua_assert(!g->gcgenerational); while (g->gcstate != GCSpause) { singlestep(L); - g->gcgenerational = 0; /* keep it in this mode */ } g->GCthreshold = 2*g->estimate; } @@ -669,11 +662,10 @@ void luaC_fullgc (lua_State *L) { 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 && g->gcstate != GCSpause)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); lua_assert(ttype(&o->gch) != LUA_TTABLE); /* must keep invariant? */ - if (g->gcstate == GCSpropagate || g->gcgenerational) + if (g->gcstate == GCSpropagate) reallymarkobject(g, v); /* restore invariant */ else /* don't mind */ makewhite(g, o); /* mark as white just to avoid other barriers */ @@ -683,8 +675,7 @@ 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 && g->gcstate != GCSpause)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); black2gray(o); /* make table gray (again) */ gco2h(o)->gclist = g->grayagain; g->grayagain = o; @@ -706,7 +697,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ g->rootgc = o; if (isgray(o)) { - if (g->gcstate == GCSpropagate || g->gcgenerational) { + if (g->gcstate == GCSpropagate) { gray2black(o); /* closed upvalues need barrier */ luaC_barrier(L, uv, uv->v); } diff --git a/llimits.h b/llimits.h index efbe3898..86b3f28f 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.61 2004/11/24 18:55:56 roberto Exp roberto $ +** $Id: llimits.h,v 1.62 2004/12/13 12:15:11 roberto Exp roberto $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -73,8 +73,6 @@ typedef LUA_UACNUMBER l_uacNumber; typedef lu_int32 Instruction; -/* divisor for GC pace */ -#define GCDIV 8 /* maximum stack for a Lua function */ #define MAXSTACK 250 diff --git a/lstate.c b/lstate.c index 54917649..33a5cd7d 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.20 2005/01/04 15:55:12 roberto Exp roberto $ +** $Id: lstate.c,v 2.21 2005/01/05 18:20:51 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -95,7 +95,6 @@ static void f_luaopen (lua_State *L, void *ud) { luaX_init(L); luaS_fix(luaS_newliteral(L, MEMERRMSG)); g->GCthreshold = 4*g->totalbytes; - g->prevestimate = g->estimate = g->totalbytes; } @@ -180,7 +179,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { luaZ_initbuffer(L, &g->buff); g->panic = NULL; g->gcstate = GCSpause; - g->gcgenerational = 0; g->rootgc = obj2gco(L); g->sweepstrgc = 0; g->sweepgc = &g->rootgc; @@ -190,8 +188,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->weak = NULL; g->tmudata = NULL; g->totalbytes = sizeof(LG); - g->gcpace = GCDIV; - g->incgc = 1; + g->gcpace = 200; /* 200% (wait memory to double before next collection) */ + g->gcstepmul = 200; /* GC runs `twice the speed' of memory allocation */ + g->gcdept = 0; 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 26a94082..1bb887c4 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.10 2004/12/13 12:15:11 roberto Exp roberto $ +** $Id: lstate.h,v 2.11 2005/01/05 18:20:51 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -71,7 +71,6 @@ typedef struct global_State { void *ud; /* auxiliary data to `realloc' */ lu_byte currentwhite; lu_byte gcstate; /* state of garbage collector */ - lu_byte gcgenerational; GCObject *rootgc; /* list of all collectable objects */ GCObject *firstudata; /* udata go to the end of `rootgc' */ GCObject **sweepgc; /* position of sweep in `rootgc' */ @@ -84,9 +83,9 @@ typedef struct global_State { lu_mem GCthreshold; 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 gcpace; /* relative `speed' of the GC */ - int incgc; /* 0 if GC is done non-incrementally */ + lu_mem gcdept; /* how much GC is `behind schedule' */ + int gcpace; /* size of pause between successive GCs */ + int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ TValue _registry; struct lua_State *mainthread; diff --git a/ltests.c b/ltests.c index 6139106c..18257905 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.15 2004/11/01 15:06:50 roberto Exp roberto $ +** $Id: ltests.c,v 2.16 2005/01/05 18:20:51 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -153,9 +153,9 @@ void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { if (isdead(g,t)) return 0; - if (g->gcstate == GCSpropagate || g->gcgenerational) + if (g->gcstate == GCSpropagate) return !isblack(f) || !iswhite(t); - else if (g->gcstate == GCSfinalize && !g->gcgenerational) + else if (g->gcstate == GCSfinalize) return iswhite(f); else return 1; @@ -175,8 +175,7 @@ static void printobj (global_State *g, GCObject *o) { static int testobjref (global_State *g, GCObject *f, GCObject *t) { int r = testobjref1(g,f,t); if (!r) { - printf("%d(%02X) %c - ", g->gcstate, g->currentwhite, - g->gcgenerational ? 'G' : ' '); + printf("%d(%02X) - ", g->gcstate, g->currentwhite); printobj(g, f); printf("\t-> "); printobj(g, t); @@ -295,7 +294,7 @@ static void checkobject (global_State *g, GCObject *o) { printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked); } else { - if (g->gcstate == GCSfinalize && !g->gcgenerational) + if (g->gcstate == GCSfinalize) lua_assert(iswhite(o)); switch (o->gch.tt) { case LUA_TUPVAL: { diff --git a/lua.h b/lua.h index 3d629f3a..956108a3 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.198 2005/01/07 19:53:32 roberto Exp roberto $ +** $Id: lua.h,v 1.199 2005/01/10 17:31:50 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil ** http://www.lua.org mailto:info@lua.org @@ -227,7 +227,7 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCCOUNT 3 #define LUA_GCSTEP 4 #define LUA_GCSETPACE 5 -#define LUA_GCSETINCMODE 6 +#define LUA_GCSETSTEPMUL 6 LUA_API int (lua_gc) (lua_State *L, int what, int data); -- cgit v1.2.3-55-g6feb