** 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. */
| 753 | ** convergence on chains in the same table. |
| 754 | */ |
| 755 | static void convergeephemerons (global_State *g) { |
| 756 | int changed; |
| 757 | int dir = 0; |
| 758 | do { |
| 759 | GCObject *w; |
| 760 | GCObject *next = g->ephemeron; /* get ephemeron list */ |
| 761 | g->ephemeron = NULL; /* tables may return to this list when traversed */ |
| 762 | changed = 0; |
| 763 | while ((w = next) != NULL) { /* for each ephemeron table */ |
| 764 | Table *h = gco2t(w); |
| 765 | next = h->gclist; /* list is rebuilt during loop */ |
| 766 | nw2black(h); /* out of the list (for now) */ |
| 767 | if (traverseephemeron(g, h, dir)) { /* marked some value? */ |
| 768 | propagateall(g); /* propagate changes */ |
| 769 | changed = 1; /* will have to revisit all ephemeron tables */ |
| 770 | } |
| 771 | } |
| 772 | dir = !dir; /* invert direction next time */ |
| 773 | } while (changed); /* repeat until no more changes */ |
| 774 | } |
| 775 | |
| 776 | /* }====================================================== */ |
| 777 |
no test coverage detected