MCPcopy Create free account
hub / github.com/ObEngine/ObEngine / traverseephemeron

Function traverseephemeron

extlibs/lua/src/lgc.c:416–458  ·  view source on GitHub ↗

** Traverse an ephemeron table and link it to proper list. Returns true ** iff any object was marked during this traversal (which implies that ** convergence has to continue). During propagation phase, keep table ** in 'grayagain' list, to be visited again in the atomic phase. In ** the atomic phase, if table has any white->white entry, it has to ** be revisited during ephemeron convergence (as th

Source from the content-addressed store, hash-verified

414** tables) must be kept in some gray list for post-processing.
415*/
416static int traverseephemeron (global_State *g, Table *h, int inv) {
417 int marked = 0; /* true if an object is marked in this traversal */
418 int hasclears = 0; /* true if table has white keys */
419 int hasww = 0; /* true if table has entry "white-key -> white-value" */
420 unsigned int i;
421 unsigned int asize = luaH_realasize(h);
422 unsigned int nsize = sizenode(h);
423 /* traverse array part */
424 for (i = 0; i < asize; i++) {
425 if (valiswhite(&h->array[i])) {
426 marked = 1;
427 reallymarkobject(g, gcvalue(&h->array[i]));
428 }
429 }
430 /* traverse hash part; if 'inv', traverse descending
431 (see 'convergeephemerons') */
432 for (i = 0; i < nsize; i++) {
433 Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i);
434 if (isempty(gval(n))) /* entry is empty? */
435 clearkey(n); /* clear its key */
436 else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */
437 hasclears = 1; /* table must be cleared */
438 if (valiswhite(gval(n))) /* value not marked yet? */
439 hasww = 1; /* white-white entry */
440 }
441 else if (valiswhite(gval(n))) { /* value not marked yet? */
442 marked = 1;
443 reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
444 }
445 }
446 /* link table into proper list */
447 if (g->gcstate == GCSpropagate)
448 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
449 else if (hasww) /* table has white->white entries? */
450 linkgclist(h, g->ephemeron); /* have to propagate again */
451 else if (hasclears) /* table has white keys? */
452 linkgclist(h, g->allweak); /* may have to clean white keys */
453 else if (g->gckind == KGC_GEN)
454 linkgclist(h, g->grayagain); /* keep it in some list */
455 else
456 gray2black(h);
457 return marked;
458}
459
460
461static void traversestrongtable (global_State *g, Table *h) {

Callers 2

traversetableFunction · 0.85
convergeephemeronsFunction · 0.85

Calls 4

luaH_realasizeFunction · 0.85
reallymarkobjectFunction · 0.85
clearkeyFunction · 0.85
isclearedFunction · 0.85

Tested by

no test coverage detected