/* ** enter first sweep phase (strings) and prepare pointers for other ** sweep phases. The calls to 'sweeptolive' make pointers point to an ** object inside the list (instead of to the header), so that the real ** sweep do not need to skip objects created between "now" and the start ** of the real sweep. ** Returns how many objects it swept. */ static int entersweep (lua_State *L) { global_State *g = G(L); int n = 0; g->gcstate = GCSsweepstring; lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); /* prepare to sweep strings, finalizable objects, and regular objects */ g->sweepstrgc = 0; g->sweepfin = sweeptolive(L, &g->finobj, &n); g->sweepgc = sweeptolive(L, &g->allgc, &n); return n; }
/* ** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { global_State *g = G(L); if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ isfinalized(o) || /* ... or is finalized... */ gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ return; /* nothing to be done */ else { /* move 'o' to 'finobj' list */ GCObject **p; GCheader *ho = gch(o); if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ lua_assert(issweepphase(g)); g->sweepgc = sweeptolive(L, g->sweepgc, NULL); } /* search for pointer pointing to 'o' */ for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } *p = ho->next; /* remove 'o' from root list */ ho->next = g->finobj; /* link it in list 'finobj' */ g->finobj = o; l_setbit(ho->marked, SEPARATED); /* mark it as such */ if (!keepinvariantout(g)) /* not keeping invariant? */ makewhite(g, o); /* "sweep" object */ else resetoldbit(o); /* see MOVE OLD rule */ } }
/* ** Enter first sweep phase. ** The call to 'sweeptolive' makes pointer point to an object inside ** the list (instead of to the header), so that the real sweep do not ** need to skip objects created between "now" and the start of the real ** sweep. ** Returns how many objects it swept. */ static int entersweep (lua_State *L) { global_State *g = G(L); int n = 0; g->gcstate = GCSswpallgc; lua_assert(g->sweepgc == NULL); g->sweepgc = sweeptolive(L, &g->allgc, &n); return n; }
/* ** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { global_State *g = G(L); if (tofinalize(o) || /* obj. is already marked... */ gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ return; /* nothing to be done */ else { /* move 'o' to 'finobj' list */ GCObject **p; if (issweepphase(g)) { makewhite(g, o); /* "sweep" object 'o' */ if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */ } /* search for pointer pointing to 'o' */ for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } *p = o->next; /* remove 'o' from 'allgc' list */ o->next = g->finobj; /* link it in 'finobj' list */ g->finobj = o; l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ } }