1 /* $NetBSD: lgc.c,v 1.13 2023/06/08 21:12:08 nikita Exp $ */ 2 3 /* 4 ** Id: lgc.c 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 #ifndef _KERNEL 15 #include <stdio.h> 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 ** Maximum number of elements to sweep in each single step. 35 ** (Large enough to dissipate fixed overheads but small enough 36 ** to allow small steps for the collector.) 37 */ 38 #define GCSWEEPMAX 100 39 40 /* 41 ** Maximum number of finalizers to call in each single step. 42 */ 43 #define GCFINMAX 10 44 45 46 /* 47 ** Cost of calling one finalizer. 48 */ 49 #define GCFINALIZECOST 50 50 51 52 /* 53 ** The equivalent, in bytes, of one unit of "work" (visiting a slot, 54 ** sweeping an object, etc.) 55 */ 56 #define WORK2MEM sizeof(TValue) 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 /* mask with all color bits */ 67 #define maskcolors (bitmask(BLACKBIT) | WHITEBITS) 68 69 /* mask with all GC bits */ 70 #define maskgcbits (maskcolors | AGEBITS) 71 72 73 /* macro to erase all color bits then set only the current white bit */ 74 #define makewhite(g,x) \ 75 (x->marked = cast_byte((x->marked & ~maskcolors) | luaC_white(g))) 76 77 /* make an object gray (neither white nor black) */ 78 #define set2gray(x) resetbits(x->marked, maskcolors) 79 80 81 /* make an object black (coming from any color) */ 82 #define set2black(x) \ 83 (x->marked = cast_byte((x->marked & ~WHITEBITS) | bitmask(BLACKBIT))) 84 85 86 #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 87 88 #define keyiswhite(n) (keyiscollectable(n) && iswhite(gckey(n))) 89 90 91 /* 92 ** Protected access to objects in values 93 */ 94 #define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) 95 96 97 #define markvalue(g,o) { checkliveness(g->mainthread,o); \ 98 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } 99 100 #define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); } 101 102 #define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } 103 104 /* 105 ** mark an object that can be NULL (either because it is really optional, 106 ** or it was stripped as debug info, or inside an uncompleted structure) 107 */ 108 #define markobjectN(g,t) { if (t) markobject(g,t); } 109 110 static void reallymarkobject (global_State *g, GCObject *o); 111 static lu_mem atomic (lua_State *L); 112 static void entersweep (lua_State *L); 113 114 115 /* 116 ** {====================================================== 117 ** Generic functions 118 ** ======================================================= 119 */ 120 121 122 /* 123 ** one after last element in a hash array 124 */ 125 #define gnodelast(h) gnode(h, cast_sizet(sizenode(h))) 126 127 128 static GCObject **getgclist (GCObject *o) { 129 switch (o->tt) { 130 case LUA_VTABLE: return &gco2t(o)->gclist; 131 case LUA_VLCL: return &gco2lcl(o)->gclist; 132 case LUA_VCCL: return &gco2ccl(o)->gclist; 133 case LUA_VTHREAD: return &gco2th(o)->gclist; 134 case LUA_VPROTO: return &gco2p(o)->gclist; 135 case LUA_VUSERDATA: { 136 Udata *u = gco2u(o); 137 lua_assert(u->nuvalue > 0); 138 return &u->gclist; 139 } 140 default: lua_assert(0); return 0; 141 } 142 } 143 144 145 /* 146 ** Link a collectable object 'o' with a known type into the list 'p'. 147 ** (Must be a macro to access the 'gclist' field in different types.) 148 */ 149 #define linkgclist(o,p) linkgclist_(obj2gco(o), &(o)->gclist, &(p)) 150 151 static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) { 152 lua_assert(!isgray(o)); /* cannot be in a gray list */ 153 *pnext = *list; 154 *list = o; 155 set2gray(o); /* now it is */ 156 } 157 158 159 /* 160 ** Link a generic collectable object 'o' into the list 'p'. 161 */ 162 #define linkobjgclist(o,p) linkgclist_(obj2gco(o), getgclist(o), &(p)) 163 164 165 166 /* 167 ** Clear keys for empty entries in tables. If entry is empty, mark its 168 ** entry as dead. This allows the collection of the key, but keeps its 169 ** entry in the table: its removal could break a chain and could break 170 ** a table traversal. Other places never manipulate dead keys, because 171 ** its associated empty value is enough to signal that the entry is 172 ** logically empty. 173 */ 174 static void clearkey (Node *n) { 175 lua_assert(isempty(gval(n))); 176 if (keyiscollectable(n)) 177 setdeadkey(n); /* unused key; remove it */ 178 } 179 180 181 /* 182 ** tells whether a key or value can be cleared from a weak 183 ** table. Non-collectable objects are never removed from weak 184 ** tables. Strings behave as 'values', so are never removed too. for 185 ** other objects: if really collected, cannot keep them; for objects 186 ** being finalized, keep them in keys, but not in values 187 */ 188 static int iscleared (global_State *g, const GCObject *o) { 189 if (o == NULL) return 0; /* non-collectable value */ 190 else if (novariant(o->tt) == LUA_TSTRING) { 191 markobject(g, o); /* strings are 'values', so are never weak */ 192 return 0; 193 } 194 else return iswhite(o); 195 } 196 197 198 /* 199 ** Barrier that moves collector forward, that is, marks the white object 200 ** 'v' being pointed by the black object 'o'. In the generational 201 ** mode, 'v' must also become old, if 'o' is old; however, it cannot 202 ** be changed directly to OLD, because it may still point to non-old 203 ** objects. So, it is marked as OLD0. In the next cycle it will become 204 ** OLD1, and in the next it will finally become OLD (regular old). By 205 ** then, any object it points to will also be old. If called in the 206 ** incremental sweep phase, it clears the black object to white (sweep 207 ** it) to avoid other barrier calls for this same object. (That cannot 208 ** be done is generational mode, as its sweep does not distinguish 209 ** whites from deads.) 210 */ 211 void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { 212 global_State *g = G(L); 213 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 214 if (keepinvariant(g)) { /* must keep invariant? */ 215 reallymarkobject(g, v); /* restore invariant */ 216 if (isold(o)) { 217 lua_assert(!isold(v)); /* white object could not be old */ 218 setage(v, G_OLD0); /* restore generational invariant */ 219 } 220 } 221 else { /* sweep phase */ 222 lua_assert(issweepphase(g)); 223 if (g->gckind == KGC_INC) /* incremental mode? */ 224 makewhite(g, o); /* mark 'o' as white to avoid other barriers */ 225 } 226 } 227 228 229 /* 230 ** barrier that moves collector backward, that is, mark the black object 231 ** pointing to a white object as gray again. 232 */ 233 void luaC_barrierback_ (lua_State *L, GCObject *o) { 234 global_State *g = G(L); 235 lua_assert(isblack(o) && !isdead(g, o)); 236 lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1)); 237 if (getage(o) == G_TOUCHED2) /* already in gray list? */ 238 set2gray(o); /* make it gray to become touched1 */ 239 else /* link it in 'grayagain' and paint it gray */ 240 linkobjgclist(o, g->grayagain); 241 if (isold(o)) /* generational mode? */ 242 setage(o, G_TOUCHED1); /* touched in current cycle */ 243 } 244 245 246 void luaC_fix (lua_State *L, GCObject *o) { 247 global_State *g = G(L); 248 lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ 249 set2gray(o); /* they will be gray forever */ 250 setage(o, G_OLD); /* and old forever */ 251 g->allgc = o->next; /* remove object from 'allgc' list */ 252 o->next = g->fixedgc; /* link it to 'fixedgc' list */ 253 g->fixedgc = o; 254 } 255 256 257 /* 258 ** create a new collectable object (with given type, size, and offset) 259 ** and link it to 'allgc' list. 260 */ 261 GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) { 262 global_State *g = G(L); 263 char *p = cast_charp(luaM_newobject(L, novariant(tt), sz)); 264 GCObject *o = cast(GCObject *, p + offset); 265 o->marked = luaC_white(g); 266 o->tt = tt; 267 o->next = g->allgc; 268 g->allgc = o; 269 return o; 270 } 271 272 273 GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { 274 return luaC_newobjdt(L, tt, sz, 0); 275 } 276 277 /* }====================================================== */ 278 279 280 281 /* 282 ** {====================================================== 283 ** Mark functions 284 ** ======================================================= 285 */ 286 287 288 /* 289 ** Mark an object. Userdata with no user values, strings, and closed 290 ** upvalues are visited and turned black here. Open upvalues are 291 ** already indirectly linked through their respective threads in the 292 ** 'twups' list, so they don't go to the gray list; nevertheless, they 293 ** are kept gray to avoid barriers, as their values will be revisited 294 ** by the thread or by 'remarkupvals'. Other objects are added to the 295 ** gray list to be visited (and turned black) later. Both userdata and 296 ** upvalues can call this function recursively, but this recursion goes 297 ** for at most two levels: An upvalue cannot refer to another upvalue 298 ** (only closures can), and a userdata's metatable must be a table. 299 */ 300 static void reallymarkobject (global_State *g, GCObject *o) { 301 switch (o->tt) { 302 case LUA_VSHRSTR: 303 case LUA_VLNGSTR: { 304 set2black(o); /* nothing to visit */ 305 break; 306 } 307 case LUA_VUPVAL: { 308 UpVal *uv = gco2upv(o); 309 if (upisopen(uv)) 310 set2gray(uv); /* open upvalues are kept gray */ 311 else 312 set2black(uv); /* closed upvalues are visited here */ 313 markvalue(g, uv->v.p); /* mark its content */ 314 break; 315 } 316 case LUA_VUSERDATA: { 317 Udata *u = gco2u(o); 318 if (u->nuvalue == 0) { /* no user values? */ 319 markobjectN(g, u->metatable); /* mark its metatable */ 320 set2black(u); /* nothing else to mark */ 321 break; 322 } 323 /* else... */ 324 } /* FALLTHROUGH */ 325 case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE: 326 case LUA_VTHREAD: case LUA_VPROTO: { 327 linkobjgclist(o, g->gray); /* to be visited later */ 328 break; 329 } 330 default: lua_assert(0); break; 331 } 332 } 333 334 335 /* 336 ** mark metamethods for basic types 337 */ 338 static void markmt (global_State *g) { 339 int i; 340 for (i=0; i < LUA_NUMTAGS; i++) 341 markobjectN(g, g->mt[i]); 342 } 343 344 345 /* 346 ** mark all objects in list of being-finalized 347 */ 348 static lu_mem markbeingfnz (global_State *g) { 349 GCObject *o; 350 lu_mem count = 0; 351 for (o = g->tobefnz; o != NULL; o = o->next) { 352 count++; 353 markobject(g, o); 354 } 355 return count; 356 } 357 358 359 /* 360 ** For each non-marked thread, simulates a barrier between each open 361 ** upvalue and its value. (If the thread is collected, the value will be 362 ** assigned to the upvalue, but then it can be too late for the barrier 363 ** to act. The "barrier" does not need to check colors: A non-marked 364 ** thread must be young; upvalues cannot be older than their threads; so 365 ** any visited upvalue must be young too.) Also removes the thread from 366 ** the list, as it was already visited. Removes also threads with no 367 ** upvalues, as they have nothing to be checked. (If the thread gets an 368 ** upvalue later, it will be linked in the list again.) 369 */ 370 static int remarkupvals (global_State *g) { 371 lua_State *thread; 372 lua_State **p = &g->twups; 373 int work = 0; /* estimate of how much work was done here */ 374 while ((thread = *p) != NULL) { 375 work++; 376 if (!iswhite(thread) && thread->openupval != NULL) 377 p = &thread->twups; /* keep marked thread with upvalues in the list */ 378 else { /* thread is not marked or without upvalues */ 379 UpVal *uv; 380 lua_assert(!isold(thread) || thread->openupval == NULL); 381 *p = thread->twups; /* remove thread from the list */ 382 thread->twups = thread; /* mark that it is out of list */ 383 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { 384 lua_assert(getage(uv) <= getage(thread)); 385 work++; 386 if (!iswhite(uv)) { /* upvalue already visited? */ 387 lua_assert(upisopen(uv) && isgray(uv)); 388 markvalue(g, uv->v.p); /* mark its value */ 389 } 390 } 391 } 392 } 393 return work; 394 } 395 396 397 static void cleargraylists (global_State *g) { 398 g->gray = g->grayagain = NULL; 399 g->weak = g->allweak = g->ephemeron = NULL; 400 } 401 402 403 /* 404 ** mark root set and reset all gray lists, to start a new collection 405 */ 406 static void restartcollection (global_State *g) { 407 cleargraylists(g); 408 markobject(g, g->mainthread); 409 markvalue(g, &g->l_registry); 410 markmt(g); 411 markbeingfnz(g); /* mark any finalizing object left from previous cycle */ 412 } 413 414 /* }====================================================== */ 415 416 417 /* 418 ** {====================================================== 419 ** Traverse functions 420 ** ======================================================= 421 */ 422 423 424 /* 425 ** Check whether object 'o' should be kept in the 'grayagain' list for 426 ** post-processing by 'correctgraylist'. (It could put all old objects 427 ** in the list and leave all the work to 'correctgraylist', but it is 428 ** more efficient to avoid adding elements that will be removed.) Only 429 ** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go 430 ** back to a gray list, but then it must become OLD. (That is what 431 ** 'correctgraylist' does when it finds a TOUCHED2 object.) 432 */ 433 static void genlink (global_State *g, GCObject *o) { 434 lua_assert(isblack(o)); 435 if (getage(o) == G_TOUCHED1) { /* touched in this cycle? */ 436 linkobjgclist(o, g->grayagain); /* link it back in 'grayagain' */ 437 } /* everything else do not need to be linked back */ 438 else if (getage(o) == G_TOUCHED2) 439 changeage(o, G_TOUCHED2, G_OLD); /* advance age */ 440 } 441 442 443 /* 444 ** Traverse a table with weak values and link it to proper list. During 445 ** propagate phase, keep it in 'grayagain' list, to be revisited in the 446 ** atomic phase. In the atomic phase, if table has any white value, 447 ** put it in 'weak' list, to be cleared. 448 */ 449 static void traverseweakvalue (global_State *g, Table *h) { 450 Node *n, *limit = gnodelast(h); 451 /* if there is array part, assume it may have white values (it is not 452 worth traversing it now just to check) */ 453 int hasclears = (h->alimit > 0); 454 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ 455 if (isempty(gval(n))) /* entry is empty? */ 456 clearkey(n); /* clear its key */ 457 else { 458 lua_assert(!keyisnil(n)); 459 markkey(g, n); 460 if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ 461 hasclears = 1; /* table will have to be cleared */ 462 } 463 } 464 if (g->gcstate == GCSatomic && hasclears) 465 linkgclist(h, g->weak); /* has to be cleared later */ 466 else 467 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ 468 } 469 470 471 /* 472 ** Traverse an ephemeron table and link it to proper list. Returns true 473 ** iff any object was marked during this traversal (which implies that 474 ** convergence has to continue). During propagation phase, keep table 475 ** in 'grayagain' list, to be visited again in the atomic phase. In 476 ** the atomic phase, if table has any white->white entry, it has to 477 ** be revisited during ephemeron convergence (as that key may turn 478 ** black). Otherwise, if it has any white key, table has to be cleared 479 ** (in the atomic phase). In generational mode, some tables 480 ** must be kept in some gray list for post-processing; this is done 481 ** by 'genlink'. 482 */ 483 static int traverseephemeron (global_State *g, Table *h, int inv) { 484 int marked = 0; /* true if an object is marked in this traversal */ 485 int hasclears = 0; /* true if table has white keys */ 486 int hasww = 0; /* true if table has entry "white-key -> white-value" */ 487 unsigned int i; 488 unsigned int asize = luaH_realasize(h); 489 unsigned int nsize = sizenode(h); 490 /* traverse array part */ 491 for (i = 0; i < asize; i++) { 492 if (valiswhite(&h->array[i])) { 493 marked = 1; 494 reallymarkobject(g, gcvalue(&h->array[i])); 495 } 496 } 497 /* traverse hash part; if 'inv', traverse descending 498 (see 'convergeephemerons') */ 499 for (i = 0; i < nsize; i++) { 500 Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i); 501 if (isempty(gval(n))) /* entry is empty? */ 502 clearkey(n); /* clear its key */ 503 else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ 504 hasclears = 1; /* table must be cleared */ 505 if (valiswhite(gval(n))) /* value not marked yet? */ 506 hasww = 1; /* white-white entry */ 507 } 508 else if (valiswhite(gval(n))) { /* value not marked yet? */ 509 marked = 1; 510 reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ 511 } 512 } 513 /* link table into proper list */ 514 if (g->gcstate == GCSpropagate) 515 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ 516 else if (hasww) /* table has white->white entries? */ 517 linkgclist(h, g->ephemeron); /* have to propagate again */ 518 else if (hasclears) /* table has white keys? */ 519 linkgclist(h, g->allweak); /* may have to clean white keys */ 520 else 521 genlink(g, obj2gco(h)); /* check whether collector still needs to see it */ 522 return marked; 523 } 524 525 526 static void traversestrongtable (global_State *g, Table *h) { 527 Node *n, *limit = gnodelast(h); 528 unsigned int i; 529 unsigned int asize = luaH_realasize(h); 530 for (i = 0; i < asize; i++) /* traverse array part */ 531 markvalue(g, &h->array[i]); 532 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ 533 if (isempty(gval(n))) /* entry is empty? */ 534 clearkey(n); /* clear its key */ 535 else { 536 lua_assert(!keyisnil(n)); 537 markkey(g, n); 538 markvalue(g, gval(n)); 539 } 540 } 541 genlink(g, obj2gco(h)); 542 } 543 544 545 static lu_mem traversetable (global_State *g, Table *h) { 546 const char *weakkey, *weakvalue; 547 const TValue *mode = gfasttm(g, h->metatable, TM_MODE); 548 markobjectN(g, h->metatable); 549 if (mode && ttisstring(mode) && /* is there a weak mode? */ 550 (cast_void(weakkey = strchr(svalue(mode), 'k')), 551 cast_void(weakvalue = strchr(svalue(mode), 'v')), 552 (weakkey || weakvalue))) { /* is really weak? */ 553 if (!weakkey) /* strong keys? */ 554 traverseweakvalue(g, h); 555 else if (!weakvalue) /* strong values? */ 556 traverseephemeron(g, h, 0); 557 else /* all weak */ 558 linkgclist(h, g->allweak); /* nothing to traverse now */ 559 } 560 else /* not weak */ 561 traversestrongtable(g, h); 562 return 1 + h->alimit + 2 * allocsizenode(h); 563 } 564 565 566 static int traverseudata (global_State *g, Udata *u) { 567 int i; 568 markobjectN(g, u->metatable); /* mark its metatable */ 569 for (i = 0; i < u->nuvalue; i++) 570 markvalue(g, &u->uv[i].uv); 571 genlink(g, obj2gco(u)); 572 return 1 + u->nuvalue; 573 } 574 575 576 /* 577 ** Traverse a prototype. (While a prototype is being build, its 578 ** arrays can be larger than needed; the extra slots are filled with 579 ** NULL, so the use of 'markobjectN') 580 */ 581 static int traverseproto (global_State *g, Proto *f) { 582 int i; 583 markobjectN(g, f->source); 584 for (i = 0; i < f->sizek; i++) /* mark literals */ 585 markvalue(g, &f->k[i]); 586 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ 587 markobjectN(g, f->upvalues[i].name); 588 for (i = 0; i < f->sizep; i++) /* mark nested protos */ 589 markobjectN(g, f->p[i]); 590 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ 591 markobjectN(g, f->locvars[i].varname); 592 return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; 593 } 594 595 596 static int traverseCclosure (global_State *g, CClosure *cl) { 597 int i; 598 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ 599 markvalue(g, &cl->upvalue[i]); 600 return 1 + cl->nupvalues; 601 } 602 603 /* 604 ** Traverse a Lua closure, marking its prototype and its upvalues. 605 ** (Both can be NULL while closure is being created.) 606 */ 607 static int traverseLclosure (global_State *g, LClosure *cl) { 608 int i; 609 markobjectN(g, cl->p); /* mark its prototype */ 610 for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ 611 UpVal *uv = cl->upvals[i]; 612 markobjectN(g, uv); /* mark upvalue */ 613 } 614 return 1 + cl->nupvalues; 615 } 616 617 618 /* 619 ** Traverse a thread, marking the elements in the stack up to its top 620 ** and cleaning the rest of the stack in the final traversal. That 621 ** ensures that the entire stack have valid (non-dead) objects. 622 ** Threads have no barriers. In gen. mode, old threads must be visited 623 ** at every cycle, because they might point to young objects. In inc. 624 ** mode, the thread can still be modified before the end of the cycle, 625 ** and therefore it must be visited again in the atomic phase. To ensure 626 ** these visits, threads must return to a gray list if they are not new 627 ** (which can only happen in generational mode) or if the traverse is in 628 ** the propagate phase (which can only happen in incremental mode). 629 */ 630 static int traversethread (global_State *g, lua_State *th) { 631 UpVal *uv; 632 StkId o = th->stack.p; 633 if (isold(th) || g->gcstate == GCSpropagate) 634 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ 635 if (o == NULL) 636 return 1; /* stack not completely built yet */ 637 lua_assert(g->gcstate == GCSatomic || 638 th->openupval == NULL || isintwups(th)); 639 for (; o < th->top.p; o++) /* mark live elements in the stack */ 640 markvalue(g, s2v(o)); 641 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) 642 markobject(g, uv); /* open upvalues cannot be collected */ 643 if (g->gcstate == GCSatomic) { /* final traversal? */ 644 for (; o < th->stack_last.p + EXTRA_STACK; o++) 645 setnilvalue(s2v(o)); /* clear dead stack slice */ 646 /* 'remarkupvals' may have removed thread from 'twups' list */ 647 if (!isintwups(th) && th->openupval != NULL) { 648 th->twups = g->twups; /* link it back to the list */ 649 g->twups = th; 650 } 651 } 652 else if (!g->gcemergency) 653 luaD_shrinkstack(th); /* do not change stack in emergency cycle */ 654 return 1 + stacksize(th); 655 } 656 657 658 /* 659 ** traverse one gray object, turning it to black. 660 */ 661 static lu_mem propagatemark (global_State *g) { 662 GCObject *o = g->gray; 663 nw2black(o); 664 g->gray = *getgclist(o); /* remove from 'gray' list */ 665 switch (o->tt) { 666 case LUA_VTABLE: return traversetable(g, gco2t(o)); 667 case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); 668 case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); 669 case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); 670 case LUA_VPROTO: return traverseproto(g, gco2p(o)); 671 case LUA_VTHREAD: return traversethread(g, gco2th(o)); 672 default: lua_assert(0); return 0; 673 } 674 } 675 676 677 static lu_mem propagateall (global_State *g) { 678 lu_mem tot = 0; 679 while (g->gray) 680 tot += propagatemark(g); 681 return tot; 682 } 683 684 685 /* 686 ** Traverse all ephemeron tables propagating marks from keys to values. 687 ** Repeat until it converges, that is, nothing new is marked. 'dir' 688 ** inverts the direction of the traversals, trying to speed up 689 ** convergence on chains in the same table. 690 ** 691 */ 692 static void convergeephemerons (global_State *g) { 693 int changed; 694 int dir = 0; 695 do { 696 GCObject *w; 697 GCObject *next = g->ephemeron; /* get ephemeron list */ 698 g->ephemeron = NULL; /* tables may return to this list when traversed */ 699 changed = 0; 700 while ((w = next) != NULL) { /* for each ephemeron table */ 701 Table *h = gco2t(w); 702 next = h->gclist; /* list is rebuilt during loop */ 703 nw2black(h); /* out of the list (for now) */ 704 if (traverseephemeron(g, h, dir)) { /* marked some value? */ 705 propagateall(g); /* propagate changes */ 706 changed = 1; /* will have to revisit all ephemeron tables */ 707 } 708 } 709 dir = !dir; /* invert direction next time */ 710 } while (changed); /* repeat until no more changes */ 711 } 712 713 /* }====================================================== */ 714 715 716 /* 717 ** {====================================================== 718 ** Sweep Functions 719 ** ======================================================= 720 */ 721 722 723 /* 724 ** clear entries with unmarked keys from all weaktables in list 'l' 725 */ 726 static void clearbykeys (global_State *g, GCObject *l) { 727 for (; l; l = gco2t(l)->gclist) { 728 Table *h = gco2t(l); 729 Node *limit = gnodelast(h); 730 Node *n; 731 for (n = gnode(h, 0); n < limit; n++) { 732 if (iscleared(g, gckeyN(n))) /* unmarked key? */ 733 setempty(gval(n)); /* remove entry */ 734 if (isempty(gval(n))) /* is entry empty? */ 735 clearkey(n); /* clear its key */ 736 } 737 } 738 } 739 740 741 /* 742 ** clear entries with unmarked values from all weaktables in list 'l' up 743 ** to element 'f' 744 */ 745 static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { 746 for (; l != f; l = gco2t(l)->gclist) { 747 Table *h = gco2t(l); 748 Node *n, *limit = gnodelast(h); 749 unsigned int i; 750 unsigned int asize = luaH_realasize(h); 751 for (i = 0; i < asize; i++) { 752 TValue *o = &h->array[i]; 753 if (iscleared(g, gcvalueN(o))) /* value was collected? */ 754 setempty(o); /* remove entry */ 755 } 756 for (n = gnode(h, 0); n < limit; n++) { 757 if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ 758 setempty(gval(n)); /* remove entry */ 759 if (isempty(gval(n))) /* is entry empty? */ 760 clearkey(n); /* clear its key */ 761 } 762 } 763 } 764 765 766 static void freeupval (lua_State *L, UpVal *uv) { 767 if (upisopen(uv)) 768 luaF_unlinkupval(uv); 769 luaM_free(L, uv); 770 } 771 772 773 static void freeobj (lua_State *L, GCObject *o) { 774 switch (o->tt) { 775 case LUA_VPROTO: 776 luaF_freeproto(L, gco2p(o)); 777 break; 778 case LUA_VUPVAL: 779 freeupval(L, gco2upv(o)); 780 break; 781 case LUA_VLCL: { 782 LClosure *cl = gco2lcl(o); 783 luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); 784 break; 785 } 786 case LUA_VCCL: { 787 CClosure *cl = gco2ccl(o); 788 luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); 789 break; 790 } 791 case LUA_VTABLE: 792 luaH_free(L, gco2t(o)); 793 break; 794 case LUA_VTHREAD: 795 luaE_freethread(L, gco2th(o)); 796 break; 797 case LUA_VUSERDATA: { 798 Udata *u = gco2u(o); 799 luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); 800 break; 801 } 802 case LUA_VSHRSTR: { 803 TString *ts = gco2ts(o); 804 luaS_remove(L, ts); /* remove it from hash table */ 805 luaM_freemem(L, ts, sizelstring(ts->shrlen)); 806 break; 807 } 808 case LUA_VLNGSTR: { 809 TString *ts = gco2ts(o); 810 luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); 811 break; 812 } 813 default: lua_assert(0); 814 } 815 } 816 817 818 /* 819 ** sweep at most 'countin' elements from a list of GCObjects erasing dead 820 ** objects, where a dead object is one marked with the old (non current) 821 ** white; change all non-dead objects back to white, preparing for next 822 ** collection cycle. Return where to continue the traversal or NULL if 823 ** list is finished. ('*countout' gets the number of elements traversed.) 824 */ 825 static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, 826 int *countout) { 827 global_State *g = G(L); 828 int ow = otherwhite(g); 829 int i; 830 int white = luaC_white(g); /* current white */ 831 for (i = 0; *p != NULL && i < countin; i++) { 832 GCObject *curr = *p; 833 int marked = curr->marked; 834 if (isdeadm(ow, marked)) { /* is 'curr' dead? */ 835 *p = curr->next; /* remove 'curr' from list */ 836 freeobj(L, curr); /* erase 'curr' */ 837 } 838 else { /* change mark to 'white' */ 839 curr->marked = cast_byte((marked & ~maskgcbits) | white); 840 p = &curr->next; /* go to next element */ 841 } 842 } 843 if (countout) 844 *countout = i; /* number of elements traversed */ 845 return (*p == NULL) ? NULL : p; 846 } 847 848 849 /* 850 ** sweep a list until a live object (or end of list) 851 */ 852 static GCObject **sweeptolive (lua_State *L, GCObject **p) { 853 GCObject **old = p; 854 do { 855 p = sweeplist(L, p, 1, NULL); 856 } while (p == old); 857 return p; 858 } 859 860 /* }====================================================== */ 861 862 863 /* 864 ** {====================================================== 865 ** Finalization 866 ** ======================================================= 867 */ 868 869 /* 870 ** If possible, shrink string table. 871 */ 872 static void checkSizes (lua_State *L, global_State *g) { 873 if (!g->gcemergency) { 874 if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ 875 l_mem olddebt = g->GCdebt; 876 luaS_resize(L, g->strt.size / 2); 877 g->GCestimate += g->GCdebt - olddebt; /* correct estimate */ 878 } 879 } 880 } 881 882 883 /* 884 ** Get the next udata to be finalized from the 'tobefnz' list, and 885 ** link it back into the 'allgc' list. 886 */ 887 static GCObject *udata2finalize (global_State *g) { 888 GCObject *o = g->tobefnz; /* get first element */ 889 lua_assert(tofinalize(o)); 890 g->tobefnz = o->next; /* remove it from 'tobefnz' list */ 891 o->next = g->allgc; /* return it to 'allgc' list */ 892 g->allgc = o; 893 resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ 894 if (issweepphase(g)) 895 makewhite(g, o); /* "sweep" object */ 896 else if (getage(o) == G_OLD1) 897 g->firstold1 = o; /* it is the first OLD1 object in the list */ 898 return o; 899 } 900 901 902 static void dothecall (lua_State *L, void *ud) { 903 UNUSED(ud); 904 luaD_callnoyield(L, L->top.p - 2, 0); 905 } 906 907 908 static void GCTM (lua_State *L) { 909 global_State *g = G(L); 910 const TValue *tm; 911 TValue v; 912 lua_assert(!g->gcemergency); 913 setgcovalue(L, &v, udata2finalize(g)); 914 tm = luaT_gettmbyobj(L, &v, TM_GC); 915 if (!notm(tm)) { /* is there a finalizer? */ 916 int status; 917 lu_byte oldah = L->allowhook; 918 int oldgcstp = g->gcstp; 919 g->gcstp |= GCSTPGC; /* avoid GC steps */ 920 L->allowhook = 0; /* stop debug hooks during GC metamethod */ 921 setobj2s(L, L->top.p++, tm); /* push finalizer... */ 922 setobj2s(L, L->top.p++, &v); /* ... and its argument */ 923 L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ 924 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0); 925 L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ 926 L->allowhook = oldah; /* restore hooks */ 927 g->gcstp = oldgcstp; /* restore state */ 928 if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ 929 luaE_warnerror(L, "__gc"); 930 L->top.p--; /* pops error object */ 931 } 932 } 933 } 934 935 936 /* 937 ** Call a few finalizers 938 */ 939 static int runafewfinalizers (lua_State *L, int n) { 940 global_State *g = G(L); 941 int i; 942 for (i = 0; i < n && g->tobefnz; i++) 943 GCTM(L); /* call one finalizer */ 944 return i; 945 } 946 947 948 /* 949 ** call all pending finalizers 950 */ 951 static void callallpendingfinalizers (lua_State *L) { 952 global_State *g = G(L); 953 while (g->tobefnz) 954 GCTM(L); 955 } 956 957 958 /* 959 ** find last 'next' field in list 'p' list (to add elements in its end) 960 */ 961 static GCObject **findlast (GCObject **p) { 962 while (*p != NULL) 963 p = &(*p)->next; 964 return p; 965 } 966 967 968 /* 969 ** Move all unreachable objects (or 'all' objects) that need 970 ** finalization from list 'finobj' to list 'tobefnz' (to be finalized). 971 ** (Note that objects after 'finobjold1' cannot be white, so they 972 ** don't need to be traversed. In incremental mode, 'finobjold1' is NULL, 973 ** so the whole list is traversed.) 974 */ 975 static void separatetobefnz (global_State *g, int all) { 976 GCObject *curr; 977 GCObject **p = &g->finobj; 978 GCObject **lastnext = findlast(&g->tobefnz); 979 while ((curr = *p) != g->finobjold1) { /* traverse all finalizable objects */ 980 lua_assert(tofinalize(curr)); 981 if (!(iswhite(curr) || all)) /* not being collected? */ 982 p = &curr->next; /* don't bother with it */ 983 else { 984 if (curr == g->finobjsur) /* removing 'finobjsur'? */ 985 g->finobjsur = curr->next; /* correct it */ 986 *p = curr->next; /* remove 'curr' from 'finobj' list */ 987 curr->next = *lastnext; /* link at the end of 'tobefnz' list */ 988 *lastnext = curr; 989 lastnext = &curr->next; 990 } 991 } 992 } 993 994 995 /* 996 ** If pointer 'p' points to 'o', move it to the next element. 997 */ 998 static void checkpointer (GCObject **p, GCObject *o) { 999 if (o == *p) 1000 *p = o->next; 1001 } 1002 1003 1004 /* 1005 ** Correct pointers to objects inside 'allgc' list when 1006 ** object 'o' is being removed from the list. 1007 */ 1008 static void correctpointers (global_State *g, GCObject *o) { 1009 checkpointer(&g->survival, o); 1010 checkpointer(&g->old1, o); 1011 checkpointer(&g->reallyold, o); 1012 checkpointer(&g->firstold1, o); 1013 } 1014 1015 1016 /* 1017 ** if object 'o' has a finalizer, remove it from 'allgc' list (must 1018 ** search the list to find it) and link it in 'finobj' list. 1019 */ 1020 void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { 1021 global_State *g = G(L); 1022 if (tofinalize(o) || /* obj. is already marked... */ 1023 gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */ 1024 (g->gcstp & GCSTPCLS)) /* or closing state? */ 1025 return; /* nothing to be done */ 1026 else { /* move 'o' to 'finobj' list */ 1027 GCObject **p; 1028 if (issweepphase(g)) { 1029 makewhite(g, o); /* "sweep" object 'o' */ 1030 if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ 1031 g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ 1032 } 1033 else 1034 correctpointers(g, o); 1035 /* search for pointer pointing to 'o' */ 1036 for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } 1037 *p = o->next; /* remove 'o' from 'allgc' list */ 1038 o->next = g->finobj; /* link it in 'finobj' list */ 1039 g->finobj = o; 1040 l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ 1041 } 1042 } 1043 1044 /* }====================================================== */ 1045 1046 1047 /* 1048 ** {====================================================== 1049 ** Generational Collector 1050 ** ======================================================= 1051 */ 1052 1053 1054 /* 1055 ** Set the "time" to wait before starting a new GC cycle; cycle will 1056 ** start when memory use hits the threshold of ('estimate' * pause / 1057 ** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero, 1058 ** because Lua cannot even start with less than PAUSEADJ bytes). 1059 */ 1060 static void setpause (global_State *g) { 1061 l_mem threshold, debt; 1062 int pause = getgcparam(g->gcpause); 1063 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ 1064 lua_assert(estimate > 0); 1065 threshold = (pause < MAX_LMEM / estimate) /* overflow? */ 1066 ? estimate * pause /* no overflow */ 1067 : MAX_LMEM; /* overflow; truncate to maximum */ 1068 debt = gettotalbytes(g) - threshold; 1069 if (debt > 0) debt = 0; 1070 luaE_setdebt(g, debt); 1071 } 1072 1073 1074 /* 1075 ** Sweep a list of objects to enter generational mode. Deletes dead 1076 ** objects and turns the non dead to old. All non-dead threads---which 1077 ** are now old---must be in a gray list. Everything else is not in a 1078 ** gray list. Open upvalues are also kept gray. 1079 */ 1080 static void sweep2old (lua_State *L, GCObject **p) { 1081 GCObject *curr; 1082 global_State *g = G(L); 1083 while ((curr = *p) != NULL) { 1084 if (iswhite(curr)) { /* is 'curr' dead? */ 1085 lua_assert(isdead(g, curr)); 1086 *p = curr->next; /* remove 'curr' from list */ 1087 freeobj(L, curr); /* erase 'curr' */ 1088 } 1089 else { /* all surviving objects become old */ 1090 setage(curr, G_OLD); 1091 if (curr->tt == LUA_VTHREAD) { /* threads must be watched */ 1092 lua_State *th = gco2th(curr); 1093 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ 1094 } 1095 else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr))) 1096 set2gray(curr); /* open upvalues are always gray */ 1097 else /* everything else is black */ 1098 nw2black(curr); 1099 p = &curr->next; /* go to next element */ 1100 } 1101 } 1102 } 1103 1104 1105 /* 1106 ** Sweep for generational mode. Delete dead objects. (Because the 1107 ** collection is not incremental, there are no "new white" objects 1108 ** during the sweep. So, any white object must be dead.) For 1109 ** non-dead objects, advance their ages and clear the color of 1110 ** new objects. (Old objects keep their colors.) 1111 ** The ages of G_TOUCHED1 and G_TOUCHED2 objects cannot be advanced 1112 ** here, because these old-generation objects are usually not swept 1113 ** here. They will all be advanced in 'correctgraylist'. That function 1114 ** will also remove objects turned white here from any gray list. 1115 */ 1116 static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, 1117 GCObject *limit, GCObject **pfirstold1) { 1118 static const lu_byte nextage[] = { 1119 G_SURVIVAL, /* from G_NEW */ 1120 G_OLD1, /* from G_SURVIVAL */ 1121 G_OLD1, /* from G_OLD0 */ 1122 G_OLD, /* from G_OLD1 */ 1123 G_OLD, /* from G_OLD (do not change) */ 1124 G_TOUCHED1, /* from G_TOUCHED1 (do not change) */ 1125 G_TOUCHED2 /* from G_TOUCHED2 (do not change) */ 1126 }; 1127 int white = luaC_white(g); 1128 GCObject *curr; 1129 while ((curr = *p) != limit) { 1130 if (iswhite(curr)) { /* is 'curr' dead? */ 1131 lua_assert(!isold(curr) && isdead(g, curr)); 1132 *p = curr->next; /* remove 'curr' from list */ 1133 freeobj(L, curr); /* erase 'curr' */ 1134 } 1135 else { /* correct mark and age */ 1136 if (getage(curr) == G_NEW) { /* new objects go back to white */ 1137 int marked = curr->marked & ~maskgcbits; /* erase GC bits */ 1138 curr->marked = cast_byte(marked | G_SURVIVAL | white); 1139 } 1140 else { /* all other objects will be old, and so keep their color */ 1141 setage(curr, nextage[getage(curr)]); 1142 if (getage(curr) == G_OLD1 && *pfirstold1 == NULL) 1143 *pfirstold1 = curr; /* first OLD1 object in the list */ 1144 } 1145 p = &curr->next; /* go to next element */ 1146 } 1147 } 1148 return p; 1149 } 1150 1151 1152 /* 1153 ** Traverse a list making all its elements white and clearing their 1154 ** age. In incremental mode, all objects are 'new' all the time, 1155 ** except for fixed strings (which are always old). 1156 */ 1157 static void whitelist (global_State *g, GCObject *p) { 1158 int white = luaC_white(g); 1159 for (; p != NULL; p = p->next) 1160 p->marked = cast_byte((p->marked & ~maskgcbits) | white); 1161 } 1162 1163 1164 /* 1165 ** Correct a list of gray objects. Return pointer to where rest of the 1166 ** list should be linked. 1167 ** Because this correction is done after sweeping, young objects might 1168 ** be turned white and still be in the list. They are only removed. 1169 ** 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; 1170 ** Non-white threads also remain on the list; 'TOUCHED2' objects become 1171 ** regular old; they and anything else are removed from the list. 1172 */ 1173 static GCObject **correctgraylist (GCObject **p) { 1174 GCObject *curr; 1175 while ((curr = *p) != NULL) { 1176 GCObject **next = getgclist(curr); 1177 if (iswhite(curr)) 1178 goto remove; /* remove all white objects */ 1179 else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ 1180 lua_assert(isgray(curr)); 1181 nw2black(curr); /* make it black, for next barrier */ 1182 changeage(curr, G_TOUCHED1, G_TOUCHED2); 1183 goto remain; /* keep it in the list and go to next element */ 1184 } 1185 else if (curr->tt == LUA_VTHREAD) { 1186 lua_assert(isgray(curr)); 1187 goto remain; /* keep non-white threads on the list */ 1188 } 1189 else { /* everything else is removed */ 1190 lua_assert(isold(curr)); /* young objects should be white here */ 1191 if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ 1192 changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ 1193 nw2black(curr); /* make object black (to be removed) */ 1194 goto remove; 1195 } 1196 remove: *p = *next; continue; 1197 remain: p = next; continue; 1198 } 1199 return p; 1200 } 1201 1202 1203 /* 1204 ** Correct all gray lists, coalescing them into 'grayagain'. 1205 */ 1206 static void correctgraylists (global_State *g) { 1207 GCObject **list = correctgraylist(&g->grayagain); 1208 *list = g->weak; g->weak = NULL; 1209 list = correctgraylist(list); 1210 *list = g->allweak; g->allweak = NULL; 1211 list = correctgraylist(list); 1212 *list = g->ephemeron; g->ephemeron = NULL; 1213 correctgraylist(list); 1214 } 1215 1216 1217 /* 1218 ** Mark black 'OLD1' objects when starting a new young collection. 1219 ** Gray objects are already in some gray list, and so will be visited 1220 ** in the atomic step. 1221 */ 1222 static void markold (global_State *g, GCObject *from, GCObject *to) { 1223 GCObject *p; 1224 for (p = from; p != to; p = p->next) { 1225 if (getage(p) == G_OLD1) { 1226 lua_assert(!iswhite(p)); 1227 changeage(p, G_OLD1, G_OLD); /* now they are old */ 1228 if (isblack(p)) 1229 reallymarkobject(g, p); 1230 } 1231 } 1232 } 1233 1234 1235 /* 1236 ** Finish a young-generation collection. 1237 */ 1238 static void finishgencycle (lua_State *L, global_State *g) { 1239 correctgraylists(g); 1240 checkSizes(L, g); 1241 g->gcstate = GCSpropagate; /* skip restart */ 1242 if (!g->gcemergency) 1243 callallpendingfinalizers(L); 1244 } 1245 1246 1247 /* 1248 ** Does a young collection. First, mark 'OLD1' objects. Then does the 1249 ** atomic step. Then, sweep all lists and advance pointers. Finally, 1250 ** finish the collection. 1251 */ 1252 static void youngcollection (lua_State *L, global_State *g) { 1253 GCObject **psurvival; /* to point to first non-dead survival object */ 1254 GCObject *dummy; /* dummy out parameter to 'sweepgen' */ 1255 lua_assert(g->gcstate == GCSpropagate); 1256 if (g->firstold1) { /* are there regular OLD1 objects? */ 1257 markold(g, g->firstold1, g->reallyold); /* mark them */ 1258 g->firstold1 = NULL; /* no more OLD1 objects (for now) */ 1259 } 1260 markold(g, g->finobj, g->finobjrold); 1261 markold(g, g->tobefnz, NULL); 1262 atomic(L); 1263 1264 /* sweep nursery and get a pointer to its last live element */ 1265 g->gcstate = GCSswpallgc; 1266 psurvival = sweepgen(L, g, &g->allgc, g->survival, &g->firstold1); 1267 /* sweep 'survival' */ 1268 sweepgen(L, g, psurvival, g->old1, &g->firstold1); 1269 g->reallyold = g->old1; 1270 g->old1 = *psurvival; /* 'survival' survivals are old now */ 1271 g->survival = g->allgc; /* all news are survivals */ 1272 1273 /* repeat for 'finobj' lists */ 1274 dummy = NULL; /* no 'firstold1' optimization for 'finobj' lists */ 1275 psurvival = sweepgen(L, g, &g->finobj, g->finobjsur, &dummy); 1276 /* sweep 'survival' */ 1277 sweepgen(L, g, psurvival, g->finobjold1, &dummy); 1278 g->finobjrold = g->finobjold1; 1279 g->finobjold1 = *psurvival; /* 'survival' survivals are old now */ 1280 g->finobjsur = g->finobj; /* all news are survivals */ 1281 1282 sweepgen(L, g, &g->tobefnz, NULL, &dummy); 1283 finishgencycle(L, g); 1284 } 1285 1286 1287 /* 1288 ** Clears all gray lists, sweeps objects, and prepare sublists to enter 1289 ** generational mode. The sweeps remove dead objects and turn all 1290 ** surviving objects to old. Threads go back to 'grayagain'; everything 1291 ** else is turned black (not in any gray list). 1292 */ 1293 static void atomic2gen (lua_State *L, global_State *g) { 1294 cleargraylists(g); 1295 /* sweep all elements making them old */ 1296 g->gcstate = GCSswpallgc; 1297 sweep2old(L, &g->allgc); 1298 /* everything alive now is old */ 1299 g->reallyold = g->old1 = g->survival = g->allgc; 1300 g->firstold1 = NULL; /* there are no OLD1 objects anywhere */ 1301 1302 /* repeat for 'finobj' lists */ 1303 sweep2old(L, &g->finobj); 1304 g->finobjrold = g->finobjold1 = g->finobjsur = g->finobj; 1305 1306 sweep2old(L, &g->tobefnz); 1307 1308 g->gckind = KGC_GEN; 1309 g->lastatomic = 0; 1310 g->GCestimate = gettotalbytes(g); /* base for memory control */ 1311 finishgencycle(L, g); 1312 } 1313 1314 1315 /* 1316 ** Set debt for the next minor collection, which will happen when 1317 ** memory grows 'genminormul'%. 1318 */ 1319 static void setminordebt (global_State *g) { 1320 luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); 1321 } 1322 1323 1324 /* 1325 ** Enter generational mode. Must go until the end of an atomic cycle 1326 ** to ensure that all objects are correctly marked and weak tables 1327 ** are cleared. Then, turn all objects into old and finishes the 1328 ** collection. 1329 */ 1330 static lu_mem entergen (lua_State *L, global_State *g) { 1331 lu_mem numobjs; 1332 luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */ 1333 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ 1334 numobjs = atomic(L); /* propagates all and then do the atomic stuff */ 1335 atomic2gen(L, g); 1336 setminordebt(g); /* set debt assuming next cycle will be minor */ 1337 return numobjs; 1338 } 1339 1340 1341 /* 1342 ** Enter incremental mode. Turn all objects white, make all 1343 ** intermediate lists point to NULL (to avoid invalid pointers), 1344 ** and go to the pause state. 1345 */ 1346 static void enterinc (global_State *g) { 1347 whitelist(g, g->allgc); 1348 g->reallyold = g->old1 = g->survival = NULL; 1349 whitelist(g, g->finobj); 1350 whitelist(g, g->tobefnz); 1351 g->finobjrold = g->finobjold1 = g->finobjsur = NULL; 1352 g->gcstate = GCSpause; 1353 g->gckind = KGC_INC; 1354 g->lastatomic = 0; 1355 } 1356 1357 1358 /* 1359 ** Change collector mode to 'newmode'. 1360 */ 1361 void luaC_changemode (lua_State *L, int newmode) { 1362 global_State *g = G(L); 1363 if (newmode != g->gckind) { 1364 if (newmode == KGC_GEN) /* entering generational mode? */ 1365 entergen(L, g); 1366 else 1367 enterinc(g); /* entering incremental mode */ 1368 } 1369 g->lastatomic = 0; 1370 } 1371 1372 1373 /* 1374 ** Does a full collection in generational mode. 1375 */ 1376 static lu_mem fullgen (lua_State *L, global_State *g) { 1377 enterinc(g); 1378 return entergen(L, g); 1379 } 1380 1381 1382 /* 1383 ** Does a major collection after last collection was a "bad collection". 1384 ** 1385 ** When the program is building a big structure, it allocates lots of 1386 ** memory but generates very little garbage. In those scenarios, 1387 ** the generational mode just wastes time doing small collections, and 1388 ** major collections are frequently what we call a "bad collection", a 1389 ** collection that frees too few objects. To avoid the cost of switching 1390 ** between generational mode and the incremental mode needed for full 1391 ** (major) collections, the collector tries to stay in incremental mode 1392 ** after a bad collection, and to switch back to generational mode only 1393 ** after a "good" collection (one that traverses less than 9/8 objects 1394 ** of the previous one). 1395 ** The collector must choose whether to stay in incremental mode or to 1396 ** switch back to generational mode before sweeping. At this point, it 1397 ** does not know the real memory in use, so it cannot use memory to 1398 ** decide whether to return to generational mode. Instead, it uses the 1399 ** number of objects traversed (returned by 'atomic') as a proxy. The 1400 ** field 'g->lastatomic' keeps this count from the last collection. 1401 ** ('g->lastatomic != 0' also means that the last collection was bad.) 1402 */ 1403 static void stepgenfull (lua_State *L, global_State *g) { 1404 lu_mem newatomic; /* count of traversed objects */ 1405 lu_mem lastatomic = g->lastatomic; /* count from last collection */ 1406 if (g->gckind == KGC_GEN) /* still in generational mode? */ 1407 enterinc(g); /* enter incremental mode */ 1408 luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ 1409 newatomic = atomic(L); /* mark everybody */ 1410 if (newatomic < lastatomic + (lastatomic >> 3)) { /* good collection? */ 1411 atomic2gen(L, g); /* return to generational mode */ 1412 setminordebt(g); 1413 } 1414 else { /* another bad collection; stay in incremental mode */ 1415 g->GCestimate = gettotalbytes(g); /* first estimate */; 1416 entersweep(L); 1417 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ 1418 setpause(g); 1419 g->lastatomic = newatomic; 1420 } 1421 } 1422 1423 1424 /* 1425 ** Does a generational "step". 1426 ** Usually, this means doing a minor collection and setting the debt to 1427 ** make another collection when memory grows 'genminormul'% larger. 1428 ** 1429 ** However, there are exceptions. If memory grows 'genmajormul'% 1430 ** larger than it was at the end of the last major collection (kept 1431 ** in 'g->GCestimate'), the function does a major collection. At the 1432 ** end, it checks whether the major collection was able to free a 1433 ** decent amount of memory (at least half the growth in memory since 1434 ** previous major collection). If so, the collector keeps its state, 1435 ** and the next collection will probably be minor again. Otherwise, 1436 ** we have what we call a "bad collection". In that case, set the field 1437 ** 'g->lastatomic' to signal that fact, so that the next collection will 1438 ** go to 'stepgenfull'. 1439 ** 1440 ** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; 1441 ** in that case, do a minor collection. 1442 */ 1443 static void genstep (lua_State *L, global_State *g) { 1444 if (g->lastatomic != 0) /* last collection was a bad one? */ 1445 stepgenfull(L, g); /* do a full step */ 1446 else { 1447 lu_mem majorbase = g->GCestimate; /* memory after last major collection */ 1448 lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); 1449 if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { 1450 lu_mem numobjs = fullgen(L, g); /* do a major collection */ 1451 if (gettotalbytes(g) < majorbase + (majorinc / 2)) { 1452 /* collected at least half of memory growth since last major 1453 collection; keep doing minor collections. */ 1454 lua_assert(g->lastatomic == 0); 1455 } 1456 else { /* bad collection */ 1457 g->lastatomic = numobjs; /* signal that last collection was bad */ 1458 setpause(g); /* do a long wait for next (major) collection */ 1459 } 1460 } 1461 else { /* regular case; do a minor collection */ 1462 youngcollection(L, g); 1463 setminordebt(g); 1464 g->GCestimate = majorbase; /* preserve base value */ 1465 } 1466 } 1467 lua_assert(isdecGCmodegen(g)); 1468 } 1469 1470 /* }====================================================== */ 1471 1472 1473 /* 1474 ** {====================================================== 1475 ** GC control 1476 ** ======================================================= 1477 */ 1478 1479 1480 /* 1481 ** Enter first sweep phase. 1482 ** The call to 'sweeptolive' makes the pointer point to an object 1483 ** inside the list (instead of to the header), so that the real sweep do 1484 ** not need to skip objects created between "now" and the start of the 1485 ** real sweep. 1486 */ 1487 static void entersweep (lua_State *L) { 1488 global_State *g = G(L); 1489 g->gcstate = GCSswpallgc; 1490 lua_assert(g->sweepgc == NULL); 1491 g->sweepgc = sweeptolive(L, &g->allgc); 1492 } 1493 1494 1495 /* 1496 ** Delete all objects in list 'p' until (but not including) object 1497 ** 'limit'. 1498 */ 1499 static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { 1500 while (p != limit) { 1501 GCObject *next = p->next; 1502 freeobj(L, p); 1503 p = next; 1504 } 1505 } 1506 1507 1508 /* 1509 ** Call all finalizers of the objects in the given Lua state, and 1510 ** then free all objects, except for the main thread. 1511 */ 1512 void luaC_freeallobjects (lua_State *L) { 1513 global_State *g = G(L); 1514 g->gcstp = GCSTPCLS; /* no extra finalizers after here */ 1515 luaC_changemode(L, KGC_INC); 1516 separatetobefnz(g, 1); /* separate all objects with finalizers */ 1517 lua_assert(g->finobj == NULL); 1518 callallpendingfinalizers(L); 1519 deletelist(L, g->allgc, obj2gco(g->mainthread)); 1520 lua_assert(g->finobj == NULL); /* no new finalizers */ 1521 deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ 1522 lua_assert(g->strt.nuse == 0); 1523 } 1524 1525 1526 static lu_mem atomic (lua_State *L) { 1527 global_State *g = G(L); 1528 lu_mem work = 0; 1529 GCObject *origweak, *origall; 1530 GCObject *grayagain = g->grayagain; /* save original list */ 1531 g->grayagain = NULL; 1532 lua_assert(g->ephemeron == NULL && g->weak == NULL); 1533 lua_assert(!iswhite(g->mainthread)); 1534 g->gcstate = GCSatomic; 1535 markobject(g, L); /* mark running thread */ 1536 /* registry and global metatables may be changed by API */ 1537 markvalue(g, &g->l_registry); 1538 markmt(g); /* mark global metatables */ 1539 work += propagateall(g); /* empties 'gray' list */ 1540 /* remark occasional upvalues of (maybe) dead threads */ 1541 work += remarkupvals(g); 1542 work += propagateall(g); /* propagate changes */ 1543 g->gray = grayagain; 1544 work += propagateall(g); /* traverse 'grayagain' list */ 1545 convergeephemerons(g); 1546 /* at this point, all strongly accessible objects are marked. */ 1547 /* Clear values from weak tables, before checking finalizers */ 1548 clearbyvalues(g, g->weak, NULL); 1549 clearbyvalues(g, g->allweak, NULL); 1550 origweak = g->weak; origall = g->allweak; 1551 separatetobefnz(g, 0); /* separate objects to be finalized */ 1552 work += markbeingfnz(g); /* mark objects that will be finalized */ 1553 work += propagateall(g); /* remark, to propagate 'resurrection' */ 1554 convergeephemerons(g); 1555 /* at this point, all resurrected objects are marked. */ 1556 /* remove dead objects from weak tables */ 1557 clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ 1558 clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ 1559 /* clear values from resurrected weak tables */ 1560 clearbyvalues(g, g->weak, origweak); 1561 clearbyvalues(g, g->allweak, origall); 1562 luaS_clearcache(g); 1563 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 1564 lua_assert(g->gray == NULL); 1565 return work; /* estimate of slots marked by 'atomic' */ 1566 } 1567 1568 1569 static int sweepstep (lua_State *L, global_State *g, 1570 int nextstate, GCObject **nextlist) { 1571 if (g->sweepgc) { 1572 l_mem olddebt = g->GCdebt; 1573 int count; 1574 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count); 1575 g->GCestimate += g->GCdebt - olddebt; /* update estimate */ 1576 return count; 1577 } 1578 else { /* enter next state */ 1579 g->gcstate = nextstate; 1580 g->sweepgc = nextlist; 1581 return 0; /* no work done */ 1582 } 1583 } 1584 1585 1586 static lu_mem singlestep (lua_State *L) { 1587 global_State *g = G(L); 1588 lu_mem work; 1589 lua_assert(!g->gcstopem); /* collector is not reentrant */ 1590 g->gcstopem = 1; /* no emergency collections while collecting */ 1591 switch (g->gcstate) { 1592 case GCSpause: { 1593 restartcollection(g); 1594 g->gcstate = GCSpropagate; 1595 work = 1; 1596 break; 1597 } 1598 case GCSpropagate: { 1599 if (g->gray == NULL) { /* no more gray objects? */ 1600 g->gcstate = GCSenteratomic; /* finish propagate phase */ 1601 work = 0; 1602 } 1603 else 1604 work = propagatemark(g); /* traverse one gray object */ 1605 break; 1606 } 1607 case GCSenteratomic: { 1608 work = atomic(L); /* work is what was traversed by 'atomic' */ 1609 entersweep(L); 1610 g->GCestimate = gettotalbytes(g); /* first estimate */; 1611 break; 1612 } 1613 case GCSswpallgc: { /* sweep "regular" objects */ 1614 work = sweepstep(L, g, GCSswpfinobj, &g->finobj); 1615 break; 1616 } 1617 case GCSswpfinobj: { /* sweep objects with finalizers */ 1618 work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); 1619 break; 1620 } 1621 case GCSswptobefnz: { /* sweep objects to be finalized */ 1622 work = sweepstep(L, g, GCSswpend, NULL); 1623 break; 1624 } 1625 case GCSswpend: { /* finish sweeps */ 1626 checkSizes(L, g); 1627 g->gcstate = GCScallfin; 1628 work = 0; 1629 break; 1630 } 1631 case GCScallfin: { /* call remaining finalizers */ 1632 if (g->tobefnz && !g->gcemergency) { 1633 g->gcstopem = 0; /* ok collections during finalizers */ 1634 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; 1635 } 1636 else { /* emergency mode or no more finalizers */ 1637 g->gcstate = GCSpause; /* finish collection */ 1638 work = 0; 1639 } 1640 break; 1641 } 1642 default: lua_assert(0); return 0; 1643 } 1644 g->gcstopem = 0; 1645 return work; 1646 } 1647 1648 1649 /* 1650 ** advances the garbage collector until it reaches a state allowed 1651 ** by 'statemask' 1652 */ 1653 void luaC_runtilstate (lua_State *L, int statesmask) { 1654 global_State *g = G(L); 1655 while (!testbit(statesmask, g->gcstate)) 1656 singlestep(L); 1657 } 1658 1659 1660 1661 /* 1662 ** Performs a basic incremental step. The debt and step size are 1663 ** converted from bytes to "units of work"; then the function loops 1664 ** running single steps until adding that many units of work or 1665 ** finishing a cycle (pause state). Finally, it sets the debt that 1666 ** controls when next step will be performed. 1667 */ 1668 static void incstep (lua_State *L, global_State *g) { 1669 int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ 1670 l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; 1671 l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem)) 1672 ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul 1673 : MAX_LMEM; /* overflow; keep maximum value */ 1674 do { /* repeat until pause or enough "credit" (negative debt) */ 1675 lu_mem work = singlestep(L); /* perform one single step */ 1676 debt -= work; 1677 } while (debt > -stepsize && g->gcstate != GCSpause); 1678 if (g->gcstate == GCSpause) 1679 setpause(g); /* pause until next cycle */ 1680 else { 1681 debt = (debt / stepmul) * WORK2MEM; /* convert 'work units' to bytes */ 1682 luaE_setdebt(g, debt); 1683 } 1684 } 1685 1686 /* 1687 ** Performs a basic GC step if collector is running. (If collector is 1688 ** not running, set a reasonable debt to avoid it being called at 1689 ** every single check.) 1690 */ 1691 void luaC_step (lua_State *L) { 1692 global_State *g = G(L); 1693 if (!gcrunning(g)) /* not running? */ 1694 luaE_setdebt(g, -2000); 1695 else { 1696 if(isdecGCmodegen(g)) 1697 genstep(L, g); 1698 else 1699 incstep(L, g); 1700 } 1701 } 1702 1703 1704 /* 1705 ** Perform a full collection in incremental mode. 1706 ** Before running the collection, check 'keepinvariant'; if it is true, 1707 ** there may be some objects marked as black, so the collector has 1708 ** to sweep all objects to turn them back to white (as white has not 1709 ** changed, nothing will be collected). 1710 */ 1711 static void fullinc (lua_State *L, global_State *g) { 1712 if (keepinvariant(g)) /* black objects? */ 1713 entersweep(L); /* sweep everything to turn them back to white */ 1714 /* finish any pending sweep phase to start a new cycle */ 1715 luaC_runtilstate(L, bitmask(GCSpause)); 1716 luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ 1717 /* estimate must be correct after a full GC cycle */ 1718 lua_assert(g->GCestimate == gettotalbytes(g)); 1719 luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ 1720 setpause(g); 1721 } 1722 1723 1724 /* 1725 ** Performs a full GC cycle; if 'isemergency', set a flag to avoid 1726 ** some operations which could change the interpreter state in some 1727 ** unexpected ways (running finalizers and shrinking some structures). 1728 */ 1729 void luaC_fullgc (lua_State *L, int isemergency) { 1730 global_State *g = G(L); 1731 lua_assert(!g->gcemergency); 1732 g->gcemergency = isemergency; /* set flag */ 1733 if (g->gckind == KGC_INC) 1734 fullinc(L, g); 1735 else 1736 fullgen(L, g); 1737 g->gcemergency = 0; 1738 } 1739 1740 /* }====================================================== */ 1741 1742 1743