static void atomic (lua_State *L) { global_State *g = G(L); size_t udsize; /* total size of userdata to be finalized */ /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); /* traverse objects cautch by write barrier and by 'remarkupvals' */ propagateall(g); /* remark weak tables */ g->gray = g->weak; g->weak = NULL; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ markmt(g); /* mark basic metatables (again) */ propagateall(g); /* remark gray again */ g->gray = g->grayagain; g->grayagain = NULL; propagateall(g); udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ marktmu(g); /* mark `preserved' userdata */ udsize += propagateall(g); /* remark, to propagate `preserveness' */ cleartable(g->weak); /* remove collected objects from weak tables */ /* flip current white */ g->currentwhite = cast_byte(otherwhite(g)); g->sweepstrgc = 0; g->sweepgc = &g->rootgc; g->gcstate = GCSsweepstring; g->estimate = g->totalbytes - udsize; /* first estimate */ }
static size_t mark (lua_State *L) { size_t deadmem; GCState st; GCObject *wkv; st.L = L; st.g = G(L); st.tmark = NULL; st.wkv = st.wk = st.wv = NULL; markroot(&st, L); propagatemarks(&st); /* mark all reachable objects */ cleartablevalues(L, st.wkv); cleartablevalues(L, st.wv); wkv = st.wkv; /* keys must be cleared after preserving udata */ st.wkv = NULL; st.wv = NULL; deadmem = luaC_separateudata(L); /* separate userdata to be preserved */ marktmu(&st); /* mark `preserved' userdata */ propagatemarks(&st); /* remark, to propagate `preserveness' */ cleartablekeys(L, wkv); /* `propagatemarks' may resuscitate some weak tables; clear them too */ cleartablekeys(L, st.wk); cleartablevalues(L, st.wv); cleartablekeys(L, st.wkv); cleartablevalues(L, st.wkv); return deadmem; }