commit 0270c204c235a495ce4702ac3891eb30752d0c8d
parent efc7c5d503e30128e8282f0a70d3793e9ee3bd3a
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 6 Dec 2022 12:02:07 -0300
Simplification in handling of GC debt
Each incremental step has always the same size (stepsize), and the
debt for next step also is always the same.
Diffstat:
M | lapi.c | | | 30 | +++++++++++++++++------------- |
M | lgc.c | | | 12 | +++++------- |
2 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/lapi.c b/lapi.c
@@ -1145,7 +1145,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
}
case LUA_GCRESTART: {
luaE_setdebt(g, 0);
- g->gcstp = 0; /* (GCSTPGC must be already zero here) */
+ g->gcstp = 0; /* (bit GCSTPGC must be zero here) */
break;
}
case LUA_GCCOLLECT: {
@@ -1162,21 +1162,25 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
break;
}
case LUA_GCSTEP: {
- int data = va_arg(argp, int);
- l_obj debt = 1; /* =1 to signal that it did an actual step */
+ int todo = va_arg(argp, int); /* work to be done */
+ int didsomething = 0;
lu_byte oldstp = g->gcstp;
- g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */
- if (data == 0) {
- luaE_setdebt(g, 0); /* do a basic step */
- luaC_step(L);
- }
- else { /* add 'data' to total debt */
- debt = data + g->GCdebt;
- luaE_setdebt(g, debt);
- luaC_checkGC(L);
+ g->gcstp = 0; /* allow GC to run (bit GCSTPGC must be zero here) */
+ if (todo == 0)
+ todo = 1 << g->gcstepsize; /* standard step size */
+ while (todo + g->GCdebt > 0) { /* enough to run a step? */
+ todo += g->GCdebt; /* decrement 'todo' (debt is usually negative) */
+ luaC_step(L); /* run one basic step */
+ didsomething = 1;
+ if (g->gckind == KGC_GEN) /* minor collections? */
+ todo = 0; /* doesn't make sense to repeat in this case */
+ else if (g->gcstate == GCSpause)
+ break; /* don't run more than one cycle */
}
+ /* add remaining 'todo' to total debt */
+ luaE_setdebt(g, todo + g->GCdebt);
g->gcstp = oldstp; /* restore previous state */
- if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
+ if (didsomething && g->gcstate == GCSpause) /* end of cycle? */
res = 1; /* signal it */
break;
}
diff --git a/lgc.c b/lgc.c
@@ -1037,7 +1037,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
*/
static void setpause (global_State *g) {
unsigned int pause = getgcparam(g->gcpause);
- lu_mem threshold = g->marked / 8 * pause / 12;
+ l_obj threshold = g->marked / 8 * pause / 12;
l_obj debt = gettotalobjs(g) - threshold;
if (debt > 0) debt = 0;
luaE_setdebt(g, debt);
@@ -1600,18 +1600,16 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
** controls when next step will be performed.
*/
static void incstep (lua_State *L, global_State *g) {
- int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */
- l_obj debt = (g->GCdebt / 100) * stepmul;
l_obj stepsize = cast(l_obj, 1) << g->gcstepsize;
+ l_obj work2do = stepsize * getgcparam(g->gcstepmul) / 100;
do { /* repeat until pause or enough "credit" (negative debt) */
l_obj work = singlestep(L); /* perform one single step */
- debt -= work;
- } while (debt > -stepsize && g->gcstate != GCSpause);
+ work2do -= work;
+ } while (work2do > 0 && g->gcstate != GCSpause);
if (g->gcstate == GCSpause)
setpause(g); /* pause until next cycle */
else {
- debt = (debt / stepmul) * 100; /* apply step multiplier */
- luaE_setdebt(g, debt);
+ luaE_setdebt(g, -stepsize);
}
}