mirror of https://github.com/lua/lua
no more generational collector (and no more `noinc' mode)
This commit is contained in:
parent
d2bda8046c
commit
5be517602e
8
lapi.c
8
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 */
|
||||
|
|
13
lbaselib.c
13
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");
|
||||
|
|
57
lgc.c
57
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
9
lstate.c
9
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);
|
||||
|
|
9
lstate.h
9
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;
|
||||
|
|
11
ltests.c
11
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: {
|
||||
|
|
4
lua.h
4
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue