Преглед изворни кода

Comments about OLD0/OLD1 ages

Improved the comments in file 'lgc.c' explaining the roles of "ages"
OLD0 and OLD1 in the generacional collector.
Roberto Ierusalimschy пре 7 година
родитељ
комит
ccae0f5aad
1 измењених фајлова са 30 додато и 24 уклоњено
  1. 30 24
      lgc.c

+ 30 - 24
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.
 */