** 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. */
| 1046 | ** For threads, just remove white ones from the list. |
| 1047 | */ |
| 1048 | static GCObject **correctgraylist (GCObject **p) { |
| 1049 | GCObject *curr; |
| 1050 | while ((curr = *p) != NULL) { |
| 1051 | switch (curr->tt) { |
| 1052 | case LUA_VTABLE: case LUA_VUSERDATA: { |
| 1053 | GCObject **next = getgclist(curr); |
| 1054 | if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ |
| 1055 | lua_assert(isgray(curr)); |
| 1056 | gray2black(curr); /* make it black, for next barrier */ |
| 1057 | changeage(curr, G_TOUCHED1, G_TOUCHED2); |
| 1058 | p = next; /* go to next element */ |
| 1059 | } |
| 1060 | else { /* not touched in this cycle */ |
| 1061 | if (!iswhite(curr)) { /* not white? */ |
| 1062 | lua_assert(isold(curr)); |
| 1063 | if (getage(curr) == G_TOUCHED2) /* advance from G_TOUCHED2... */ |
| 1064 | changeage(curr, G_TOUCHED2, G_OLD); /* ... to G_OLD */ |
| 1065 | gray2black(curr); /* make it black */ |
| 1066 | } |
| 1067 | /* else, object is white: just remove it from this list */ |
| 1068 | *p = *next; /* remove 'curr' from gray list */ |
| 1069 | } |
| 1070 | break; |
| 1071 | } |
| 1072 | case LUA_VTHREAD: { |
| 1073 | lua_State *th = gco2th(curr); |
| 1074 | lua_assert(!isblack(th)); |
| 1075 | if (iswhite(th)) /* new object? */ |
| 1076 | *p = th->gclist; /* remove from gray list */ |
| 1077 | else /* old threads remain gray */ |
| 1078 | p = &th->gclist; /* go to next element */ |
| 1079 | break; |
| 1080 | } |
| 1081 | default: lua_assert(0); /* nothing more could be gray here */ |
| 1082 | } |
| 1083 | } |
| 1084 | return p; |
| 1085 | } |
| 1086 | |
| 1087 | |
| 1088 | /* |
no test coverage detected