** traverse one gray object, turning it to black. ** Returns `quantity' traversed. */
| 6277 | ** Returns `quantity' traversed. |
| 6278 | */ |
| 6279 | static l_mem propagatemark (global_State *g) { |
| 6280 | GCObject *o = g->gray; |
| 6281 | lua_assert(isgray(o)); |
| 6282 | gray2black(o); |
| 6283 | switch (o->gch.tt) { |
| 6284 | case LUA_TTABLE: { |
| 6285 | Table *h = gco2h(o); |
| 6286 | g->gray = h->gclist; |
| 6287 | if (traversetable(g, h)) /* table is weak? */ |
| 6288 | black2gray(o); /* keep it gray */ |
| 6289 | return sizeof(Table) + sizeof(TValue) * h->sizearray + |
| 6290 | sizeof(Node) * sizenode(h); |
| 6291 | } |
| 6292 | case LUA_TFUNCTION: { |
| 6293 | Closure *cl = gco2cl(o); |
| 6294 | g->gray = cl->c.gclist; |
| 6295 | traverseclosure(g, cl); |
| 6296 | return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : |
| 6297 | sizeLclosure(cl->l.nupvalues); |
| 6298 | } |
| 6299 | case LUA_TTHREAD: { |
| 6300 | lua_State *th = gco2th(o); |
| 6301 | g->gray = th->gclist; |
| 6302 | th->gclist = g->grayagain; |
| 6303 | g->grayagain = o; |
| 6304 | black2gray(o); |
| 6305 | traversestack(g, th); |
| 6306 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + |
| 6307 | sizeof(CallInfo) * th->size_ci; |
| 6308 | } |
| 6309 | case LUA_TPROTO: { |
| 6310 | Proto *p = gco2p(o); |
| 6311 | g->gray = p->gclist; |
| 6312 | traverseproto(g, p); |
| 6313 | return sizeof(Proto) + sizeof(Instruction) * p->sizecode + |
| 6314 | sizeof(Proto *) * p->sizep + |
| 6315 | sizeof(TValue) * p->sizek + |
| 6316 | sizeof(int) * p->sizelineinfo + |
| 6317 | sizeof(LocVar) * p->sizelocvars + |
| 6318 | sizeof(TString *) * p->sizeupvalues; |
| 6319 | } |
| 6320 | default: lua_assert(0); return 0; |
| 6321 | } |
| 6322 | } |
| 6323 | |
| 6324 | |
| 6325 | static size_t propagateall (global_State *g) { |
no test coverage detected