Some adjustments in transition minor->major

Plus extra comments and other details.
This commit is contained in:
Roberto Ierusalimschy
2024-10-18 17:10:20 -03:00
parent 3d54b42d59
commit d0815046d0
2 changed files with 46 additions and 37 deletions

78
lgc.c
View File

@@ -424,10 +424,8 @@ static void cleargraylists (global_State *g) {
/*
** mark root set and reset all gray lists, to start a new collection.
** 'marked' is initialized with the number of fixed objects in the state,
** to count the total number of live objects during a cycle. (That is
** the metafield names, plus the reserved words, plus "_ENV" plus the
** memory-error message.)
** 'GCmarked' is initialized to count the total number of live bytes
** during a cycle.
*/
static void restartcollection (global_State *g) {
cleargraylists(g);
@@ -1067,10 +1065,25 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
** =======================================================
*/
/*
** Fields 'GCmarked' and 'GCmajorminor' are used to control the pace and
** the mode of the collector. They play several roles, depending on the
** mode of the collector:
** * KGC_INC:
** GCmarked: number of marked bytes during a cycle.
** GCmajorminor: not used.
** * KGC_GENMINOR
** GCmarked: number of bytes that became old since last major collection.
** GCmajorminor: number of bytes marked in last major collection.
** * KGC_GENMAJOR
** GCmarked: number of bytes that became old sinse last major collection.
** GCmajorminor: number of bytes marked in last major collection.
*/
/*
** Set the "time" to wait before starting a new incremental cycle;
** cycle will start when number of objects in use hits the threshold of
** cycle will start when number of bytes in use hits the threshold of
** approximately (marked * pause / 100).
*/
static void setpause (global_State *g) {
@@ -1258,7 +1271,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
** in generational mode.
*/
static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
g->GCmajorminor = g->GCmarked; /* number of live objects */
g->GCmajorminor = g->GCmarked; /* number of live bytes */
g->gckind = kind;
g->reallyold = g->old1 = g->survival = NULL;
g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
@@ -1269,21 +1282,16 @@ static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
/*
** Decide whether to shift to major mode. It tests two conditions:
** 1) Whether the number of added old objects in this collection is more
** than half the number of new objects. ('step' is equal to the debt set
** to trigger the next minor collection; that is equal to the number
** of objects created since the previous minor collection. Except for
** forward barriers, it is the maximum number of objects that can become
** old in each minor collection.)
** 2) Whether the accumulated number of added old objects is larger
** than 'minormajor'% of the number of lived objects after the last
** major collection. (That percentage is computed in 'limit'.)
** Decide whether to shift to major mode. It shifts if the accumulated
** number of added old bytes (counted in 'GCmarked') is larger than
** 'minormajor'% of the number of lived bytes after the last major
** collection. (This number is kept in 'GCmajorminor'.)
*/
static int checkminormajor (global_State *g, l_mem addedold1) {
l_mem step = applygcparam(g, MINORMUL, g->GCmajorminor);
static int checkminormajor (global_State *g) {
l_mem limit = applygcparam(g, MINORMAJOR, g->GCmajorminor);
return (addedold1 >= (step >> 1) || g->GCmarked >= limit);
if (limit == 0)
return 0; /* special case: 'minormajor' 0 stops major collections */
return (g->GCmarked >= limit);
}
/*
@@ -1326,13 +1334,13 @@ static void youngcollection (lua_State *L, global_State *g) {
sweepgen(L, g, &g->tobefnz, NULL, &dummy, &addedold1);
/* keep total number of added old1 objects */
/* keep total number of added old1 bytes */
g->GCmarked = marked + addedold1;
/* decide whether to shift to major mode */
if (checkminormajor(g, addedold1)) {
if (checkminormajor(g)) {
minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
g->GCmarked = 0; /* avoid pause in first major cycle */
g->GCmarked = 0; /* avoid pause in first major cycle (see 'setpause') */
}
else
finishgencycle(L, g); /* still in minor mode; finish it */
@@ -1361,8 +1369,8 @@ static void atomic2gen (lua_State *L, global_State *g) {
sweep2old(L, &g->tobefnz);
g->gckind = KGC_GENMINOR;
g->GCmajorminor = g->GCmarked; /* "base" for number of objects */
g->GCmarked = 0; /* to count the number of added old1 objects */
g->GCmajorminor = g->GCmarked; /* "base" for number of bytes */
g->GCmarked = 0; /* to count the number of added old1 bytes */
finishgencycle(L, g);
}
@@ -1423,15 +1431,15 @@ static void fullgen (lua_State *L, global_State *g) {
/*
** After an atomic incremental step from a major collection,
** check whether collector could return to minor collections.
** It checks whether the number of objects 'tobecollected'
** is greater than 'majorminor'% of the number of objects added
** since the last collection ('addedobjs').
** It checks whether the number of bytes 'tobecollected'
** is greater than 'majorminor'% of the number of bytes added
** since the last collection ('addedbytes').
*/
static int checkmajorminor (lua_State *L, global_State *g) {
if (g->gckind == KGC_GENMAJOR) { /* generational mode? */
l_mem numbytes = gettotalbytes(g);
l_mem addedobjs = numbytes - g->GCmajorminor;
l_mem limit = applygcparam(g, MAJORMINOR, addedobjs);
l_mem addedbytes = numbytes - g->GCmajorminor;
l_mem limit = applygcparam(g, MAJORMINOR, addedbytes);
l_mem tobecollected = numbytes - g->GCmarked;
if (tobecollected > limit) {
atomic2gen(L, g); /* return to generational mode */
@@ -1670,9 +1678,7 @@ static void incstep (lua_State *L, global_State *g) {
l_mem work2do = applygcparam(g, STEPMUL, stepsize);
l_mem stres;
int fast = (work2do == 0); /* special case: do a full collection */
//printf("\n** %ld %ld %d\n", work2do, stepsize, g->gcstate);
do { /* repeat until enough work */
//printf("%d-", g->gcstate);
stres = singlestep(L, fast); /* perform one single step */
if (stres == step2minor) /* returned to minor collections? */
return; /* nothing else to be done here */
@@ -1688,6 +1694,10 @@ static void incstep (lua_State *L, global_State *g) {
}
#if !defined(luai_tracegc)
#define luai_tracegc(L) ((void)0)
#endif
/*
** Performs a basic GC step if collector is running. (If collector is
** not running, set a reasonable debt to avoid it being called at
@@ -1699,20 +1709,16 @@ void luaC_step (lua_State *L) {
if (!gcrunning(g)) /* not running? */
luaE_setdebt(g, 20000);
else {
//printf("mem: %ld kind: %s ", gettotalbytes(g),
// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" :
// "genminor");
luai_tracegc(L); /* for internal debugging */
switch (g->gckind) {
case KGC_INC: case KGC_GENMAJOR:
incstep(L, g);
//printf("%d) ", g->gcstate);
break;
case KGC_GENMINOR:
youngcollection(L, g);
setminordebt(g);
break;
}
//printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt);
}
}