aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-06 12:02:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-06 12:02:34 -0300
commit0270c204c235a495ce4702ac3891eb30752d0c8d (patch)
treef97e28fe989eb6c6ee96656c6f225fa50a44d7ef
parentefc7c5d503e30128e8282f0a70d3793e9ee3bd3a (diff)
downloadlua-0270c204c235a495ce4702ac3891eb30752d0c8d.tar.gz
lua-0270c204c235a495ce4702ac3891eb30752d0c8d.tar.bz2
lua-0270c204c235a495ce4702ac3891eb30752d0c8d.zip
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 (limited to '')
-rw-r--r--lapi.c30
-rw-r--r--lgc.c12
2 files changed, 22 insertions, 20 deletions
diff --git a/lapi.c b/lapi.c
index 0cde72cc..d6d7a8db 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1145,7 +1145,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
1145 } 1145 }
1146 case LUA_GCRESTART: { 1146 case LUA_GCRESTART: {
1147 luaE_setdebt(g, 0); 1147 luaE_setdebt(g, 0);
1148 g->gcstp = 0; /* (GCSTPGC must be already zero here) */ 1148 g->gcstp = 0; /* (bit GCSTPGC must be zero here) */
1149 break; 1149 break;
1150 } 1150 }
1151 case LUA_GCCOLLECT: { 1151 case LUA_GCCOLLECT: {
@@ -1162,21 +1162,25 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
1162 break; 1162 break;
1163 } 1163 }
1164 case LUA_GCSTEP: { 1164 case LUA_GCSTEP: {
1165 int data = va_arg(argp, int); 1165 int todo = va_arg(argp, int); /* work to be done */
1166 l_obj debt = 1; /* =1 to signal that it did an actual step */ 1166 int didsomething = 0;
1167 lu_byte oldstp = g->gcstp; 1167 lu_byte oldstp = g->gcstp;
1168 g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ 1168 g->gcstp = 0; /* allow GC to run (bit GCSTPGC must be zero here) */
1169 if (data == 0) { 1169 if (todo == 0)
1170 luaE_setdebt(g, 0); /* do a basic step */ 1170 todo = 1 << g->gcstepsize; /* standard step size */
1171 luaC_step(L); 1171 while (todo + g->GCdebt > 0) { /* enough to run a step? */
1172 } 1172 todo += g->GCdebt; /* decrement 'todo' (debt is usually negative) */
1173 else { /* add 'data' to total debt */ 1173 luaC_step(L); /* run one basic step */
1174 debt = data + g->GCdebt; 1174 didsomething = 1;
1175 luaE_setdebt(g, debt); 1175 if (g->gckind == KGC_GEN) /* minor collections? */
1176 luaC_checkGC(L); 1176 todo = 0; /* doesn't make sense to repeat in this case */
1177 else if (g->gcstate == GCSpause)
1178 break; /* don't run more than one cycle */
1177 } 1179 }
1180 /* add remaining 'todo' to total debt */
1181 luaE_setdebt(g, todo + g->GCdebt);
1178 g->gcstp = oldstp; /* restore previous state */ 1182 g->gcstp = oldstp; /* restore previous state */
1179 if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ 1183 if (didsomething && g->gcstate == GCSpause) /* end of cycle? */
1180 res = 1; /* signal it */ 1184 res = 1; /* signal it */
1181 break; 1185 break;
1182 } 1186 }
diff --git a/lgc.c b/lgc.c
index 1b24fda6..c93b5994 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1037,7 +1037,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
1037*/ 1037*/
1038static void setpause (global_State *g) { 1038static void setpause (global_State *g) {
1039 unsigned int pause = getgcparam(g->gcpause); 1039 unsigned int pause = getgcparam(g->gcpause);
1040 lu_mem threshold = g->marked / 8 * pause / 12; 1040 l_obj threshold = g->marked / 8 * pause / 12;
1041 l_obj debt = gettotalobjs(g) - threshold; 1041 l_obj debt = gettotalobjs(g) - threshold;
1042 if (debt > 0) debt = 0; 1042 if (debt > 0) debt = 0;
1043 luaE_setdebt(g, debt); 1043 luaE_setdebt(g, debt);
@@ -1600,18 +1600,16 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
1600** controls when next step will be performed. 1600** controls when next step will be performed.
1601*/ 1601*/
1602static void incstep (lua_State *L, global_State *g) { 1602static void incstep (lua_State *L, global_State *g) {
1603 int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */
1604 l_obj debt = (g->GCdebt / 100) * stepmul;
1605 l_obj stepsize = cast(l_obj, 1) << g->gcstepsize; 1603 l_obj stepsize = cast(l_obj, 1) << g->gcstepsize;
1604 l_obj work2do = stepsize * getgcparam(g->gcstepmul) / 100;
1606 do { /* repeat until pause or enough "credit" (negative debt) */ 1605 do { /* repeat until pause or enough "credit" (negative debt) */
1607 l_obj work = singlestep(L); /* perform one single step */ 1606 l_obj work = singlestep(L); /* perform one single step */
1608 debt -= work; 1607 work2do -= work;
1609 } while (debt > -stepsize && g->gcstate != GCSpause); 1608 } while (work2do > 0 && g->gcstate != GCSpause);
1610 if (g->gcstate == GCSpause) 1609 if (g->gcstate == GCSpause)
1611 setpause(g); /* pause until next cycle */ 1610 setpause(g); /* pause until next cycle */
1612 else { 1611 else {
1613 debt = (debt / stepmul) * 100; /* apply step multiplier */ 1612 luaE_setdebt(g, -stepsize);
1614 luaE_setdebt(g, debt);
1615 } 1613 }
1616} 1614}
1617 1615