aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-12-07 15:45:11 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-12-07 15:45:11 -0300
commit925fe8a0f2a667c96c015ee74d1a702af9ea5507 (patch)
treebca1cb92e11218498f4c76f651f4a5fa1a8c87b5 /lgc.c
parent789e7acdea3ada96bd00b7aac6d82e805bfee85c (diff)
downloadlua-925fe8a0f2a667c96c015ee74d1a702af9ea5507.tar.gz
lua-925fe8a0f2a667c96c015ee74d1a702af9ea5507.tar.bz2
lua-925fe8a0f2a667c96c015ee74d1a702af9ea5507.zip
First criteria for shifts minor<->major
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/lgc.c b/lgc.c
index 50e6e0e9..a4f63765 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1205,20 +1205,21 @@ static void correctgraylists (global_State *g) {
1205/* 1205/*
1206** Mark black 'OLD1' objects when starting a new young collection. 1206** Mark black 'OLD1' objects when starting a new young collection.
1207** Gray objects are already in some gray list, and so will be visited in 1207** Gray objects are already in some gray list, and so will be visited in
1208** the atomic step. The counter 'GCmajorminor' keeps how many objects to 1208** the atomic step. Returns the number of objects that became old.
1209** become old before a major collection.
1210*/ 1209*/
1211static void markold (global_State *g, GCObject *from, GCObject *to) { 1210static l_obj markold (global_State *g, GCObject *from, GCObject *to) {
1212 GCObject *p; 1211 GCObject *p;
1212 l_obj count = 0;
1213 for (p = from; p != to; p = p->next) { 1213 for (p = from; p != to; p = p->next) {
1214 if (getage(p) == G_OLD1) { 1214 if (getage(p) == G_OLD1) {
1215 lua_assert(!iswhite(p)); 1215 lua_assert(!iswhite(p));
1216 setage(p, G_OLD); /* now they are old */ 1216 setage(p, G_OLD); /* now they are old */
1217 g->GCmajorminor--; /* one more old object */ 1217 count++; /* one more old object */
1218 if (isblack(p)) 1218 if (isblack(p))
1219 reallymarkobject(g, p); 1219 reallymarkobject(g, p);
1220 } 1220 }
1221 } 1221 }
1222 return count;
1222} 1223}
1223 1224
1224 1225
@@ -1240,7 +1241,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
1240*/ 1241*/
1241static void atomic2major (lua_State *L, global_State *g) { 1242static void atomic2major (lua_State *L, global_State *g) {
1242 l_obj stepsize = cast(l_obj, 1) << g->gcstepsize; 1243 l_obj stepsize = cast(l_obj, 1) << g->gcstepsize;
1243 g->GCmajorminor = gettotalobjs(g); 1244 g->GCmajorminor = g->marked; /* number of live objects */
1244 g->gckind = KGC_GENMAJOR; 1245 g->gckind = KGC_GENMAJOR;
1245 g->reallyold = g->old1 = g->survival = NULL; 1246 g->reallyold = g->old1 = g->survival = NULL;
1246 g->finobjrold = g->finobjold1 = g->finobjsur = NULL; 1247 g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
@@ -1250,29 +1251,53 @@ static void atomic2major (lua_State *L, global_State *g) {
1250 1251
1251 1252
1252/* 1253/*
1254** Decide whether to shift to major mode. It tests two conditions:
1255** 1) Whether the number of added old objects in this collection is more
1256** than half the number of new objects. ("step" is the number of objects
1257** created between minor collections. Except for forward barriers, it
1258** is the maximum number of objects that can become old in each minor
1259** collection.)
1260** 2) Whether the accumulated number of added old objects is larger
1261** than 'minormajor'% of the number of lived objects after the last
1262** major collection. (That percentage is computed in 'limit'.)
1263*/
1264static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) {
1265 l_obj step = applygcparam(g, genminormul, g->GCmajorminor);
1266 l_obj limit = applygcparam(g, minormajor, g->GCmajorminor);
1267//printf("-> major? %ld %ld %ld %ld (%ld)\n", g->marked, limit, step, addedold1, gettotalobjs(g));
1268 if (addedold1 >= (step >> 1) || g->marked >= limit) {
1269 atomic2major(L, g); /* go to major mode */
1270 return 1;
1271 }
1272 return 0; /* stay in minor mode */
1273}
1274
1275/*
1253** Does a young collection. First, mark 'OLD1' objects. Then does the 1276** Does a young collection. First, mark 'OLD1' objects. Then does the
1254** atomic step. Then, check whether to continue in minor mode. If so, 1277** atomic step. Then, check whether to continue in minor mode. If so,
1255** sweep all lists and advance pointers. Finally, finish the collection. 1278** sweep all lists and advance pointers. Finally, finish the collection.
1256*/ 1279*/
1257static void youngcollection (lua_State *L, global_State *g) { 1280static void youngcollection (lua_State *L, global_State *g) {
1281 l_obj addedold1 = 0;
1282 l_obj marked = g->marked; /* preserve 'g->marked' */
1258 GCObject **psurvival; /* to point to first non-dead survival object */ 1283 GCObject **psurvival; /* to point to first non-dead survival object */
1259 GCObject *dummy; /* dummy out parameter to 'sweepgen' */ 1284 GCObject *dummy; /* dummy out parameter to 'sweepgen' */
1260 lua_assert(g->gcstate == GCSpropagate); 1285 lua_assert(g->gcstate == GCSpropagate);
1261 g->marked = 0;
1262 if (g->firstold1) { /* are there regular OLD1 objects? */ 1286 if (g->firstold1) { /* are there regular OLD1 objects? */
1263 markold(g, g->firstold1, g->reallyold); /* mark them */ 1287 addedold1 += markold(g, g->firstold1, g->reallyold); /* mark them */
1264 g->firstold1 = NULL; /* no more OLD1 objects (for now) */ 1288 g->firstold1 = NULL; /* no more OLD1 objects (for now) */
1265 } 1289 }
1266 markold(g, g->finobj, g->finobjrold); 1290 addedold1 += markold(g, g->finobj, g->finobjrold);
1267 markold(g, g->tobefnz, NULL); 1291 addedold1 += markold(g, g->tobefnz, NULL);
1292
1293 atomic(L); /* will lose 'g->marked' */
1268 1294
1269 atomic(L); 1295 /* keep total number of added old1 objects */
1296 g->marked = marked + addedold1;
1270 1297
1271 /* decide whether to shift to major mode */ 1298 /* decide whether to shift to major mode */
1272 if (g->GCmajorminor <= 0) { /* ?? */ 1299 if (checkminormajor(L, g, addedold1))
1273 atomic2major(L, g); /* go to major mode */
1274 return; /* nothing else to be done here */ 1300 return; /* nothing else to be done here */
1275 }
1276 1301
1277 /* sweep nursery and get a pointer to its last live element */ 1302 /* sweep nursery and get a pointer to its last live element */
1278 g->gcstate = GCSswpallgc; 1303 g->gcstate = GCSswpallgc;
@@ -1319,7 +1344,8 @@ static void atomic2gen (lua_State *L, global_State *g) {
1319 sweep2old(L, &g->tobefnz); 1344 sweep2old(L, &g->tobefnz);
1320 1345
1321 g->gckind = KGC_GENMINOR; 1346 g->gckind = KGC_GENMINOR;
1322 g->GCmajorminor = applygcparam(g, genmajormul, g->marked); 1347 g->GCmajorminor = g->marked; /* "base" for number of objects */
1348 g->marked = 0; /* to count the number of added old1 objects */
1323 finishgencycle(L, g); 1349 finishgencycle(L, g);
1324} 1350}
1325 1351
@@ -1329,7 +1355,7 @@ static void atomic2gen (lua_State *L, global_State *g) {
1329** total number of objects grows 'genminormul'%. 1355** total number of objects grows 'genminormul'%.
1330*/ 1356*/
1331static void setminordebt (global_State *g) { 1357static void setminordebt (global_State *g) {
1332 luaE_setdebt(g, applygcparam(g, genminormul, gettotalobjs(g))); 1358 luaE_setdebt(g, applygcparam(g, genminormul, g->GCmajorminor));
1333} 1359}
1334 1360
1335 1361
@@ -1369,13 +1395,11 @@ static void enterinc (global_State *g) {
1369*/ 1395*/
1370void luaC_changemode (lua_State *L, int newmode) { 1396void luaC_changemode (lua_State *L, int newmode) {
1371 global_State *g = G(L); 1397 global_State *g = G(L);
1398 if (g->gckind == KGC_GENMAJOR) /* doing major collections? */
1399 g->gckind = KGC_INC; /* already incremental but in name */
1372 if (newmode != g->gckind) { /* does it need to change? */ 1400 if (newmode != g->gckind) { /* does it need to change? */
1373 if (newmode == KGC_INC) { /* entering incremental mode? */ 1401 if (newmode == KGC_INC) /* entering incremental mode? */
1374 if (g->gckind == KGC_GENMAJOR) 1402 enterinc(g); /* entering incremental mode */
1375 g->gckind = KGC_INC; /* already incremental but in name */
1376 else
1377 enterinc(g); /* entering incremental mode */
1378 }
1379 else { 1403 else {
1380 lua_assert(newmode == KGC_GENMINOR); 1404 lua_assert(newmode == KGC_GENMINOR);
1381 entergen(L, g); 1405 entergen(L, g);
@@ -1396,16 +1420,24 @@ static void fullgen (lua_State *L, global_State *g) {
1396/* 1420/*
1397** After an atomic incremental step from a major collection, 1421** After an atomic incremental step from a major collection,
1398** check whether collector could return to minor collections. 1422** check whether collector could return to minor collections.
1423** It checks whether the number of objects 'tobecollected'
1424** is greater than 'majorminor'% of the number of objects added
1425** since the last collection ('addedobjs').
1399*/ 1426*/
1400static int checkmajorminor (lua_State *L, global_State *g) { 1427static int checkmajorminor (lua_State *L, global_State *g) {
1401 if (g->gckind == KGC_GENMAJOR) { 1428 if (g->gckind == KGC_GENMAJOR) {
1402 l_obj numobjs = gettotalobjs(g); /* current count */ 1429 l_obj numobjs = gettotalobjs(g);
1403 if (g->marked < numobjs - (numobjs >> 2)) { /* ?? */ 1430 l_obj addedobjs = numobjs - g->GCmajorminor;
1431 l_obj limit = applygcparam(g, majorminor, addedobjs);
1432 l_obj tobecollected = numobjs - g->marked;
1433//printf("-> minor? %ld %ld %ld\n", tobecollected, limit, numobjs);
1434 if (tobecollected > limit) {
1404 atomic2gen(L, g); /* return to generational mode */ 1435 atomic2gen(L, g); /* return to generational mode */
1405 setminordebt(g); 1436 setminordebt(g);
1406 return 0; /* exit incremental collection */ 1437 return 0; /* exit incremental collection */
1407 } 1438 }
1408 } 1439 }
1440 g->GCmajorminor = g->marked; /* prepare for next collection */
1409 return 1; /* stay doing incremental collections */ 1441 return 1; /* stay doing incremental collections */
1410} 1442}
1411 1443
@@ -1634,8 +1666,6 @@ void luaC_step (lua_State *L) {
1634 if (!gcrunning(g)) /* not running? */ 1666 if (!gcrunning(g)) /* not running? */
1635 luaE_setdebt(g, 2000); 1667 luaE_setdebt(g, 2000);
1636 else { 1668 else {
1637//printf("> step: %d %d %ld %ld -> ", g->gckind, g->gcstate, gettotalobjs(g), g->GCdebt);
1638
1639 switch (g->gckind) { 1669 switch (g->gckind) {
1640 case KGC_INC: case KGC_GENMAJOR: 1670 case KGC_INC: case KGC_GENMAJOR:
1641 incstep(L, g); 1671 incstep(L, g);
@@ -1645,7 +1675,6 @@ void luaC_step (lua_State *L) {
1645 setminordebt(g); 1675 setminordebt(g);
1646 break; 1676 break;
1647 } 1677 }
1648//printf("%d %d %ld %ld\n", g->gckind, g->gcstate, gettotalobjs(g), g->GCdebt);
1649 } 1678 }
1650} 1679}
1651 1680