/* ** traverse one gray object, turning it to black (except for threads, ** which are always gray). ** Returns number of values traversed. */ static int propagatemark (global_State *g) { GCObject *o = g->gray; lua_assert(isgray(o)); gray2black(o); switch (gch(o)->tt) { case LUA_TTABLE: { Table *h = gco2t(o); g->gray = h->gclist; return traversetable(g, h); } case LUA_TFUNCTION: { Closure *cl = gco2cl(o); g->gray = cl->c.gclist; return traverseclosure(g, cl); } case LUA_TTHREAD: { lua_State *th = gco2th(o); g->gray = th->gclist; th->gclist = g->grayagain; g->grayagain = o; black2gray(o); return traversestack(g, th); } case LUA_TPROTO: { Proto *p = gco2p(o); g->gray = p->gclist; return traverseproto(g, p); } default: lua_assert(0); return 0; } }
static void propagatemarks (GCState *st) { while (st->tmark) { /* traverse marked objects */ switch (st->tmark->gch.tt) { case LUA_TTABLE: { Table *h = gcotoh(st->tmark); st->tmark = h->gclist; traversetable(st, h); break; } case LUA_TFUNCTION: { Closure *cl = gcotocl(st->tmark); st->tmark = cl->c.gclist; traverseclosure(st, cl); break; } case LUA_TTHREAD: { lua_State *th = gcototh(st->tmark); st->tmark = th->gclist; traversestack(st, th); break; } case LUA_TPROTO: { Proto *p = gcotop(st->tmark); st->tmark = p->gclist; traverseproto(st, p); break; } default: lua_assert(0); } } }
static void propagatemarks (GCState *st) { while (st->tmark) { /* traverse marked objects */ switch (st->tmark->gch.tt) { case LUA_TTABLE: { Table *h = gcotoh(st->tmark); st->tmark = h->gclist; traversetable(st, h); break; } case LUA_TFUNCTION: { Closure *cl = gcotocl(st->tmark); st->tmark = cl->c.gclist; traverseclosure(st, cl); break; } case LUA_TTHREAD: { lua_State *th = gcototh(st->tmark); #if LUA_REFCOUNT st->tmark = th->gclist_head.next; #else !LUA_REFCOUNT st->tmark = th->gclist; #endif LUA_REFCOUNT traversestack(st, th); if (G(th)->userGCFunction) { st->L = th; G(th)->userGCFunction(st); } break; } case LUA_TPROTO: { Proto *p = gcotop(st->tmark); st->tmark = p->gclist; traverseproto(st, p); break; } #if LUA_REFCOUNT case LUA_TNIL: { st->tmark = NULL; break; } #endif LUA_REFCOUNT default: lua_assert(0); } } }
/* ** traverse one gray object, turning it to black. ** Returns `quantity' traversed. */ static l_mem propagatemark (global_State *g) { GCObject *o = g->gray; lua_assert(isgray(o)); gray2black(o); switch (o->gch.tt) { case LUA_TTABLE: { Table *h = gco2h(o); g->gray = h->gclist; if (traversetable(g, h)) /* table is weak? */ black2gray(o); /* keep it gray */ return sizeof(Table) + sizeof(TValue) * h->sizearray + sizeof(Node) * sizenode(h); } case LUA_TFUNCTION: { Closure *cl = gco2cl(o); g->gray = cl->c.gclist; traverseclosure(g, cl); return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : sizeLclosure(cl->l.nupvalues); } case LUA_TTHREAD: { lua_State *th = gco2th(o); g->gray = th->gclist; th->gclist = g->grayagain; g->grayagain = o; black2gray(o); traversestack(g, th); return sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci; } case LUA_TPROTO: { Proto *p = gco2p(o); g->gray = p->gclist; traverseproto(g, p); return sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto *) * p->sizep + sizeof(TValue) * p->sizek + sizeof(int) * p->sizelineinfo + sizeof(LocVar) * p->sizelocvars + sizeof(TString *) * p->sizeupvalues; } default: lua_assert(0); return 0; } }
/* ** traverse one gray object, turning it to black (except for threads, ** which are always gray). */ static void propagatemark (global_State *g) { lu_mem size; GCObject *o = g->gray; lua_assert(isgray(o)); gray2black(o); switch (o->tt) { case LUA_TTABLE: { Table *h = gco2t(o); g->gray = h->gclist; /* remove from 'gray' list */ size = traversetable(g, h); break; } case LUA_TLCL: { LClosure *cl = gco2lcl(o); g->gray = cl->gclist; /* remove from 'gray' list */ size = traverseLclosure(g, cl); break; } case LUA_TCCL: { CClosure *cl = gco2ccl(o); g->gray = cl->gclist; /* remove from 'gray' list */ size = traverseCclosure(g, cl); break; } case LUA_TTHREAD: { lua_State *th = gco2th(o); g->gray = th->gclist; /* remove from 'gray' list */ linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ black2gray(o); size = traversethread(g, th); break; } case LUA_TPROTO: { Proto *p = gco2p(o); g->gray = p->gclist; /* remove from 'gray' list */ size = traverseproto(g, p); break; } default: lua_assert(0); return; } g->GCmemtrav += size; }