aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-08-03 13:22:57 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-08-03 13:22:57 -0300
commitb9b554e0f68726b19274209ea6ce910b7e9f5fbf (patch)
tree5e0b126da4447bcb7bdfc80821d209dc86584a9e /lgc.c
parent0dc5deca1c0182a4a3db2fcfd7bc721f27fb352b (diff)
downloadlua-b9b554e0f68726b19274209ea6ce910b7e9f5fbf.tar.gz
lua-b9b554e0f68726b19274209ea6ce910b7e9f5fbf.tar.bz2
lua-b9b554e0f68726b19274209ea6ce910b7e9f5fbf.zip
Clearer handling of gray lists when entering generational mode
When entering generational mode, all objects are old. So, the only objects that need to be in a gray list are threads, which can be assigned without barriers. Changes in anything else (e.g., weak tables) will trigger barriers that, if needed, will add the object to a gray list.
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/lgc.c b/lgc.c
index 9973c9db..5e8c02d3 100644
--- a/lgc.c
+++ b/lgc.c
@@ -368,12 +368,17 @@ static int remarkupvals (global_State *g) {
368} 368}
369 369
370 370
371static void cleargraylists (global_State *g) {
372 g->gray = g->grayagain = NULL;
373 g->weak = g->allweak = g->ephemeron = NULL;
374}
375
376
371/* 377/*
372** mark root set and reset all gray lists, to start a new collection 378** mark root set and reset all gray lists, to start a new collection
373*/ 379*/
374static void restartcollection (global_State *g) { 380static void restartcollection (global_State *g) {
375 g->gray = g->grayagain = NULL; 381 cleargraylists(g);
376 g->weak = g->allweak = g->ephemeron = NULL;
377 markobject(g, g->mainthread); 382 markobject(g, g->mainthread);
378 markvalue(g, &g->l_registry); 383 markvalue(g, &g->l_registry);
379 markmt(g); 384 markmt(g);
@@ -1019,19 +1024,30 @@ static void setpause (global_State *g);
1019 1024
1020 1025
1021/* 1026/*
1022** Sweep a list of objects, deleting dead ones and turning 1027** Sweep a list of objects to enter generational mode. Deletes dead
1023** the non dead to old (without changing their colors). 1028** objects and turns the non dead to old. All non-dead threads---which
1029** are now old---must be in a gray list. Everything else is not in a
1030** gray list.
1031**
1024*/ 1032*/
1025static void sweep2old (lua_State *L, GCObject **p) { 1033static void sweep2old (lua_State *L, GCObject **p) {
1026 GCObject *curr; 1034 GCObject *curr;
1035 global_State *g = G(L);
1027 while ((curr = *p) != NULL) { 1036 while ((curr = *p) != NULL) {
1028 if (iswhite(curr)) { /* is 'curr' dead? */ 1037 if (iswhite(curr)) { /* is 'curr' dead? */
1029 lua_assert(isdead(G(L), curr)); 1038 lua_assert(isdead(g, curr));
1030 *p = curr->next; /* remove 'curr' from list */ 1039 *p = curr->next; /* remove 'curr' from list */
1031 freeobj(L, curr); /* erase 'curr' */ 1040 freeobj(L, curr); /* erase 'curr' */
1032 } 1041 }
1033 else { /* all surviving objects become old */ 1042 else { /* all surviving objects become old */
1034 setage(curr, G_OLD); 1043 setage(curr, G_OLD);
1044 if (curr->tt == LUA_VTHREAD) { /* threads must be watched */
1045 lua_State *th = gco2th(curr);
1046 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
1047 black2gray(th); /* OK if already gray */
1048 }
1049 else /* everything else is black */
1050 gray2black(curr); /* OK if already black */
1035 p = &curr->next; /* go to next element */ 1051 p = &curr->next; /* go to next element */
1036 } 1052 }
1037 } 1053 }
@@ -1221,7 +1237,14 @@ static void youngcollection (lua_State *L, global_State *g) {
1221} 1237}
1222 1238
1223 1239
1240/*
1241** Clears all gray lists, sweeps objects, and prepare sublists to enter
1242** generational mode. The sweeps remove dead objects and turn all
1243** surviving objects to old. Threads go back to 'grayagain'; everything
1244** else is turned black (not in any gray list).
1245*/
1224static void atomic2gen (lua_State *L, global_State *g) { 1246static void atomic2gen (lua_State *L, global_State *g) {
1247 cleargraylists(g);
1225 /* sweep all elements making them old */ 1248 /* sweep all elements making them old */
1226 g->gcstate = GCSswpallgc; 1249 g->gcstate = GCSswpallgc;
1227 sweep2old(L, &g->allgc); 1250 sweep2old(L, &g->allgc);
@@ -1244,7 +1267,8 @@ static void atomic2gen (lua_State *L, global_State *g) {
1244 1267
1245/* 1268/*
1246** Enter generational mode. Must go until the end of an atomic cycle 1269** Enter generational mode. Must go until the end of an atomic cycle
1247** to ensure that all threads and weak tables are in the gray lists. 1270** to ensure that all objects are correctly marked and weak tables
1271** are cleared.
1248** Then, turn all objects into old and finishes the collection. 1272** Then, turn all objects into old and finishes the collection.
1249*/ 1273*/
1250static lu_mem entergen (lua_State *L, global_State *g) { 1274static lu_mem entergen (lua_State *L, global_State *g) {