commit d0815046d003f8f24efcdb03d35dd125ddd3b5f9
parent 3d54b42d59bcc1b31a369f3497ac22745d63cae6
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 18 Oct 2024 17:09:53 -0300
Some adjustments in transition minor->major
Plus extra comments and other details.
Diffstat:
M | lgc.c | | | 78 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
M | manual/manual.of | | | 5 | ++++- |
2 files changed, 46 insertions(+), 37 deletions(-)
diff --git a/lgc.c b/lgc.c
@@ -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);
}
}
diff --git a/manual/manual.of b/manual/manual.of
@@ -719,6 +719,8 @@ than the total after the previous major collection.
For instance, for a multiplier of 100,
the collector will do a major collection when the number of old bytes
gets larger than twice the total after the previous major collection.
+As a special case,
+a value of 0 stops the collector from doing major collections.
The major-minor multiplier controls the shift back to minor collections.
For a multiplier @M{x},
@@ -6441,7 +6443,8 @@ Changes the collector mode to generational and returns the previous mode.
Changes and/or retrieves the values of a parameter of the collector.
This option must be followed by one or two extra arguments:
The name of the parameter being changed or retrieved (a string)
-and an optional new value for that parameter (an integer).
+and an optional new value for that parameter,
+an integer in the range @M{[0,100000]}.
The first argument must have one of the following values:
@description{
@item{@St{minormul}| The minor multiplier. }