aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-08-23 16:06:23 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-08-23 16:06:23 -0300
commita1f77a234a053da46b06d5d4be00ffb30d3eb45b (patch)
tree38c6e136763628e8a2e9f4bb2b325f0db8481456
parentc6cea857a4845940c833e39a149d20bb64a9af85 (diff)
downloadlua-a1f77a234a053da46b06d5d4be00ffb30d3eb45b.tar.gz
lua-a1f77a234a053da46b06d5d4be00ffb30d3eb45b.tar.bz2
lua-a1f77a234a053da46b06d5d4be00ffb30d3eb45b.zip
Bug: set correct pause when (re)entering gen. collection.
-rw-r--r--lgc.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/lgc.c b/lgc.c
index 42a73d81..317ea450 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1041,7 +1041,25 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
1041** ======================================================= 1041** =======================================================
1042*/ 1042*/
1043 1043
1044static void setpause (global_State *g); 1044
1045/*
1046** Set the "time" to wait before starting a new GC cycle; cycle will
1047** start when memory use hits the threshold of ('estimate' * pause /
1048** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero,
1049** because Lua cannot even start with less than PAUSEADJ bytes).
1050*/
1051static void setpause (global_State *g) {
1052 l_mem threshold, debt;
1053 int pause = getgcparam(g->gcpause);
1054 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
1055 lua_assert(estimate > 0);
1056 threshold = (pause < MAX_LMEM / estimate) /* overflow? */
1057 ? estimate * pause /* no overflow */
1058 : MAX_LMEM; /* overflow; truncate to maximum */
1059 debt = gettotalbytes(g) - threshold;
1060 if (debt > 0) debt = 0;
1061 luaE_setdebt(g, debt);
1062}
1045 1063
1046 1064
1047/* 1065/*
@@ -1286,6 +1304,15 @@ static void atomic2gen (lua_State *L, global_State *g) {
1286 1304
1287 1305
1288/* 1306/*
1307** Set debt for the next minor collection, which will happen when
1308** memory grows 'genminormul'%.
1309*/
1310static void setminordebt (global_State *g) {
1311 luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul));
1312}
1313
1314
1315/*
1289** Enter generational mode. Must go until the end of an atomic cycle 1316** Enter generational mode. Must go until the end of an atomic cycle
1290** to ensure that all objects are correctly marked and weak tables 1317** to ensure that all objects are correctly marked and weak tables
1291** are cleared. Then, turn all objects into old and finishes the 1318** are cleared. Then, turn all objects into old and finishes the
@@ -1297,6 +1324,7 @@ static lu_mem entergen (lua_State *L, global_State *g) {
1297 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ 1324 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
1298 numobjs = atomic(L); /* propagates all and then do the atomic stuff */ 1325 numobjs = atomic(L); /* propagates all and then do the atomic stuff */
1299 atomic2gen(L, g); 1326 atomic2gen(L, g);
1327 setminordebt(g); /* set debt assuming next cycle will be minor */
1300 return numobjs; 1328 return numobjs;
1301} 1329}
1302 1330
@@ -1343,15 +1371,6 @@ static lu_mem fullgen (lua_State *L, global_State *g) {
1343 1371
1344 1372
1345/* 1373/*
1346** Set debt for the next minor collection, which will happen when
1347** memory grows 'genminormul'%.
1348*/
1349static void setminordebt (global_State *g) {
1350 luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul));
1351}
1352
1353
1354/*
1355** Does a major collection after last collection was a "bad collection". 1374** Does a major collection after last collection was a "bad collection".
1356** 1375**
1357** When the program is building a big structure, it allocates lots of 1376** When the program is building a big structure, it allocates lots of
@@ -1422,8 +1441,8 @@ static void genstep (lua_State *L, global_State *g) {
1422 lu_mem numobjs = fullgen(L, g); /* do a major collection */ 1441 lu_mem numobjs = fullgen(L, g); /* do a major collection */
1423 if (gettotalbytes(g) < majorbase + (majorinc / 2)) { 1442 if (gettotalbytes(g) < majorbase + (majorinc / 2)) {
1424 /* collected at least half of memory growth since last major 1443 /* collected at least half of memory growth since last major
1425 collection; keep doing minor collections */ 1444 collection; keep doing minor collections. */
1426 setminordebt(g); 1445 lua_assert(g->lastatomic == 0);
1427 } 1446 }
1428 else { /* bad collection */ 1447 else { /* bad collection */
1429 g->lastatomic = numobjs; /* signal that last collection was bad */ 1448 g->lastatomic = numobjs; /* signal that last collection was bad */
@@ -1450,26 +1469,6 @@ static void genstep (lua_State *L, global_State *g) {
1450 1469
1451 1470
1452/* 1471/*
1453** Set the "time" to wait before starting a new GC cycle; cycle will
1454** start when memory use hits the threshold of ('estimate' * pause /
1455** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero,
1456** because Lua cannot even start with less than PAUSEADJ bytes).
1457*/
1458static void setpause (global_State *g) {
1459 l_mem threshold, debt;
1460 int pause = getgcparam(g->gcpause);
1461 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
1462 lua_assert(estimate > 0);
1463 threshold = (pause < MAX_LMEM / estimate) /* overflow? */
1464 ? estimate * pause /* no overflow */
1465 : MAX_LMEM; /* overflow; truncate to maximum */
1466 debt = gettotalbytes(g) - threshold;
1467 if (debt > 0) debt = 0;
1468 luaE_setdebt(g, debt);
1469}
1470
1471
1472/*
1473** Enter first sweep phase. 1472** Enter first sweep phase.
1474** The call to 'sweeptolive' makes the pointer point to an object 1473** The call to 'sweeptolive' makes the pointer point to an object
1475** inside the list (instead of to the header), so that the real sweep do 1474** inside the list (instead of to the header), so that the real sweep do