diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-06 12:02:34 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-06 12:02:34 -0300 |
commit | 0270c204c235a495ce4702ac3891eb30752d0c8d (patch) | |
tree | f97e28fe989eb6c6ee96656c6f225fa50a44d7ef | |
parent | efc7c5d503e30128e8282f0a70d3793e9ee3bd3a (diff) | |
download | lua-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.c | 30 | ||||
-rw-r--r-- | lgc.c | 12 |
2 files changed, 22 insertions, 20 deletions
@@ -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 | } |
@@ -1037,7 +1037,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
1037 | */ | 1037 | */ |
1038 | static void setpause (global_State *g) { | 1038 | static 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 | */ |
1602 | static void incstep (lua_State *L, global_State *g) { | 1602 | static 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 | ||