** traverse one gray object, turning it to black. ** Returns `quantity' traversed. */
| 275 | ** Returns `quantity' traversed. |
| 276 | */ |
| 277 | static l_mem propagatemark (global_State *g) { |
| 278 | GCObject *o = g->gray; |
| 279 | lua_assert(isgray(o)); |
| 280 | gray2black(o); |
| 281 | switch (o->gch.tt) { |
| 282 | case LUA_TTABLE: { |
| 283 | Table *h = gco2h(o); |
| 284 | g->gray = h->gclist; |
| 285 | if (traversetable(g, h)) /* table is weak? */ |
| 286 | black2gray(o); /* keep it gray */ |
| 287 | return sizeof(Table) + sizeof(TValue) * h->sizearray + |
| 288 | sizeof(Node) * sizenode(h); |
| 289 | } |
| 290 | case LUA_TFUNCTION: { |
| 291 | Closure *cl = gco2cl(o); |
| 292 | g->gray = cl->c.gclist; |
| 293 | traverseclosure(g, cl); |
| 294 | return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : |
| 295 | sizeLclosure(cl->l.nupvalues); |
| 296 | } |
| 297 | case LUA_TTHREAD: { |
| 298 | lua_State *th = gco2th(o); |
| 299 | g->gray = th->gclist; |
| 300 | th->gclist = g->grayagain; |
| 301 | g->grayagain = o; |
| 302 | black2gray(o); |
| 303 | traversestack(g, th); |
| 304 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + |
| 305 | sizeof(CallInfo) * th->size_ci; |
| 306 | } |
| 307 | case LUA_TPROTO: { |
| 308 | Proto *p = gco2p(o); |
| 309 | g->gray = p->gclist; |
| 310 | traverseproto(g, p); |
| 311 | return sizeof(Proto) + sizeof(Instruction) * p->sizecode + |
| 312 | sizeof(Proto *) * p->sizep + |
| 313 | sizeof(TValue) * p->sizek + |
| 314 | sizeof(int) * p->sizelineinfo + |
| 315 | sizeof(LocVar) * p->sizelocvars + |
| 316 | sizeof(TString *) * p->sizeupvalues; |
| 317 | } |
| 318 | default: lua_assert(0); return 0; |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | |
| 323 | static size_t propagateall (global_State *g) { |
no test coverage detected