diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-12-07 15:45:11 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-12-07 15:45:11 -0300 |
| commit | 925fe8a0f2a667c96c015ee74d1a702af9ea5507 (patch) | |
| tree | bca1cb92e11218498f4c76f651f4a5fa1a8c87b5 /lgc.c | |
| parent | 789e7acdea3ada96bd00b7aac6d82e805bfee85c (diff) | |
| download | lua-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.c | 81 |
1 files changed, 55 insertions, 26 deletions
| @@ -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 | */ |
| 1211 | static void markold (global_State *g, GCObject *from, GCObject *to) { | 1210 | static 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 | */ |
| 1241 | static void atomic2major (lua_State *L, global_State *g) { | 1242 | static 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 | */ | ||
| 1264 | static 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 | */ |
| 1257 | static void youngcollection (lua_State *L, global_State *g) { | 1280 | static 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 | */ |
| 1331 | static void setminordebt (global_State *g) { | 1357 | static 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 | */ |
| 1370 | void luaC_changemode (lua_State *L, int newmode) { | 1396 | void 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 | */ |
| 1400 | static int checkmajorminor (lua_State *L, global_State *g) { | 1427 | static 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 | ||
