** 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. ** */
| 681 | ** |
| 682 | */ |
| 683 | static void convergeephemerons (global_State *g) { |
| 684 | int changed; |
| 685 | int dir = 0; |
| 686 | do { |
| 687 | GCObject *w; |
| 688 | GCObject *next = g->ephemeron; /* get ephemeron list */ |
| 689 | g->ephemeron = NULL; /* tables may return to this list when traversed */ |
| 690 | changed = 0; |
| 691 | while ((w = next) != NULL) { /* for each ephemeron table */ |
| 692 | Table *h = gco2t(w); |
| 693 | next = h->gclist; /* list is rebuilt during loop */ |
| 694 | nw2black(h); /* out of the list (for now) */ |
| 695 | if (traverseephemeron(g, h, dir)) { /* marked some value? */ |
| 696 | propagateall(g); /* propagate changes */ |
| 697 | changed = 1; /* will have to revisit all ephemeron tables */ |
| 698 | } |
| 699 | } |
| 700 | dir = !dir; /* invert direction next time */ |
| 701 | } while (changed); /* repeat until no more changes */ |
| 702 | } |
| 703 | |
| 704 | /* }====================================================== */ |
| 705 |
no test coverage detected