From 5d8b5b9290c932bdfd7dcc670a5af957bdd58392 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 13 Dec 2022 15:45:57 -0300 Subject: [PATCH] Changed signal of GC debt Positive debts seems more natural then negative ones. --- lapi.c | 8 ++++---- lgc.c | 16 ++++++++-------- lgc.h | 4 ++-- llimits.h | 7 ++----- lstate.c | 6 +++--- lstate.h | 6 +++--- 6 files changed, 22 insertions(+), 25 deletions(-) diff --git a/lapi.c b/lapi.c index 8c70bd4c..b2ac0c57 100644 --- a/lapi.c +++ b/lapi.c @@ -1168,8 +1168,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { 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) */ + while (todo >= g->GCdebt) { /* enough to run a step? */ + todo -= g->GCdebt; /* decrement 'todo' */ luaC_step(L); /* run one basic step */ didsomething = 1; if (g->gckind == KGC_GEN) /* minor collections? */ @@ -1177,8 +1177,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { 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); + /* remove remaining 'todo' from total debt */ + luaE_setdebt(g, g->GCdebt - todo); g->gcstp = oldstp; /* restore previous state */ if (didsomething && g->gcstate == GCSpause) /* end of cycle? */ res = 1; /* signal it */ diff --git a/lgc.c b/lgc.c index 90a49091..27856650 100644 --- a/lgc.c +++ b/lgc.c @@ -242,7 +242,7 @@ GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) { global_State *g = G(L); char *p = cast_charp(luaM_newobject(L, novariant(tt), sz)); GCObject *o = cast(GCObject *, p + offset); - g->GCdebt++; + g->GCdebt--; o->marked = luaC_white(g); o->tt = tt; o->next = g->allgc; @@ -1034,8 +1034,8 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { */ static void setpause (global_State *g) { l_obj threshold = applygcparam(g, gcpause, g->marked); - l_obj debt = gettotalobjs(g) - threshold; - if (debt > 0) debt = 0; + l_obj debt = threshold - gettotalobjs(g); + if (debt < 0) debt = 0; luaE_setdebt(g, debt); } @@ -1285,7 +1285,7 @@ static void atomic2gen (lua_State *L, global_State *g) { ** total number of objects grows 'genminormul'%. */ static void setminordebt (global_State *g) { - luaE_setdebt(g, -applygcparam(g, genminormul, gettotalobjs(g))); + luaE_setdebt(g, applygcparam(g, genminormul, gettotalobjs(g))); } @@ -1378,13 +1378,13 @@ static void genmajorstep (lua_State *L, global_State *g) { ** Does a generational "step". If the total number of objects grew ** more than 'majormul'% since the last major collection, does a ** major collection. Otherwise, does a minor collection. The test -** ('GCdebt' > 0) avoids major collections when the step originated from +** ('GCdebt' != 0) avoids major collections when the step originated from ** 'collectgarbage("step")'. */ static void genstep (lua_State *L, global_State *g) { l_obj majorbase = g->GClastmajor; /* count after last major collection */ l_obj majorinc = applygcparam(g, genmajormul, majorbase); - if (g->GCdebt > 0 && gettotalobjs(g) > majorbase + majorinc) { + if (g->GCdebt != 0 && gettotalobjs(g) > majorbase + majorinc) { /* do a major collection */ enterinc(g); g->gckind = KGC_GENMAJOR; @@ -1605,7 +1605,7 @@ static void incstep (lua_State *L, global_State *g) { if (g->gcstate == GCSpause) setpause(g); /* pause until next cycle */ else { - luaE_setdebt(g, -stepsize); + luaE_setdebt(g, stepsize); } } @@ -1618,7 +1618,7 @@ void luaC_step (lua_State *L) { global_State *g = G(L); lua_assert(!g->gcemergency); if (!gcrunning(g)) /* not running? */ - luaE_setdebt(g, -2000); + luaE_setdebt(g, 2000); else { switch (g->gckind) { case KGC_INC: diff --git a/lgc.h b/lgc.h index 6d82690d..c8f7c6e6 100644 --- a/lgc.h +++ b/lgc.h @@ -175,13 +175,13 @@ /* -** Does one step of collection when debt becomes positive. 'pre'/'pos' +** Does one step of collection when debt becomes zero. 'pre'/'pos' ** allows some adjustments to be done only when needed. macro ** 'condchangemem' is used only for heavy tests (forcing a full ** GC cycle on every opportunity) */ #define luaC_condGC(L,pre,pos) \ - { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ + { if (G(L)->GCdebt <= 0) { pre; luaC_step(L); pos;}; \ condchangemem(L,pre,pos); } /* more often than not, 'pre'/'pos' are empty */ diff --git a/llimits.h b/llimits.h index e4948791..246dca8b 100644 --- a/llimits.h +++ b/llimits.h @@ -33,6 +33,8 @@ typedef unsigned long lu_mem; typedef long l_obj; #endif /* } */ +#define MAX_LOBJ cast(l_obj, ~cast(lu_mem, 0) >> 1) + /* chars used as small naturals (so that 'char' is reserved for characters) */ typedef unsigned char lu_byte; @@ -47,11 +49,6 @@ typedef signed char ls_byte; : (size_t)(LUA_MAXINTEGER)) -#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) - -#define MAX_LMEM ((l_obj)(MAX_LUMEM >> 1)) - - #define MAX_INT INT_MAX /* maximum value of an int */ diff --git a/lstate.c b/lstate.c index b9897d96..bee3bf66 100644 --- a/lstate.c +++ b/lstate.c @@ -89,9 +89,9 @@ static unsigned int luai_makeseed (lua_State *L) { void luaE_setdebt (global_State *g, l_obj debt) { l_obj tb = gettotalobjs(g); lua_assert(tb > 0); - if (debt < tb - MAX_LMEM) - debt = tb - MAX_LMEM; /* will make 'totalobjs == MAX_LMEM' */ - g->totalobjs = tb - debt; + if (debt > MAX_LOBJ - tb) + debt = MAX_LOBJ - tb; /* will make 'totalobjs == MAX_LMEM' */ + g->totalobjs = tb + debt; g->GCdebt = debt; } diff --git a/lstate.h b/lstate.h index c290ff32..1aef2f75 100644 --- a/lstate.h +++ b/lstate.h @@ -251,8 +251,8 @@ typedef struct global_State { lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to 'frealloc' */ lu_mem totalbytes; /* number of bytes currently allocated */ - l_obj totalobjs; /* total number of objects allocated - GCdebt */ - l_obj GCdebt; /* bytes allocated not yet compensated by the collector */ + l_obj totalobjs; /* total number of objects allocated + GCdebt */ + l_obj GCdebt; /* objects counted but not yet allocated */ l_obj marked; /* number of objects marked in a GC cycle */ l_obj GClastmajor; /* objects at last major collection */ stringtable strt; /* hash table for strings */ @@ -388,7 +388,7 @@ union GCUnion { /* actual number of total objects allocated */ -#define gettotalobjs(g) ((g)->totalobjs + (g)->GCdebt) +#define gettotalobjs(g) ((g)->totalobjs - (g)->GCdebt) LUAI_FUNC void luaE_setdebt (global_State *g, l_obj debt);