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