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.
This commit is contained in:
Roberto Ierusalimschy 2022-12-06 12:02:34 -03:00
parent efc7c5d503
commit 0270c204c2
2 changed files with 22 additions and 20 deletions

30
lapi.c
View File

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

12
lgc.c
View File

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