** Traverse all ephemeron tables propagating marks from keys to values. ** Repeat until it converges, that is, nothing new is marked. 'dir' ** inverts the direction of the traversals, trying to speed up ** convergence on chains in the same table. ** */
| 689 | ** |
| 690 | */ |
| 691 | static void convergeephemerons (global_State *g) { |
| 692 | int changed; |
| 693 | int dir = 0; |
| 694 | do { |
| 695 | GCObject *w; |
| 696 | GCObject *next = g->ephemeron; /* get ephemeron list */ |
| 697 | g->ephemeron = NULL; /* tables may return to this list when traversed */ |
| 698 | changed = 0; |
| 699 | while ((w = next) != NULL) { /* for each ephemeron table */ |
| 700 | Table *h = gco2t(w); |
| 701 | next = h->gclist; /* list is rebuilt during loop */ |
| 702 | nw2black(h); /* out of the list (for now) */ |
| 703 | if (traverseephemeron(g, h, dir)) { /* marked some value? */ |
| 704 | propagateall(g); /* propagate changes */ |
| 705 | changed = 1; /* will have to revisit all ephemeron tables */ |
| 706 | } |
| 707 | } |
| 708 | dir = !dir; /* invert direction next time */ |
| 709 | } while (changed); /* repeat until no more changes */ |
| 710 | } |
| 711 | |
| 712 | /* }====================================================== */ |
| 713 |
no test coverage detected