** Correct a list of gray objects. Return pointer to where rest of the ** list should be linked. ** Because this correction is done after sweeping, young objects might ** be turned white and still be in the list. They are only removed. ** 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; ** Non-white threads also remain on the list; 'TOUCHED2' objects become ** regular old; the
| 1170 | ** regular old; they and anything else are removed from the list. |
| 1171 | */ |
| 1172 | static GCObject **correctgraylist (GCObject **p) { |
| 1173 | GCObject *curr; |
| 1174 | while ((curr = *p) != NULL) { |
| 1175 | GCObject **next = getgclist(curr); |
| 1176 | if (iswhite(curr)) |
| 1177 | goto remove; /* remove all white objects */ |
| 1178 | else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ |
| 1179 | lua_assert(isgray(curr)); |
| 1180 | nw2black(curr); /* make it black, for next barrier */ |
| 1181 | changeage(curr, G_TOUCHED1, G_TOUCHED2); |
| 1182 | goto remain; /* keep it in the list and go to next element */ |
| 1183 | } |
| 1184 | else if (curr->tt == LUA_VTHREAD) { |
| 1185 | lua_assert(isgray(curr)); |
| 1186 | goto remain; /* keep non-white threads on the list */ |
| 1187 | } |
| 1188 | else { /* everything else is removed */ |
| 1189 | lua_assert(isold(curr)); /* young objects should be white here */ |
| 1190 | if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ |
| 1191 | changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ |
| 1192 | nw2black(curr); /* make object black (to be removed) */ |
| 1193 | goto remove; |
| 1194 | } |
| 1195 | remove: *p = *next; continue; |
| 1196 | remain: p = next; continue; |
| 1197 | } |
| 1198 | return p; |
| 1199 | } |
| 1200 | |
| 1201 | |
| 1202 | /* |
no test coverage detected