1 /* $NetBSD: lgc.c,v 1.9 2017/09/07 12:52:29 mbalmer Exp $ */ 2 3 /* 4 ** Id: lgc.c,v 2.215 2016/12/22 13:08:50 roberto Exp 5 ** Garbage Collector 6 ** See Copyright Notice in lua.h 7 */ 8 9 #define lgc_c 10 #define LUA_CORE 11 12 #include "lprefix.h" 13 14 15 #ifndef _KERNEL 16 #include <string.h> 17 #endif /* _KERNEL */ 18 19 #include "lua.h" 20 21 #include "ldebug.h" 22 #include "ldo.h" 23 #include "lfunc.h" 24 #include "lgc.h" 25 #include "lmem.h" 26 #include "lobject.h" 27 #include "lstate.h" 28 #include "lstring.h" 29 #include "ltable.h" 30 #include "ltm.h" 31 32 33 /* 34 ** internal state for collector while inside the atomic phase. The 35 ** collector should never be in this state while running regular code. 36 */ 37 #define GCSinsideatomic (GCSpause + 1) 38 39 /* 40 ** cost of sweeping one element (the size of a small object divided 41 ** by some adjust for the sweep speed) 42 */ 43 #define GCSWEEPCOST ((sizeof(TString) + 4) / 4) 44 45 /* maximum number of elements to sweep in each single step */ 46 #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) 47 48 /* cost of calling one finalizer */ 49 #define GCFINALIZECOST GCSWEEPCOST 50 51 52 /* 53 ** macro to adjust 'stepmul': 'stepmul' is actually used like 54 ** 'stepmul / STEPMULADJ' (value chosen by tests) 55 */ 56 #define STEPMULADJ 200 57 58 59 /* 60 ** macro to adjust 'pause': 'pause' is actually used like 61 ** 'pause / PAUSEADJ' (value chosen by tests) 62 */ 63 #define PAUSEADJ 100 64 65 66 /* 67 ** 'makewhite' erases all color bits then sets only the current white 68 ** bit 69 */ 70 #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) 71 #define makewhite(g,x) \ 72 (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) 73 74 #define white2gray(x) resetbits(x->marked, WHITEBITS) 75 #define black2gray(x) resetbit(x->marked, BLACKBIT) 76 77 78 #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 79 80 #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) 81 82 83 #define checkconsistency(obj) \ 84 lua_longassert(!iscollectable(obj) || righttt(obj)) 85 86 87 #define markvalue(g,o) { checkconsistency(o); \ 88 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } 89 90 #define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } 91 92 /* 93 ** mark an object that can be NULL (either because it is really optional, 94 ** or it was stripped as debug info, or inside an uncompleted structure) 95 */ 96 #define markobjectN(g,t) { if (t) markobject(g,t); } 97 98 static void reallymarkobject (global_State *g, GCObject *o); 99 100 101 /* 102 ** {====================================================== 103 ** Generic functions 104 ** ======================================================= 105 */ 106 107 108 /* 109 ** one after last element in a hash array 110 */ 111 #define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) 112 113 114 /* 115 ** link collectable object 'o' into list pointed by 'p' 116 */ 117 #define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o)) 118 119 120 /* 121 ** If key is not marked, mark its entry as dead. This allows key to be 122 ** collected, but keeps its entry in the table. A dead node is needed 123 ** when Lua looks up for a key (it may be part of a chain) and when 124 ** traversing a weak table (key might be removed from the table during 125 ** traversal). Other places never manipulate dead keys, because its 126 ** associated nil value is enough to signal that the entry is logically 127 ** empty. 128 */ 129 static void removeentry (Node *n) { 130 lua_assert(ttisnil(gval(n))); 131 if (valiswhite(gkey(n))) 132 setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */ 133 } 134 135 136 /* 137 ** tells whether a key or value can be cleared from a weak 138 ** table. Non-collectable objects are never removed from weak 139 ** tables. Strings behave as 'values', so are never removed too. for 140 ** other objects: if really collected, cannot keep them; for objects 141 ** being finalized, keep them in keys, but not in values 142 */ 143 static int iscleared (global_State *g, const TValue *o) { 144 if (!iscollectable(o)) return 0; 145 else if (ttisstring(o)) { 146 markobject(g, tsvalue(o)); /* strings are 'values', so are never weak */ 147 return 0; 148 } 149 else return iswhite(gcvalue(o)); 150 } 151 152 153 /* 154 ** barrier that moves collector forward, that is, mark the white object 155 ** being pointed by a black object. (If in sweep phase, clear the black 156 ** object to white [sweep it] to avoid other barrier calls for this 157 ** same object.) 158 */ 159 void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { 160 global_State *g = G(L); 161 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 162 if (keepinvariant(g)) /* must keep invariant? */ 163 reallymarkobject(g, v); /* restore invariant */ 164 else { /* sweep phase */ 165 lua_assert(issweepphase(g)); 166 makewhite(g, o); /* mark main obj. as white to avoid other barriers */ 167 } 168 } 169 170 171 /* 172 ** barrier that moves collector backward, that is, mark the black object 173 ** pointing to a white object as gray again. 174 */ 175 void luaC_barrierback_ (lua_State *L, Table *t) { 176 global_State *g = G(L); 177 lua_assert(isblack(t) && !isdead(g, t)); 178 black2gray(t); /* make table gray (again) */ 179 linkgclist(t, g->grayagain); 180 } 181 182 183 /* 184 ** barrier for assignments to closed upvalues. Because upvalues are 185 ** shared among closures, it is impossible to know the color of all 186 ** closures pointing to it. So, we assume that the object being assigned 187 ** must be marked. 188 */ 189 void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) { 190 global_State *g = G(L); 191 GCObject *o = gcvalue(uv->v); 192 lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */ 193 if (keepinvariant(g)) 194 markobject(g, o); 195 } 196 197 198 void luaC_fix (lua_State *L, GCObject *o) { 199 global_State *g = G(L); 200 lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ 201 white2gray(o); /* they will be gray forever */ 202 g->allgc = o->next; /* remove object from 'allgc' list */ 203 o->next = g->fixedgc; /* link it to 'fixedgc' list */ 204 g->fixedgc = o; 205 } 206 207 208 /* 209 ** create a new collectable object (with given type and size) and link 210 ** it to 'allgc' list. 211 */ 212 GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { 213 global_State *g = G(L); 214 GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); 215 o->marked = luaC_white(g); 216 o->tt = tt; 217 o->next = g->allgc; 218 g->allgc = o; 219 return o; 220 } 221 222 /* }====================================================== */ 223 224 225 226 /* 227 ** {====================================================== 228 ** Mark functions 229 ** ======================================================= 230 */ 231 232 233 /* 234 ** mark an object. Userdata, strings, and closed upvalues are visited 235 ** and turned black here. Other objects are marked gray and added 236 ** to appropriate list to be visited (and turned black) later. (Open 237 ** upvalues are already linked in 'headuv' list.) 238 */ 239 static void reallymarkobject (global_State *g, GCObject *o) { 240 reentry: 241 white2gray(o); 242 switch (o->tt) { 243 case LUA_TSHRSTR: { 244 gray2black(o); 245 g->GCmemtrav += sizelstring(gco2ts(o)->shrlen); 246 break; 247 } 248 case LUA_TLNGSTR: { 249 gray2black(o); 250 g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen); 251 break; 252 } 253 case LUA_TUSERDATA: { 254 TValue uvalue; 255 markobjectN(g, gco2u(o)->metatable); /* mark its metatable */ 256 gray2black(o); 257 g->GCmemtrav += sizeudata(gco2u(o)); 258 getuservalue(g->mainthread, gco2u(o), &uvalue); 259 if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */ 260 o = gcvalue(&uvalue); 261 goto reentry; 262 } 263 break; 264 } 265 case LUA_TLCL: { 266 linkgclist(gco2lcl(o), g->gray); 267 break; 268 } 269 case LUA_TCCL: { 270 linkgclist(gco2ccl(o), g->gray); 271 break; 272 } 273 case LUA_TTABLE: { 274 linkgclist(gco2t(o), g->gray); 275 break; 276 } 277 case LUA_TTHREAD: { 278 linkgclist(gco2th(o), g->gray); 279 break; 280 } 281 case LUA_TPROTO: { 282 linkgclist(gco2p(o), g->gray); 283 break; 284 } 285 default: lua_assert(0); break; 286 } 287 } 288 289 290 /* 291 ** mark metamethods for basic types 292 */ 293 static void markmt (global_State *g) { 294 int i; 295 for (i=0; i < LUA_NUMTAGS; i++) 296 markobjectN(g, g->mt[i]); 297 } 298 299 300 /* 301 ** mark all objects in list of being-finalized 302 */ 303 static void markbeingfnz (global_State *g) { 304 GCObject *o; 305 for (o = g->tobefnz; o != NULL; o = o->next) 306 markobject(g, o); 307 } 308 309 310 /* 311 ** Mark all values stored in marked open upvalues from non-marked threads. 312 ** (Values from marked threads were already marked when traversing the 313 ** thread.) Remove from the list threads that no longer have upvalues and 314 ** not-marked threads. 315 */ 316 static void remarkupvals (global_State *g) { 317 lua_State *thread; 318 lua_State **p = &g->twups; 319 while ((thread = *p) != NULL) { 320 lua_assert(!isblack(thread)); /* threads are never black */ 321 if (isgray(thread) && thread->openupval != NULL) 322 p = &thread->twups; /* keep marked thread with upvalues in the list */ 323 else { /* thread is not marked or without upvalues */ 324 UpVal *uv; 325 *p = thread->twups; /* remove thread from the list */ 326 thread->twups = thread; /* mark that it is out of list */ 327 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { 328 if (uv->u.open.touched) { 329 markvalue(g, uv->v); /* remark upvalue's value */ 330 uv->u.open.touched = 0; 331 } 332 } 333 } 334 } 335 } 336 337 338 /* 339 ** mark root set and reset all gray lists, to start a new collection 340 */ 341 static void restartcollection (global_State *g) { 342 g->gray = g->grayagain = NULL; 343 g->weak = g->allweak = g->ephemeron = NULL; 344 markobject(g, g->mainthread); 345 markvalue(g, &g->l_registry); 346 markmt(g); 347 markbeingfnz(g); /* mark any finalizing object left from previous cycle */ 348 } 349 350 /* }====================================================== */ 351 352 353 /* 354 ** {====================================================== 355 ** Traverse functions 356 ** ======================================================= 357 */ 358 359 /* 360 ** Traverse a table with weak values and link it to proper list. During 361 ** propagate phase, keep it in 'grayagain' list, to be revisited in the 362 ** atomic phase. In the atomic phase, if table has any white value, 363 ** put it in 'weak' list, to be cleared. 364 */ 365 static void traverseweakvalue (global_State *g, Table *h) { 366 Node *n, *limit = gnodelast(h); 367 /* if there is array part, assume it may have white values (it is not 368 worth traversing it now just to check) */ 369 int hasclears = (h->sizearray > 0); 370 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ 371 checkdeadkey(n); 372 if (ttisnil(gval(n))) /* entry is empty? */ 373 removeentry(n); /* remove it */ 374 else { 375 lua_assert(!ttisnil(gkey(n))); 376 markvalue(g, gkey(n)); /* mark key */ 377 if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ 378 hasclears = 1; /* table will have to be cleared */ 379 } 380 } 381 if (g->gcstate == GCSpropagate) 382 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ 383 else if (hasclears) 384 linkgclist(h, g->weak); /* has to be cleared later */ 385 } 386 387 388 /* 389 ** Traverse an ephemeron table and link it to proper list. Returns true 390 ** iff any object was marked during this traversal (which implies that 391 ** convergence has to continue). During propagation phase, keep table 392 ** in 'grayagain' list, to be visited again in the atomic phase. In 393 ** the atomic phase, if table has any white->white entry, it has to 394 ** be revisited during ephemeron convergence (as that key may turn 395 ** black). Otherwise, if it has any white key, table has to be cleared 396 ** (in the atomic phase). 397 */ 398 static int traverseephemeron (global_State *g, Table *h) { 399 int marked = 0; /* true if an object is marked in this traversal */ 400 int hasclears = 0; /* true if table has white keys */ 401 int hasww = 0; /* true if table has entry "white-key -> white-value" */ 402 Node *n, *limit = gnodelast(h); 403 unsigned int i; 404 /* traverse array part */ 405 for (i = 0; i < h->sizearray; i++) { 406 if (valiswhite(&h->array[i])) { 407 marked = 1; 408 reallymarkobject(g, gcvalue(&h->array[i])); 409 } 410 } 411 /* traverse hash part */ 412 for (n = gnode(h, 0); n < limit; n++) { 413 checkdeadkey(n); 414 if (ttisnil(gval(n))) /* entry is empty? */ 415 removeentry(n); /* remove it */ 416 else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ 417 hasclears = 1; /* table must be cleared */ 418 if (valiswhite(gval(n))) /* value not marked yet? */ 419 hasww = 1; /* white-white entry */ 420 } 421 else if (valiswhite(gval(n))) { /* value not marked yet? */ 422 marked = 1; 423 reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ 424 } 425 } 426 /* link table into proper list */ 427 if (g->gcstate == GCSpropagate) 428 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ 429 else if (hasww) /* table has white->white entries? */ 430 linkgclist(h, g->ephemeron); /* have to propagate again */ 431 else if (hasclears) /* table has white keys? */ 432 linkgclist(h, g->allweak); /* may have to clean white keys */ 433 return marked; 434 } 435 436 437 static void traversestrongtable (global_State *g, Table *h) { 438 Node *n, *limit = gnodelast(h); 439 unsigned int i; 440 for (i = 0; i < h->sizearray; i++) /* traverse array part */ 441 markvalue(g, &h->array[i]); 442 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ 443 checkdeadkey(n); 444 if (ttisnil(gval(n))) /* entry is empty? */ 445 removeentry(n); /* remove it */ 446 else { 447 lua_assert(!ttisnil(gkey(n))); 448 markvalue(g, gkey(n)); /* mark key */ 449 markvalue(g, gval(n)); /* mark value */ 450 } 451 } 452 } 453 454 455 static lu_mem traversetable (global_State *g, Table *h) { 456 const char *weakkey, *weakvalue; 457 const TValue *mode = gfasttm(g, h->metatable, TM_MODE); 458 markobjectN(g, h->metatable); 459 if (mode && ttisstring(mode) && /* is there a weak mode? */ 460 ((weakkey = strchr(svalue(mode), 'k')), 461 (weakvalue = strchr(svalue(mode), 'v')), 462 (weakkey || weakvalue))) { /* is really weak? */ 463 black2gray(h); /* keep table gray */ 464 if (!weakkey) /* strong keys? */ 465 traverseweakvalue(g, h); 466 else if (!weakvalue) /* strong values? */ 467 traverseephemeron(g, h); 468 else /* all weak */ 469 linkgclist(h, g->allweak); /* nothing to traverse now */ 470 } 471 else /* not weak */ 472 traversestrongtable(g, h); 473 return sizeof(Table) + sizeof(TValue) * h->sizearray + 474 sizeof(Node) * cast(size_t, allocsizenode(h)); 475 } 476 477 478 /* 479 ** Traverse a prototype. (While a prototype is being build, its 480 ** arrays can be larger than needed; the extra slots are filled with 481 ** NULL, so the use of 'markobjectN') 482 */ 483 static int traverseproto (global_State *g, Proto *f) { 484 int i; 485 if (f->cache && iswhite(f->cache)) 486 f->cache = NULL; /* allow cache to be collected */ 487 markobjectN(g, f->source); 488 for (i = 0; i < f->sizek; i++) /* mark literals */ 489 markvalue(g, &f->k[i]); 490 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ 491 markobjectN(g, f->upvalues[i].name); 492 for (i = 0; i < f->sizep; i++) /* mark nested protos */ 493 markobjectN(g, f->p[i]); 494 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ 495 markobjectN(g, f->locvars[i].varname); 496 return sizeof(Proto) + sizeof(Instruction) * f->sizecode + 497 sizeof(Proto *) * f->sizep + 498 sizeof(TValue) * f->sizek + 499 sizeof(int) * f->sizelineinfo + 500 sizeof(LocVar) * f->sizelocvars + 501 sizeof(Upvaldesc) * f->sizeupvalues; 502 } 503 504 505 static lu_mem traverseCclosure (global_State *g, CClosure *cl) { 506 int i; 507 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ 508 markvalue(g, &cl->upvalue[i]); 509 return sizeCclosure(cl->nupvalues); 510 } 511 512 /* 513 ** open upvalues point to values in a thread, so those values should 514 ** be marked when the thread is traversed except in the atomic phase 515 ** (because then the value cannot be changed by the thread and the 516 ** thread may not be traversed again) 517 */ 518 static lu_mem traverseLclosure (global_State *g, LClosure *cl) { 519 int i; 520 markobjectN(g, cl->p); /* mark its prototype */ 521 for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */ 522 UpVal *uv = cl->upvals[i]; 523 if (uv != NULL) { 524 if (upisopen(uv) && g->gcstate != GCSinsideatomic) 525 uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */ 526 else 527 markvalue(g, uv->v); 528 } 529 } 530 return sizeLclosure(cl->nupvalues); 531 } 532 533 534 static lu_mem traversethread (global_State *g, lua_State *th) { 535 StkId o = th->stack; 536 if (o == NULL) 537 return 1; /* stack not completely built yet */ 538 lua_assert(g->gcstate == GCSinsideatomic || 539 th->openupval == NULL || isintwups(th)); 540 for (; o < th->top; o++) /* mark live elements in the stack */ 541 markvalue(g, o); 542 if (g->gcstate == GCSinsideatomic) { /* final traversal? */ 543 StkId lim = th->stack + th->stacksize; /* real end of stack */ 544 for (; o < lim; o++) /* clear not-marked stack slice */ 545 setnilvalue(o); 546 /* 'remarkupvals' may have removed thread from 'twups' list */ 547 if (!isintwups(th) && th->openupval != NULL) { 548 th->twups = g->twups; /* link it back to the list */ 549 g->twups = th; 550 } 551 } 552 else if (g->gckind != KGC_EMERGENCY) 553 luaD_shrinkstack(th); /* do not change stack in emergency cycle */ 554 return (sizeof(lua_State) + sizeof(TValue) * th->stacksize + 555 sizeof(CallInfo) * th->nci); 556 } 557 558 559 /* 560 ** traverse one gray object, turning it to black (except for threads, 561 ** which are always gray). 562 */ 563 static void propagatemark (global_State *g) { 564 lu_mem size; 565 GCObject *o = g->gray; 566 lua_assert(isgray(o)); 567 gray2black(o); 568 switch (o->tt) { 569 case LUA_TTABLE: { 570 Table *h = gco2t(o); 571 g->gray = h->gclist; /* remove from 'gray' list */ 572 size = traversetable(g, h); 573 break; 574 } 575 case LUA_TLCL: { 576 LClosure *cl = gco2lcl(o); 577 g->gray = cl->gclist; /* remove from 'gray' list */ 578 size = traverseLclosure(g, cl); 579 break; 580 } 581 case LUA_TCCL: { 582 CClosure *cl = gco2ccl(o); 583 g->gray = cl->gclist; /* remove from 'gray' list */ 584 size = traverseCclosure(g, cl); 585 break; 586 } 587 case LUA_TTHREAD: { 588 lua_State *th = gco2th(o); 589 g->gray = th->gclist; /* remove from 'gray' list */ 590 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ 591 black2gray(o); 592 size = traversethread(g, th); 593 break; 594 } 595 case LUA_TPROTO: { 596 Proto *p = gco2p(o); 597 g->gray = p->gclist; /* remove from 'gray' list */ 598 size = traverseproto(g, p); 599 break; 600 } 601 default: lua_assert(0); return; 602 } 603 g->GCmemtrav += size; 604 } 605 606 607 static void propagateall (global_State *g) { 608 while (g->gray) propagatemark(g); 609 } 610 611 612 static void convergeephemerons (global_State *g) { 613 int changed; 614 do { 615 GCObject *w; 616 GCObject *next = g->ephemeron; /* get ephemeron list */ 617 g->ephemeron = NULL; /* tables may return to this list when traversed */ 618 changed = 0; 619 while ((w = next) != NULL) { 620 next = gco2t(w)->gclist; 621 if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ 622 propagateall(g); /* propagate changes */ 623 changed = 1; /* will have to revisit all ephemeron tables */ 624 } 625 } 626 } while (changed); 627 } 628 629 /* }====================================================== */ 630 631 632 /* 633 ** {====================================================== 634 ** Sweep Functions 635 ** ======================================================= 636 */ 637 638 639 /* 640 ** clear entries with unmarked keys from all weaktables in list 'l' up 641 ** to element 'f' 642 */ 643 static void clearkeys (global_State *g, GCObject *l, GCObject *f) { 644 for (; l != f; l = gco2t(l)->gclist) { 645 Table *h = gco2t(l); 646 Node *n, *limit = gnodelast(h); 647 for (n = gnode(h, 0); n < limit; n++) { 648 if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { 649 setnilvalue(gval(n)); /* remove value ... */ 650 } 651 if (ttisnil(gval(n))) /* is entry empty? */ 652 removeentry(n); /* remove entry from table */ 653 } 654 } 655 } 656 657 658 /* 659 ** clear entries with unmarked values from all weaktables in list 'l' up 660 ** to element 'f' 661 */ 662 static void clearvalues (global_State *g, GCObject *l, GCObject *f) { 663 for (; l != f; l = gco2t(l)->gclist) { 664 Table *h = gco2t(l); 665 Node *n, *limit = gnodelast(h); 666 unsigned int i; 667 for (i = 0; i < h->sizearray; i++) { 668 TValue *o = &h->array[i]; 669 if (iscleared(g, o)) /* value was collected? */ 670 setnilvalue(o); /* remove value */ 671 } 672 for (n = gnode(h, 0); n < limit; n++) { 673 if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { 674 setnilvalue(gval(n)); /* remove value ... */ 675 removeentry(n); /* and remove entry from table */ 676 } 677 } 678 } 679 } 680 681 682 void luaC_upvdeccount (lua_State *L, UpVal *uv) { 683 lua_assert(uv->refcount > 0); 684 uv->refcount--; 685 if (uv->refcount == 0 && !upisopen(uv)) 686 luaM_free(L, uv); 687 } 688 689 690 static void freeLclosure (lua_State *L, LClosure *cl) { 691 int i; 692 for (i = 0; i < cl->nupvalues; i++) { 693 UpVal *uv = cl->upvals[i]; 694 if (uv) 695 luaC_upvdeccount(L, uv); 696 } 697 luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); 698 } 699 700 701 static void freeobj (lua_State *L, GCObject *o) { 702 switch (o->tt) { 703 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; 704 case LUA_TLCL: { 705 freeLclosure(L, gco2lcl(o)); 706 break; 707 } 708 case LUA_TCCL: { 709 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); 710 break; 711 } 712 case LUA_TTABLE: luaH_free(L, gco2t(o)); break; 713 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; 714 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; 715 case LUA_TSHRSTR: 716 luaS_remove(L, gco2ts(o)); /* remove it from hash table */ 717 luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); 718 break; 719 case LUA_TLNGSTR: { 720 luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); 721 break; 722 } 723 default: lua_assert(0); 724 } 725 } 726 727 728 #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) 729 static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); 730 731 732 /* 733 ** sweep at most 'count' elements from a list of GCObjects erasing dead 734 ** objects, where a dead object is one marked with the old (non current) 735 ** white; change all non-dead objects back to white, preparing for next 736 ** collection cycle. Return where to continue the traversal or NULL if 737 ** list is finished. 738 */ 739 static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { 740 global_State *g = G(L); 741 int ow = otherwhite(g); 742 int white = luaC_white(g); /* current white */ 743 while (*p != NULL && count-- > 0) { 744 GCObject *curr = *p; 745 int marked = curr->marked; 746 if (isdeadm(ow, marked)) { /* is 'curr' dead? */ 747 *p = curr->next; /* remove 'curr' from list */ 748 freeobj(L, curr); /* erase 'curr' */ 749 } 750 else { /* change mark to 'white' */ 751 curr->marked = cast_byte((marked & maskcolors) | white); 752 p = &curr->next; /* go to next element */ 753 } 754 } 755 return (*p == NULL) ? NULL : p; 756 } 757 758 759 /* 760 ** sweep a list until a live object (or end of list) 761 */ 762 static GCObject **sweeptolive (lua_State *L, GCObject **p) { 763 GCObject **old = p; 764 do { 765 p = sweeplist(L, p, 1); 766 } while (p == old); 767 return p; 768 } 769 770 /* }====================================================== */ 771 772 773 /* 774 ** {====================================================== 775 ** Finalization 776 ** ======================================================= 777 */ 778 779 /* 780 ** If possible, shrink string table 781 */ 782 static void checkSizes (lua_State *L, global_State *g) { 783 if (g->gckind != KGC_EMERGENCY) { 784 l_mem olddebt = g->GCdebt; 785 if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ 786 luaS_resize(L, g->strt.size / 2); /* shrink it a little */ 787 g->GCestimate += g->GCdebt - olddebt; /* update estimate */ 788 } 789 } 790 791 792 static GCObject *udata2finalize (global_State *g) { 793 GCObject *o = g->tobefnz; /* get first element */ 794 lua_assert(tofinalize(o)); 795 g->tobefnz = o->next; /* remove it from 'tobefnz' list */ 796 o->next = g->allgc; /* return it to 'allgc' list */ 797 g->allgc = o; 798 resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ 799 if (issweepphase(g)) 800 makewhite(g, o); /* "sweep" object */ 801 return o; 802 } 803 804 805 static void dothecall (lua_State *L, void *ud) { 806 UNUSED(ud); 807 luaD_callnoyield(L, L->top - 2, 0); 808 } 809 810 811 static void GCTM (lua_State *L, int propagateerrors) { 812 global_State *g = G(L); 813 const TValue *tm; 814 TValue v; 815 setgcovalue(L, &v, udata2finalize(g)); 816 tm = luaT_gettmbyobj(L, &v, TM_GC); 817 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ 818 int status; 819 lu_byte oldah = L->allowhook; 820 int running = g->gcrunning; 821 L->allowhook = 0; /* stop debug hooks during GC metamethod */ 822 g->gcrunning = 0; /* avoid GC steps */ 823 setobj2s(L, L->top, tm); /* push finalizer... */ 824 setobj2s(L, L->top + 1, &v); /* ... and its argument */ 825 L->top += 2; /* and (next line) call the finalizer */ 826 L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ 827 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); 828 L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ 829 L->allowhook = oldah; /* restore hooks */ 830 g->gcrunning = running; /* restore state */ 831 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ 832 if (status == LUA_ERRRUN) { /* is there an error object? */ 833 const char *msg = (ttisstring(L->top - 1)) 834 ? svalue(L->top - 1) 835 : "no message"; 836 luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); 837 status = LUA_ERRGCMM; /* error in __gc metamethod */ 838 } 839 luaD_throw(L, status); /* re-throw error */ 840 } 841 } 842 } 843 844 845 /* 846 ** call a few (up to 'g->gcfinnum') finalizers 847 */ 848 static int runafewfinalizers (lua_State *L) { 849 global_State *g = G(L); 850 unsigned int i; 851 lua_assert(!g->tobefnz || g->gcfinnum > 0); 852 for (i = 0; g->tobefnz && i < g->gcfinnum; i++) 853 GCTM(L, 1); /* call one finalizer */ 854 g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */ 855 : g->gcfinnum * 2; /* else call a few more next time */ 856 return i; 857 } 858 859 860 /* 861 ** call all pending finalizers 862 */ 863 static void callallpendingfinalizers (lua_State *L) { 864 global_State *g = G(L); 865 while (g->tobefnz) 866 GCTM(L, 0); 867 } 868 869 870 /* 871 ** find last 'next' field in list 'p' list (to add elements in its end) 872 */ 873 static GCObject **findlast (GCObject **p) { 874 while (*p != NULL) 875 p = &(*p)->next; 876 return p; 877 } 878 879 880 /* 881 ** move all unreachable objects (or 'all' objects) that need 882 ** finalization from list 'finobj' to list 'tobefnz' (to be finalized) 883 */ 884 static void separatetobefnz (global_State *g, int all) { 885 GCObject *curr; 886 GCObject **p = &g->finobj; 887 GCObject **lastnext = findlast(&g->tobefnz); 888 while ((curr = *p) != NULL) { /* traverse all finalizable objects */ 889 lua_assert(tofinalize(curr)); 890 if (!(iswhite(curr) || all)) /* not being collected? */ 891 p = &curr->next; /* don't bother with it */ 892 else { 893 *p = curr->next; /* remove 'curr' from 'finobj' list */ 894 curr->next = *lastnext; /* link at the end of 'tobefnz' list */ 895 *lastnext = curr; 896 lastnext = &curr->next; 897 } 898 } 899 } 900 901 902 /* 903 ** if object 'o' has a finalizer, remove it from 'allgc' list (must 904 ** search the list to find it) and link it in 'finobj' list. 905 */ 906 void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { 907 global_State *g = G(L); 908 if (tofinalize(o) || /* obj. is already marked... */ 909 gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ 910 return; /* nothing to be done */ 911 else { /* move 'o' to 'finobj' list */ 912 GCObject **p; 913 if (issweepphase(g)) { 914 makewhite(g, o); /* "sweep" object 'o' */ 915 if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ 916 g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ 917 } 918 /* search for pointer pointing to 'o' */ 919 for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } 920 *p = o->next; /* remove 'o' from 'allgc' list */ 921 o->next = g->finobj; /* link it in 'finobj' list */ 922 g->finobj = o; 923 l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ 924 } 925 } 926 927 /* }====================================================== */ 928 929 930 931 /* 932 ** {====================================================== 933 ** GC control 934 ** ======================================================= 935 */ 936 937 938 /* 939 ** Set a reasonable "time" to wait before starting a new GC cycle; cycle 940 ** will start when memory use hits threshold. (Division by 'estimate' 941 ** should be OK: it cannot be zero (because Lua cannot even start with 942 ** less than PAUSEADJ bytes). 943 */ 944 static void setpause (global_State *g) { 945 l_mem threshold, debt; 946 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ 947 lua_assert(estimate > 0); 948 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ 949 ? estimate * g->gcpause /* no overflow */ 950 : MAX_LMEM; /* overflow; truncate to maximum */ 951 debt = gettotalbytes(g) - threshold; 952 luaE_setdebt(g, debt); 953 } 954 955 956 /* 957 ** Enter first sweep phase. 958 ** The call to 'sweeplist' tries to make pointer point to an object 959 ** inside the list (instead of to the header), so that the real sweep do 960 ** not need to skip objects created between "now" and the start of the 961 ** real sweep. 962 */ 963 static void entersweep (lua_State *L) { 964 global_State *g = G(L); 965 g->gcstate = GCSswpallgc; 966 lua_assert(g->sweepgc == NULL); 967 g->sweepgc = sweeplist(L, &g->allgc, 1); 968 } 969 970 971 void luaC_freeallobjects (lua_State *L) { 972 global_State *g = G(L); 973 separatetobefnz(g, 1); /* separate all objects with finalizers */ 974 lua_assert(g->finobj == NULL); 975 callallpendingfinalizers(L); 976 lua_assert(g->tobefnz == NULL); 977 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ 978 g->gckind = KGC_NORMAL; 979 sweepwholelist(L, &g->finobj); 980 sweepwholelist(L, &g->allgc); 981 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ 982 lua_assert(g->strt.nuse == 0); 983 } 984 985 986 static l_mem atomic (lua_State *L) { 987 global_State *g = G(L); 988 l_mem work; 989 GCObject *origweak, *origall; 990 GCObject *grayagain = g->grayagain; /* save original list */ 991 lua_assert(g->ephemeron == NULL && g->weak == NULL); 992 lua_assert(!iswhite(g->mainthread)); 993 g->gcstate = GCSinsideatomic; 994 g->GCmemtrav = 0; /* start counting work */ 995 markobject(g, L); /* mark running thread */ 996 /* registry and global metatables may be changed by API */ 997 markvalue(g, &g->l_registry); 998 markmt(g); /* mark global metatables */ 999 /* remark occasional upvalues of (maybe) dead threads */ 1000 remarkupvals(g); 1001 propagateall(g); /* propagate changes */ 1002 work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */ 1003 g->gray = grayagain; 1004 propagateall(g); /* traverse 'grayagain' list */ 1005 g->GCmemtrav = 0; /* restart counting */ 1006 convergeephemerons(g); 1007 /* at this point, all strongly accessible objects are marked. */ 1008 /* Clear values from weak tables, before checking finalizers */ 1009 clearvalues(g, g->weak, NULL); 1010 clearvalues(g, g->allweak, NULL); 1011 origweak = g->weak; origall = g->allweak; 1012 work += g->GCmemtrav; /* stop counting (objects being finalized) */ 1013 separatetobefnz(g, 0); /* separate objects to be finalized */ 1014 g->gcfinnum = 1; /* there may be objects to be finalized */ 1015 markbeingfnz(g); /* mark objects that will be finalized */ 1016 propagateall(g); /* remark, to propagate 'resurrection' */ 1017 g->GCmemtrav = 0; /* restart counting */ 1018 convergeephemerons(g); 1019 /* at this point, all resurrected objects are marked. */ 1020 /* remove dead objects from weak tables */ 1021 clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ 1022 clearkeys(g, g->allweak, NULL); /* clear keys from all 'allweak' tables */ 1023 /* clear values from resurrected weak tables */ 1024 clearvalues(g, g->weak, origweak); 1025 clearvalues(g, g->allweak, origall); 1026 luaS_clearcache(g); 1027 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 1028 work += g->GCmemtrav; /* complete counting */ 1029 return work; /* estimate of memory marked by 'atomic' */ 1030 } 1031 1032 1033 static lu_mem sweepstep (lua_State *L, global_State *g, 1034 int nextstate, GCObject **nextlist) { 1035 if (g->sweepgc) { 1036 l_mem olddebt = g->GCdebt; 1037 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); 1038 g->GCestimate += g->GCdebt - olddebt; /* update estimate */ 1039 if (g->sweepgc) /* is there still something to sweep? */ 1040 return (GCSWEEPMAX * GCSWEEPCOST); 1041 } 1042 /* else enter next state */ 1043 g->gcstate = nextstate; 1044 g->sweepgc = nextlist; 1045 return 0; 1046 } 1047 1048 1049 static lu_mem singlestep (lua_State *L) { 1050 global_State *g = G(L); 1051 switch (g->gcstate) { 1052 case GCSpause: { 1053 g->GCmemtrav = g->strt.size * sizeof(GCObject*); 1054 restartcollection(g); 1055 g->gcstate = GCSpropagate; 1056 return g->GCmemtrav; 1057 } 1058 case GCSpropagate: { 1059 g->GCmemtrav = 0; 1060 lua_assert(g->gray); 1061 propagatemark(g); 1062 if (g->gray == NULL) /* no more gray objects? */ 1063 g->gcstate = GCSatomic; /* finish propagate phase */ 1064 return g->GCmemtrav; /* memory traversed in this step */ 1065 } 1066 case GCSatomic: { 1067 lu_mem work; 1068 propagateall(g); /* make sure gray list is empty */ 1069 work = atomic(L); /* work is what was traversed by 'atomic' */ 1070 entersweep(L); 1071 g->GCestimate = gettotalbytes(g); /* first estimate */; 1072 return work; 1073 } 1074 case GCSswpallgc: { /* sweep "regular" objects */ 1075 return sweepstep(L, g, GCSswpfinobj, &g->finobj); 1076 } 1077 case GCSswpfinobj: { /* sweep objects with finalizers */ 1078 return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); 1079 } 1080 case GCSswptobefnz: { /* sweep objects to be finalized */ 1081 return sweepstep(L, g, GCSswpend, NULL); 1082 } 1083 case GCSswpend: { /* finish sweeps */ 1084 makewhite(g, g->mainthread); /* sweep main thread */ 1085 checkSizes(L, g); 1086 g->gcstate = GCScallfin; 1087 return 0; 1088 } 1089 case GCScallfin: { /* call remaining finalizers */ 1090 if (g->tobefnz && g->gckind != KGC_EMERGENCY) { 1091 int n = runafewfinalizers(L); 1092 return (n * GCFINALIZECOST); 1093 } 1094 else { /* emergency mode or no more finalizers */ 1095 g->gcstate = GCSpause; /* finish collection */ 1096 return 0; 1097 } 1098 } 1099 default: lua_assert(0); return 0; 1100 } 1101 } 1102 1103 1104 /* 1105 ** advances the garbage collector until it reaches a state allowed 1106 ** by 'statemask' 1107 */ 1108 void luaC_runtilstate (lua_State *L, int statesmask) { 1109 global_State *g = G(L); 1110 while (!testbit(statesmask, g->gcstate)) 1111 singlestep(L); 1112 } 1113 1114 1115 /* 1116 ** get GC debt and convert it from Kb to 'work units' (avoid zero debt 1117 ** and overflows) 1118 */ 1119 static l_mem getdebt (global_State *g) { 1120 l_mem debt = g->GCdebt; 1121 int stepmul = g->gcstepmul; 1122 if (debt <= 0) return 0; /* minimal debt */ 1123 else { 1124 debt = (debt / STEPMULADJ) + 1; 1125 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; 1126 return debt; 1127 } 1128 } 1129 1130 /* 1131 ** performs a basic GC step when collector is running 1132 */ 1133 void luaC_step (lua_State *L) { 1134 global_State *g = G(L); 1135 l_mem debt = getdebt(g); /* GC deficit (be paid now) */ 1136 if (!g->gcrunning) { /* not running? */ 1137 luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */ 1138 return; 1139 } 1140 do { /* repeat until pause or enough "credit" (negative debt) */ 1141 lu_mem work = singlestep(L); /* perform one single step */ 1142 debt -= work; 1143 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); 1144 if (g->gcstate == GCSpause) 1145 setpause(g); /* pause until next cycle */ 1146 else { 1147 debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */ 1148 luaE_setdebt(g, debt); 1149 runafewfinalizers(L); 1150 } 1151 } 1152 1153 1154 /* 1155 ** Performs a full GC cycle; if 'isemergency', set a flag to avoid 1156 ** some operations which could change the interpreter state in some 1157 ** unexpected ways (running finalizers and shrinking some structures). 1158 ** Before running the collection, check 'keepinvariant'; if it is true, 1159 ** there may be some objects marked as black, so the collector has 1160 ** to sweep all objects to turn them back to white (as white has not 1161 ** changed, nothing will be collected). 1162 */ 1163 void luaC_fullgc (lua_State *L, int isemergency) { 1164 global_State *g = G(L); 1165 lua_assert(g->gckind == KGC_NORMAL); 1166 if (isemergency) g->gckind = KGC_EMERGENCY; /* set flag */ 1167 if (keepinvariant(g)) { /* black objects? */ 1168 entersweep(L); /* sweep everything to turn them back to white */ 1169 } 1170 /* finish any pending sweep phase to start a new cycle */ 1171 luaC_runtilstate(L, bitmask(GCSpause)); 1172 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ 1173 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ 1174 /* estimate must be correct after a full GC cycle */ 1175 lua_assert(g->GCestimate == gettotalbytes(g)); 1176 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ 1177 g->gckind = KGC_NORMAL; 1178 setpause(g); 1179 } 1180 1181 /* }====================================================== */ 1182 1183 1184