** 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
| 1143 | ** regular old; they and anything else are removed from the list. |
| 1144 | */ |
| 1145 | static GCObject **correctgraylist (GCObject **p) { |
| 1146 | GCObject *curr; |
| 1147 | while ((curr = *p) != NULL) { |
| 1148 | GCObject **next = getgclist(curr); |
| 1149 | if (iswhite(curr)) |
| 1150 | goto remove; /* remove all white objects */ |
| 1151 | else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ |
| 1152 | lua_assert(isgray(curr)); |
| 1153 | nw2black(curr); /* make it black, for next barrier */ |
| 1154 | changeage(curr, G_TOUCHED1, G_TOUCHED2); |
| 1155 | goto remain; /* keep it in the list and go to next element */ |
| 1156 | } |
| 1157 | else if (curr->tt == LUA_VTHREAD) { |
| 1158 | lua_assert(isgray(curr)); |
| 1159 | goto remain; /* keep non-white threads on the list */ |
| 1160 | } |
| 1161 | else { /* everything else is removed */ |
| 1162 | lua_assert(isold(curr)); /* young objects should be white here */ |
| 1163 | if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ |
| 1164 | changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ |
| 1165 | nw2black(curr); /* make object black (to be removed) */ |
| 1166 | goto remove; |
| 1167 | } |
| 1168 | remove: *p = *next; continue; |
| 1169 | remain: p = next; continue; |
| 1170 | } |
| 1171 | return p; |
| 1172 | } |
| 1173 | |
| 1174 | |
| 1175 | /* |
no test coverage detected