mirror of
https://github.com/lua/lua
synced 2024-11-22 04:41:23 +03:00
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:
parent
efc7c5d503
commit
0270c204c2
30
lapi.c
30
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;
|
||||
}
|
||||
|
12
lgc.c
12
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user