** 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. ** */
| 630 | ** |
| 631 | */ |
| 632 | static void convergeephemerons (global_State *g) { |
| 633 | int changed; |
| 634 | int dir = 0; |
| 635 | do { |
| 636 | GCObject *w; |
| 637 | GCObject *next = g->ephemeron; /* get ephemeron list */ |
| 638 | g->ephemeron = NULL; /* tables may return to this list when traversed */ |
| 639 | changed = 0; |
| 640 | while ((w = next) != NULL) { /* for each ephemeron table */ |
| 641 | next = gco2t(w)->gclist; /* list is rebuilt during loop */ |
| 642 | if (traverseephemeron(g, gco2t(w), dir)) { /* marked some value? */ |
| 643 | propagateall(g); /* propagate changes */ |
| 644 | changed = 1; /* will have to revisit all ephemeron tables */ |
| 645 | } |
| 646 | } |
| 647 | dir = !dir; /* invert direction next time */ |
| 648 | } while (changed); /* repeat until no more changes */ |
| 649 | } |
| 650 | |
| 651 | /* }====================================================== */ |
| 652 |
no test coverage detected