diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-10-18 17:10:20 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-10-18 17:10:20 -0300 |
commit | d0815046d003f8f24efcdb03d35dd125ddd3b5f9 (patch) | |
tree | a1b6a63f16287957bcb2b6a79e003ebb723617fc | |
parent | 3d54b42d59bcc1b31a369f3497ac22745d63cae6 (diff) | |
download | lua-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.c | 78 | ||||
-rw-r--r-- | manual/manual.of | 5 |
2 files changed, 46 insertions, 37 deletions
@@ -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 | */ |
432 | static void restartcollection (global_State *g) { | 430 | static 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 | */ |
1076 | static void setpause (global_State *g) { | 1089 | static 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 | */ |
1260 | static void minor2inc (lua_State *L, global_State *g, lu_byte kind) { | 1273 | static 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 | */ |
1283 | static int checkminormajor (global_State *g, l_mem addedold1) { | 1290 | static 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 | */ |
1430 | static int checkmajorminor (lua_State *L, global_State *g) { | 1438 | static 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. | |||
719 | For instance, for a multiplier of 100, | 719 | For instance, for a multiplier of 100, |
720 | the collector will do a major collection when the number of old bytes | 720 | the collector will do a major collection when the number of old bytes |
721 | gets larger than twice the total after the previous major collection. | 721 | gets larger than twice the total after the previous major collection. |
722 | As a special case, | ||
723 | a value of 0 stops the collector from doing major collections. | ||
722 | 724 | ||
723 | The major-minor multiplier controls the shift back to minor collections. | 725 | The major-minor multiplier controls the shift back to minor collections. |
724 | For a multiplier @M{x}, | 726 | For a multiplier @M{x}, |
@@ -6441,7 +6443,8 @@ Changes the collector mode to generational and returns the previous mode. | |||
6441 | Changes and/or retrieves the values of a parameter of the collector. | 6443 | Changes and/or retrieves the values of a parameter of the collector. |
6442 | This option must be followed by one or two extra arguments: | 6444 | This option must be followed by one or two extra arguments: |
6443 | The name of the parameter being changed or retrieved (a string) | 6445 | The name of the parameter being changed or retrieved (a string) |
6444 | and an optional new value for that parameter (an integer). | 6446 | and an optional new value for that parameter, |
6447 | an integer in the range @M{[0,100000]}. | ||
6445 | The first argument must have one of the following values: | 6448 | The 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. } |