** Mark all values stored in marked open upvalues from non-marked threads. ** (Values from marked threads were already marked when traversing the ** thread.) Remove from the list threads that no longer have upvalues and ** not-marked threads. */
| 330 | ** not-marked threads. |
| 331 | */ |
| 332 | static int remarkupvals (global_State *g) { |
| 333 | lua_State *thread; |
| 334 | lua_State **p = &g->twups; |
| 335 | int work = 0; |
| 336 | while ((thread = *p) != NULL) { |
| 337 | work++; |
| 338 | lua_assert(!isblack(thread)); /* threads are never black */ |
| 339 | if (isgray(thread) && thread->openupval != NULL) |
| 340 | p = &thread->twups; /* keep marked thread with upvalues in the list */ |
| 341 | else { /* thread is not marked or without upvalues */ |
| 342 | UpVal *uv; |
| 343 | *p = thread->twups; /* remove thread from the list */ |
| 344 | thread->twups = thread; /* mark that it is out of list */ |
| 345 | for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { |
| 346 | work++; |
| 347 | if (!iswhite(uv)) /* upvalue already visited? */ |
| 348 | markvalue(g, uv->v); /* mark its value */ |
| 349 | } |
| 350 | } |
| 351 | } |
| 352 | return work; |
| 353 | } |
| 354 | |
| 355 | |
| 356 | /* |