aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-10-18 17:10:20 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-10-18 17:10:20 -0300
commitd0815046d003f8f24efcdb03d35dd125ddd3b5f9 (patch)
treea1b6a63f16287957bcb2b6a79e003ebb723617fc
parent3d54b42d59bcc1b31a369f3497ac22745d63cae6 (diff)
downloadlua-d0815046d003f8f24efcdb03d35dd125ddd3b5f9.tar.gz
lua-d0815046d003f8f24efcdb03d35dd125ddd3b5f9.tar.bz2
lua-d0815046d003f8f24efcdb03d35dd125ddd3b5f9.zip
Some adjustments in transition minor->major
Plus extra comments and other details.
-rw-r--r--lgc.c78
-rw-r--r--manual/manual.of5
2 files changed, 46 insertions, 37 deletions
diff --git a/lgc.c b/lgc.c
index e154402b..58d0bf7d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -424,10 +424,8 @@ static void cleargraylists (global_State *g) {
424 424
425/* 425/*
426** mark root set and reset all gray lists, to start a new collection. 426** mark root set and reset all gray lists, to start a new collection.
427** 'marked' is initialized with the number of fixed objects in the state, 427** 'GCmarked' is initialized to count the total number of live bytes
428** to count the total number of live objects during a cycle. (That is 428** during a cycle.
429** the metafield names, plus the reserved words, plus "_ENV" plus the
430** memory-error message.)
431*/ 429*/
432static void restartcollection (global_State *g) { 430static void restartcollection (global_State *g) {
433 cleargraylists(g); 431 cleargraylists(g);
@@ -1067,10 +1065,25 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
1067** ======================================================= 1065** =======================================================
1068*/ 1066*/
1069 1067
1068/*
1069** Fields 'GCmarked' and 'GCmajorminor' are used to control the pace and
1070** the mode of the collector. They play several roles, depending on the
1071** mode of the collector:
1072** * KGC_INC:
1073** GCmarked: number of marked bytes during a cycle.
1074** GCmajorminor: not used.
1075** * KGC_GENMINOR
1076** GCmarked: number of bytes that became old since last major collection.
1077** GCmajorminor: number of bytes marked in last major collection.
1078** * KGC_GENMAJOR
1079** GCmarked: number of bytes that became old sinse last major collection.
1080** GCmajorminor: number of bytes marked in last major collection.
1081*/
1082
1070 1083
1071/* 1084/*
1072** Set the "time" to wait before starting a new incremental cycle; 1085** Set the "time" to wait before starting a new incremental cycle;
1073** cycle will start when number of objects in use hits the threshold of 1086** cycle will start when number of bytes in use hits the threshold of
1074** approximately (marked * pause / 100). 1087** approximately (marked * pause / 100).
1075*/ 1088*/
1076static void setpause (global_State *g) { 1089static void setpause (global_State *g) {
@@ -1258,7 +1271,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
1258** in generational mode. 1271** in generational mode.
1259*/ 1272*/
1260static void minor2inc (lua_State *L, global_State *g, lu_byte kind) { 1273static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
1261 g->GCmajorminor = g->GCmarked; /* number of live objects */ 1274 g->GCmajorminor = g->GCmarked; /* number of live bytes */
1262 g->gckind = kind; 1275 g->gckind = kind;
1263 g->reallyold = g->old1 = g->survival = NULL; 1276 g->reallyold = g->old1 = g->survival = NULL;
1264 g->finobjrold = g->finobjold1 = g->finobjsur = NULL; 1277 g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
@@ -1269,21 +1282,16 @@ static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
1269 1282
1270 1283
1271/* 1284/*
1272** Decide whether to shift to major mode. It tests two conditions: 1285** Decide whether to shift to major mode. It shifts if the accumulated
1273** 1) Whether the number of added old objects in this collection is more 1286** number of added old bytes (counted in 'GCmarked') is larger than
1274** than half the number of new objects. ('step' is equal to the debt set 1287** 'minormajor'% of the number of lived bytes after the last major
1275** to trigger the next minor collection; that is equal to the number 1288** collection. (This number is kept in 'GCmajorminor'.)
1276** of objects created since the previous minor collection. Except for
1277** forward barriers, it is the maximum number of objects that can become
1278** old in each minor collection.)
1279** 2) Whether the accumulated number of added old objects is larger
1280** than 'minormajor'% of the number of lived objects after the last
1281** major collection. (That percentage is computed in 'limit'.)
1282*/ 1289*/
1283static int checkminormajor (global_State *g, l_mem addedold1) { 1290static int checkminormajor (global_State *g) {
1284 l_mem step = applygcparam(g, MINORMUL, g->GCmajorminor);
1285 l_mem limit = applygcparam(g, MINORMAJOR, g->GCmajorminor); 1291 l_mem limit = applygcparam(g, MINORMAJOR, g->GCmajorminor);
1286 return (addedold1 >= (step >> 1) || g->GCmarked >= limit); 1292 if (limit == 0)
1293 return 0; /* special case: 'minormajor' 0 stops major collections */
1294 return (g->GCmarked >= limit);
1287} 1295}
1288 1296
1289/* 1297/*
@@ -1326,13 +1334,13 @@ static void youngcollection (lua_State *L, global_State *g) {
1326 1334
1327 sweepgen(L, g, &g->tobefnz, NULL, &dummy, &addedold1); 1335 sweepgen(L, g, &g->tobefnz, NULL, &dummy, &addedold1);
1328 1336
1329 /* keep total number of added old1 objects */ 1337 /* keep total number of added old1 bytes */
1330 g->GCmarked = marked + addedold1; 1338 g->GCmarked = marked + addedold1;
1331 1339
1332 /* decide whether to shift to major mode */ 1340 /* decide whether to shift to major mode */
1333 if (checkminormajor(g, addedold1)) { 1341 if (checkminormajor(g)) {
1334 minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */ 1342 minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
1335 g->GCmarked = 0; /* avoid pause in first major cycle */ 1343 g->GCmarked = 0; /* avoid pause in first major cycle (see 'setpause') */
1336 } 1344 }
1337 else 1345 else
1338 finishgencycle(L, g); /* still in minor mode; finish it */ 1346 finishgencycle(L, g); /* still in minor mode; finish it */
@@ -1361,8 +1369,8 @@ static void atomic2gen (lua_State *L, global_State *g) {
1361 sweep2old(L, &g->tobefnz); 1369 sweep2old(L, &g->tobefnz);
1362 1370
1363 g->gckind = KGC_GENMINOR; 1371 g->gckind = KGC_GENMINOR;
1364 g->GCmajorminor = g->GCmarked; /* "base" for number of objects */ 1372 g->GCmajorminor = g->GCmarked; /* "base" for number of bytes */
1365 g->GCmarked = 0; /* to count the number of added old1 objects */ 1373 g->GCmarked = 0; /* to count the number of added old1 bytes */
1366 finishgencycle(L, g); 1374 finishgencycle(L, g);
1367} 1375}
1368 1376
@@ -1423,15 +1431,15 @@ static void fullgen (lua_State *L, global_State *g) {
1423/* 1431/*
1424** After an atomic incremental step from a major collection, 1432** After an atomic incremental step from a major collection,
1425** check whether collector could return to minor collections. 1433** check whether collector could return to minor collections.
1426** It checks whether the number of objects 'tobecollected' 1434** It checks whether the number of bytes 'tobecollected'
1427** is greater than 'majorminor'% of the number of objects added 1435** is greater than 'majorminor'% of the number of bytes added
1428** since the last collection ('addedobjs'). 1436** since the last collection ('addedbytes').
1429*/ 1437*/
1430static int checkmajorminor (lua_State *L, global_State *g) { 1438static int checkmajorminor (lua_State *L, global_State *g) {
1431 if (g->gckind == KGC_GENMAJOR) { /* generational mode? */ 1439 if (g->gckind == KGC_GENMAJOR) { /* generational mode? */
1432 l_mem numbytes = gettotalbytes(g); 1440 l_mem numbytes = gettotalbytes(g);
1433 l_mem addedobjs = numbytes - g->GCmajorminor; 1441 l_mem addedbytes = numbytes - g->GCmajorminor;
1434 l_mem limit = applygcparam(g, MAJORMINOR, addedobjs); 1442 l_mem limit = applygcparam(g, MAJORMINOR, addedbytes);
1435 l_mem tobecollected = numbytes - g->GCmarked; 1443 l_mem tobecollected = numbytes - g->GCmarked;
1436 if (tobecollected > limit) { 1444 if (tobecollected > limit) {
1437 atomic2gen(L, g); /* return to generational mode */ 1445 atomic2gen(L, g); /* return to generational mode */
@@ -1670,9 +1678,7 @@ static void incstep (lua_State *L, global_State *g) {
1670 l_mem work2do = applygcparam(g, STEPMUL, stepsize); 1678 l_mem work2do = applygcparam(g, STEPMUL, stepsize);
1671 l_mem stres; 1679 l_mem stres;
1672 int fast = (work2do == 0); /* special case: do a full collection */ 1680 int fast = (work2do == 0); /* special case: do a full collection */
1673//printf("\n** %ld %ld %d\n", work2do, stepsize, g->gcstate);
1674 do { /* repeat until enough work */ 1681 do { /* repeat until enough work */
1675//printf("%d-", g->gcstate);
1676 stres = singlestep(L, fast); /* perform one single step */ 1682 stres = singlestep(L, fast); /* perform one single step */
1677 if (stres == step2minor) /* returned to minor collections? */ 1683 if (stres == step2minor) /* returned to minor collections? */
1678 return; /* nothing else to be done here */ 1684 return; /* nothing else to be done here */
@@ -1688,6 +1694,10 @@ static void incstep (lua_State *L, global_State *g) {
1688} 1694}
1689 1695
1690 1696
1697#if !defined(luai_tracegc)
1698#define luai_tracegc(L) ((void)0)
1699#endif
1700
1691/* 1701/*
1692** Performs a basic GC step if collector is running. (If collector is 1702** Performs a basic GC step if collector is running. (If collector is
1693** not running, set a reasonable debt to avoid it being called at 1703** not running, set a reasonable debt to avoid it being called at
@@ -1699,20 +1709,16 @@ void luaC_step (lua_State *L) {
1699 if (!gcrunning(g)) /* not running? */ 1709 if (!gcrunning(g)) /* not running? */
1700 luaE_setdebt(g, 20000); 1710 luaE_setdebt(g, 20000);
1701 else { 1711 else {
1702//printf("mem: %ld kind: %s ", gettotalbytes(g), 1712 luai_tracegc(L); /* for internal debugging */
1703// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" :
1704// "genminor");
1705 switch (g->gckind) { 1713 switch (g->gckind) {
1706 case KGC_INC: case KGC_GENMAJOR: 1714 case KGC_INC: case KGC_GENMAJOR:
1707 incstep(L, g); 1715 incstep(L, g);
1708//printf("%d) ", g->gcstate);
1709 break; 1716 break;
1710 case KGC_GENMINOR: 1717 case KGC_GENMINOR:
1711 youngcollection(L, g); 1718 youngcollection(L, g);
1712 setminordebt(g); 1719 setminordebt(g);
1713 break; 1720 break;
1714 } 1721 }
1715//printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt);
1716 } 1722 }
1717} 1723}
1718 1724
diff --git a/manual/manual.of b/manual/manual.of
index c93fbfcb..6947b2a0 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -719,6 +719,8 @@ than the total after the previous major collection.
719For instance, for a multiplier of 100, 719For instance, for a multiplier of 100,
720the collector will do a major collection when the number of old bytes 720the collector will do a major collection when the number of old bytes
721gets larger than twice the total after the previous major collection. 721gets larger than twice the total after the previous major collection.
722As a special case,
723a value of 0 stops the collector from doing major collections.
722 724
723The major-minor multiplier controls the shift back to minor collections. 725The major-minor multiplier controls the shift back to minor collections.
724For a multiplier @M{x}, 726For a multiplier @M{x},
@@ -6441,7 +6443,8 @@ Changes the collector mode to generational and returns the previous mode.
6441Changes and/or retrieves the values of a parameter of the collector. 6443Changes and/or retrieves the values of a parameter of the collector.
6442This option must be followed by one or two extra arguments: 6444This option must be followed by one or two extra arguments:
6443The name of the parameter being changed or retrieved (a string) 6445The name of the parameter being changed or retrieved (a string)
6444and an optional new value for that parameter (an integer). 6446and an optional new value for that parameter,
6447an integer in the range @M{[0,100000]}.
6445The first argument must have one of the following values: 6448The first argument must have one of the following values:
6446@description{ 6449@description{
6447@item{@St{minormul}| The minor multiplier. } 6450@item{@St{minormul}| The minor multiplier. }