From ccae0f5aad11b448fa630a41b2c7c54e69d134d8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 18 Jul 2018 11:43:45 -0300 Subject: [PATCH] Comments about OLD0/OLD1 ages Improved the comments in file 'lgc.c' explaining the roles of "ages" OLD0 and OLD1 in the generacional collector. --- lgc.c | 54 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/lgc.c b/lgc.c index c11a5280..e8429e1b 100644 --- a/lgc.c +++ b/lgc.c @@ -181,9 +181,13 @@ static int iscleared (global_State *g, const GCObject *o) { /* ** barrier that moves collector forward, that is, mark the white object -** being pointed by a black object. (If in sweep phase, clear the black -** object to white [sweep it] to avoid other barrier calls for this -** same object.) +** 'v' being pointed by the black object 'o'. (If in sweep phase, clear +** the black object to white [sweep it] to avoid other barrier calls for +** this same object.) In the generational mode, 'v' must also become +** old, if 'o' is old; however, it cannot be changed directly to OLD, +** because it may still point to non-old objects. So, it is marked as +** OLD0. In the next cycle it will become OLD1, and in the next it +** will finally become OLD (regular old). */ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); @@ -218,13 +222,14 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) { /* -** Barrier for prototype's cache of closures. For an 'old1' -** object, making it gray stops it from being visited by 'markold', -** so it is linked in the 'grayagain' list to ensure it will be -** visited. Otherwise, it goes to 'protogray', as only its 'cache' field -** needs to be revisited. (A prototype to be in this barrier must be -** already finished, so its other fields cannot change and do not need -** to be revisited.) +** Barrier for prototype's cache of closures. It turns the prototype +** back to gray (it was black). For an 'OLD1' prototype, making it +** gray stops it from being visited by 'markold', so it is linked in +** the 'grayagain' list to ensure it will be visited. For other ages, +** it goes to the 'protogray' list, as only its 'cache' field needs to +** be revisited. (A prototype to be in this barrier must be already +** finished, so its other fields cannot change and do not need to be +** revisited.) */ LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p) { global_State *g = G(L); @@ -233,7 +238,7 @@ LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p) { linkgclist(p, g->grayagain); /* link it in 'grayagain' */ else linkgclist(p, g->protogray); /* link it in 'protogray' */ - black2gray(p); /* make prototype gray (to avoid other barriers) */ + black2gray(p); /* make prototype gray */ } @@ -533,9 +538,9 @@ static int traverseudata (global_State *g, Udata *u) { ** cache is white, clear it. (A cache should not prevent the ** collection of its reference.) Otherwise, if in generational ** mode, check the generational invariant. If the cache is old, -** everything is ok. If the prototype is 'old0', everything +** everything is ok. If the prototype is 'OLD0', everything ** is ok too. (It will naturally be visited again.) If the -** prototype is older than 'old0', then its cache (which is new) +** prototype is older than 'OLD0', then its cache (which is new) ** must be visited again in the next collection, so the prototype ** goes to the 'protogray' list. (If the prototype has a cache, ** it is already immutable and does not need other barriers; @@ -1085,9 +1090,9 @@ static void whitelist (global_State *g, GCObject *p) { /* -** Correct a list of gray objects. Because this correction is -** done after sweeping, young objects can be white and still -** be in the list. They are only removed. +** Correct a list of gray objects. +** Because this correction is done after sweeping, young objects might +** be turned white and still be in the list. They are only removed. ** For tables and userdata, advance 'touched1' to 'touched2'; 'touched2' ** objects become regular old and are removed from the list. ** For threads, just remove white ones from the list. @@ -1104,13 +1109,14 @@ static GCObject **correctgraylist (GCObject **p) { changeage(curr, G_TOUCHED1, G_TOUCHED2); p = next; /* go to next element */ } - else { - if (!iswhite(curr)) { + else { /* not touched in this cycle */ + if (!iswhite(curr)) { /* not white? */ lua_assert(isold(curr)); - if (getage(curr) == G_TOUCHED2) - changeage(curr, G_TOUCHED2, G_OLD); + if (getage(curr) == G_TOUCHED2) /* advance from G_TOUCHED2... */ + changeage(curr, G_TOUCHED2, G_OLD); /* ... to G_OLD */ gray2black(curr); /* make it black */ } + /* else, object is white: just remove it from this list */ *p = *next; /* remove 'curr' from gray list */ } break; @@ -1146,7 +1152,7 @@ static void correctgraylists (global_State *g) { /* -** Mark 'old1' objects when starting a new young collection. +** Mark 'OLD1' objects when starting a new young collection. ** Gray objects are already in some gray list, and so will be visited ** in the atomic step. */ @@ -1177,9 +1183,9 @@ static void finishgencycle (lua_State *L, global_State *g) { /* -** Does a young collection. First, mark 'old1' objects. (Only survival -** and "recent old" lists can contain 'old1' objects. New lists cannot -** contain 'old1' objects, at most 'old0' objects that were already +** Does a young collection. First, mark 'OLD1' objects. (Only survival +** and "recent old" lists can contain 'OLD1' objects. New lists cannot +** contain 'OLD1' objects, at most 'OLD0' objects that were already ** visited when marked old.) Then does the atomic step. Then, ** sweep all lists and advance pointers. Finally, finish the collection. */