no more generational collector (and no more `noinc' mode)

This commit is contained in:
Roberto Ierusalimschy 2005-01-14 12:19:42 -02:00
parent d2bda8046c
commit 5be517602e
8 changed files with 49 additions and 66 deletions

8
lapi.c
View File

@ -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 */

View File

@ -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");

57
lgc.c
View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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: {

4
lua.h
View File

@ -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);