commit 686e57cf9c61070ff961407e3304071e171542f4
parent 06156e7575dee21026595a30dcf76f400c447a33
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 13 Sep 2013 13:21:27 -0300
GC local pause configurable
Diffstat:
6 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/lapi.c b/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.188 2013/08/27 18:53:35 roberto Exp roberto $
+** $Id: lapi.c,v 2.189 2013/09/11 20:15:31 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -1086,6 +1086,11 @@ 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
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.280 2013/07/10 17:15:12 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.281 2013/08/05 16:58:28 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -174,9 +174,11 @@ 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", "isrunning", NULL};
+ "count", "step", "setpause", "setstepmul",
+ "setlocalpause", "isrunning", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
- LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCISRUNNING};
+ LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
+ LUA_GCSETLOCALPAUSE, 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/lgc.c b/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.163 2013/09/11 14:47:08 roberto Exp roberto $
+** $Id: lgc.c,v 2.164 2013/09/11 14:56:15 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -25,12 +25,6 @@
/*
-** How much memory to allocate before a new local collection
-*/
-#define GCLOCALPAUSE 8000
-
-
-/*
** cost of sweeping one element (the size of a small object divided
** by some adjust for the sweep speed)
*/
@@ -149,7 +143,7 @@ void luaC_barrier_ (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->gcstate != GCSpause);
- lua_assert(gch(o)->tt != LUA_TTABLE);
+ lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */
if (keepinvariant(g)) /* must keep invariant? */
reallymarkobject(g, v); /* restore invariant */
else { /* sweep phase */
@@ -888,19 +882,18 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
return; /* nothing to be done */
else { /* move 'o' to 'finobj' list */
GCObject **p;
- GCheader *ho = gch(o);
- if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */
+ if (g->sweepgc == &o->gch.next) { /* avoid removing current sweep object */
lua_assert(issweepphase(g));
g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
}
/* search for pointer pointing to 'o' */
- p = (testbit(ho->marked, LOCALMARK)) ? &g->allgc : &g->localgc;
+ p = (testbit(o->gch.marked, LOCALMARK)) ? &g->allgc : &g->localgc;
for (; *p != o; p = &gch(*p)->next) { /* empty */ }
- *p = ho->next; /* remove 'o' from its list */
- p = (testbit(ho->marked, LOCALMARK)) ? &g->finobj : &g->localfin;
- ho->next = *p; /* link it in a "fin" list */
+ *p = o->gch.next; /* remove 'o' from its list */
+ p = (testbit(o->gch.marked, LOCALMARK)) ? &g->finobj : &g->localfin;
+ o->gch.next = *p; /* link it in a "fin" list */
*p = o;
- l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */
+ l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */
if (issweepphase(g))
makewhite(g, o); /* "sweep" object */
}
@@ -1032,7 +1025,7 @@ static void setpause (global_State *g, l_mem estimate) {
? estimate * g->gcpause /* no overflow */
: MAX_LMEM; /* overflow; truncate to maximum */
g->GCthreshold = threshold;
- luaE_setdebt(g, -GCLOCALPAUSE);
+ luaE_setdebt(g, -g->gclocalpause);
}
@@ -1050,8 +1043,6 @@ static int entersweep (lua_State *L) {
g->gcstate = GCSswplocalgc;
lua_assert(g->sweepgc == NULL);
g->sweepgc = sweeptolive(L, &g->localgc, &n);
- if (g->sweepgc == NULL) /* no live objects in local list? */
- g->sweepgc = &g->localgc; /* 'sweepgc' cannot be NULL here */
return n;
}
@@ -1099,7 +1090,7 @@ static l_mem atomic (lua_State *L) {
work += g->GCmemtrav; /* stop counting (objects being finalized) */
separatetobefnz(g, 0); /* separate objects to be finalized */
markbeingfnz(g); /* mark objects that will be finalized */
- propagateall(g); /* remark, to propagate `preserveness' */
+ propagateall(g); /* remark, to propagate 'resurrection' */
work -= g->GCmemtrav; /* restart counting */
convergeephemerons(g);
/* at this point, all resurrected objects are marked. */
@@ -1117,14 +1108,15 @@ static l_mem atomic (lua_State *L) {
static lu_mem sweepstep (lua_State *L, global_State *g,
int nextstate, GCObject **nextlist) {
- g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
- if (g->sweepgc) /* is there still something to sweep? */
- return (GCSWEEPMAX * GCSWEEPCOST);
- else { /* enter next state */
- g->gcstate = nextstate;
- g->sweepgc = nextlist;
- return 0;
+ if (g->sweepgc) {
+ g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
+ if (g->sweepgc) /* is there still something to sweep? */
+ return (GCSWEEPMAX * GCSWEEPCOST);
}
+ /* else enter next state */
+ g->gcstate = nextstate;
+ g->sweepgc = nextlist;
+ return 0;
}
@@ -1245,7 +1237,7 @@ void luaC_step (lua_State *L) {
luaC_forcestep(L); /* restart collection */
}
else
- luaE_setdebt(g, -GCLOCALPAUSE);
+ luaE_setdebt(g, -g->gclocalpause);
}
}
else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */
diff --git a/lstate.c b/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.112 2013/09/11 12:26:14 roberto Exp roberto $
+** $Id: lstate.c,v 2.113 2013/09/11 14:09:55 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -30,6 +30,10 @@
#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
@@ -301,6 +305,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
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
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.94 2013/09/05 19:31:49 roberto Exp roberto $
+** $Id: lstate.h,v 2.95 2013/09/11 14:09:55 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -131,6 +131,7 @@ 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/lua.h b/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.292 2013/07/05 14:29:51 roberto Exp roberto $
+** $Id: lua.h,v 1.293 2013/08/05 16:58:28 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
@@ -288,7 +288,8 @@ LUA_API int (lua_status) (lua_State *L);
#define LUA_GCSTEP 5
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7
-#define LUA_GCISRUNNING 8
+#define LUA_GCSETLOCALPAUSE 8
+#define LUA_GCISRUNNING 9
LUA_API int (lua_gc) (lua_State *L, int what, int data);