Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. ** $Id: lgc.c,v 2.116 2011/12/02 13:18:41 roberto Exp $
  3. ** Garbage Collector
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7. #include <string.h>
  8.  
  9. #define lgc_c
  10. #define LUA_CORE
  11.  
  12. #include "lua.h"
  13.  
  14. #include "ldebug.h"
  15. #include "ldo.h"
  16. #include "lfunc.h"
  17. #include "lgc.h"
  18. #include "lmem.h"
  19. #include "lobject.h"
  20. #include "lstate.h"
  21. #include "lstring.h"
  22. #include "ltable.h"
  23. #include "ltm.h"
  24.  
  25.  
  26.  
  27. /* how much to allocate before next GC step */
  28. #define GCSTEPSIZE      1024
  29.  
  30. /* maximum number of elements to sweep in each single step */
  31. #define GCSWEEPMAX      40
  32.  
  33. /* cost of sweeping one element */
  34. #define GCSWEEPCOST     1
  35.  
  36. /* maximum number of finalizers to call in each GC step */
  37. #define GCFINALIZENUM   4
  38.  
  39. /* cost of marking the root set */
  40. #define GCROOTCOST      10
  41.  
  42. /* cost of atomic step */
  43. #define GCATOMICCOST    1000
  44.  
  45. /* basic cost to traverse one object (to be added to the links the
  46.    object may have) */
  47. #define TRAVCOST        5
  48.  
  49.  
  50. /*
  51. ** standard negative debt for GC; a reasonable "time" to wait before
  52. ** starting a new cycle
  53. */
  54. #define stddebt(g)      (-cast(l_mem, gettotalbytes(g)/100) * g->gcpause)
  55.  
  56.  
  57. /*
  58. ** 'makewhite' erases all color bits plus the old bit and then
  59. ** sets only the current white bit
  60. */
  61. #define maskcolors      (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))
  62. #define makewhite(g,x)  \
  63.  (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
  64.  
  65. #define white2gray(x)   resetbits(gch(x)->marked, WHITEBITS)
  66. #define black2gray(x)   resetbit(gch(x)->marked, BLACKBIT)
  67.  
  68. #define stringmark(s)   ((void)((s) && resetbits((s)->tsv.marked, WHITEBITS)))
  69.  
  70.  
  71. #define isfinalized(x)          testbit(gch(x)->marked, FINALIZEDBIT)
  72.  
  73. #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
  74.  
  75.  
  76. #define checkconsistency(obj)  \
  77.   lua_longassert(!iscollectable(obj) || righttt(obj))
  78.  
  79.  
  80. #define markvalue(g,o) { checkconsistency(o); \
  81.   if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
  82.  
  83. #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \
  84.                 reallymarkobject(g, obj2gco(t)); }
  85.  
  86. static void reallymarkobject (global_State *g, GCObject *o);
  87.  
  88.  
  89. /*
  90. ** {======================================================
  91. ** Generic functions
  92. ** =======================================================
  93. */
  94.  
  95.  
  96. /*
  97. ** one after last element in a hash array
  98. */
  99. #define gnodelast(h)    gnode(h, cast(size_t, sizenode(h)))
  100.  
  101.  
  102. /*
  103. ** link table 'h' into list pointed by 'p'
  104. */
  105. #define linktable(h,p)  ((h)->gclist = *(p), *(p) = obj2gco(h))
  106.  
  107.  
  108. /*
  109. ** if key is not marked, mark its entry as dead (therefore removing it
  110. ** from the table)
  111. */
  112. static void removeentry (Node *n) {
  113.   lua_assert(ttisnil(gval(n)));
  114.   if (valiswhite(gkey(n)))
  115.     setdeadvalue(gkey(n));  /* unused and unmarked key; remove it */
  116. }
  117.  
  118.  
  119. /*
  120. ** tells whether a key or value can be cleared from a weak
  121. ** table. Non-collectable objects are never removed from weak
  122. ** tables. Strings behave as `values', so are never removed too. for
  123. ** other objects: if really collected, cannot keep them; for objects
  124. ** being finalized, keep them in keys, but not in values
  125. */
  126. static int iscleared (const TValue *o) {
  127.   if (!iscollectable(o)) return 0;
  128.   else if (ttisstring(o)) {
  129.     stringmark(rawtsvalue(o));  /* strings are `values', so are never weak */
  130.     return 0;
  131.   }
  132.   else return iswhite(gcvalue(o));
  133. }
  134.  
  135.  
  136. /*
  137. ** barrier that moves collector forward, that is, mark the white object
  138. ** being pointed by a black object.
  139. */
  140. void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
  141.   global_State *g = G(L);
  142.   lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
  143.   lua_assert(isgenerational(g) || g->gcstate != GCSpause);
  144.   lua_assert(gch(o)->tt != LUA_TTABLE);
  145.   if (keepinvariant(g))  /* must keep invariant? */
  146.     reallymarkobject(g, v);  /* restore invariant */
  147.   else {  /* sweep phase */
  148.     lua_assert(issweepphase(g));
  149.     makewhite(g, o);  /* mark main obj. as white to avoid other barriers */
  150.   }
  151. }
  152.  
  153.  
  154. /*
  155. ** barrier that moves collector backward, that is, mark the black object
  156. ** pointing to a white object as gray again. (Current implementation
  157. ** only works for tables; access to 'gclist' is not uniform across
  158. ** different types.)
  159. */
  160. void luaC_barrierback_ (lua_State *L, GCObject *o) {
  161.   global_State *g = G(L);
  162.   lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
  163.   black2gray(o);  /* make object gray (again) */
  164.   gco2t(o)->gclist = g->grayagain;
  165.   g->grayagain = o;
  166. }
  167.  
  168.  
  169. /*
  170. ** barrier for prototypes. When creating first closure (cache is
  171. ** NULL), use a forward barrier; this may be the only closure of the
  172. ** prototype (if it is a "regular" function, with a single instance)
  173. ** and the prototype may be big, so it is better to avoid traversing
  174. ** it again. Otherwise, use a backward barrier, to avoid marking all
  175. ** possible instances.
  176. */
  177. LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {
  178.   global_State *g = G(L);
  179.   lua_assert(isblack(obj2gco(p)));
  180.   if (p->cache == NULL) {  /* first time? */
  181.     luaC_objbarrier(L, p, c);
  182.   }
  183.   else {  /* use a backward barrier */
  184.     black2gray(obj2gco(p));  /* make prototype gray (again) */
  185.     p->gclist = g->grayagain;
  186.     g->grayagain = obj2gco(p);
  187.   }
  188. }
  189.  
  190.  
  191. /*
  192. ** check color (and invariants) for an upvalue that was closed,
  193. ** i.e., moved into the 'allgc' list
  194. */
  195. void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
  196.   GCObject *o = obj2gco(uv);
  197.   lua_assert(!isblack(o));  /* open upvalues are never black */
  198.   if (isgray(o)) {
  199.     if (keepinvariant(g)) {
  200.       resetoldbit(o);  /* see MOVE OLD rule */
  201.       gray2black(o);  /* it is being visited now */
  202.       markvalue(g, uv->v);
  203.     }
  204.     else {
  205.       lua_assert(issweepphase(g));
  206.       makewhite(g, o);
  207.     }
  208.   }
  209. }
  210.  
  211.  
  212. /*
  213. ** create a new collectable object (with given type and size) and link
  214. ** it to '*list'. 'offset' tells how many bytes to allocate before the
  215. ** object itself (used only by states).
  216. */
  217. GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list,
  218.                        int offset) {
  219.   global_State *g = G(L);
  220.   GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset);
  221.   if (list == NULL)
  222.     list = &g->allgc;  /* standard list for collectable objects */
  223.   gch(o)->marked = luaC_white(g);
  224.   gch(o)->tt = tt;
  225.   gch(o)->next = *list;
  226.   *list = o;
  227.   return o;
  228. }
  229.  
  230. /* }====================================================== */
  231.  
  232.  
  233.  
  234. /*
  235. ** {======================================================
  236. ** Mark functions
  237. ** =======================================================
  238. */
  239.  
  240.  
  241. /*
  242. ** mark an object. Userdata and closed upvalues are visited and turned
  243. ** black here. Strings remain gray (it is the same as making them
  244. ** black). Other objects are marked gray and added to appropriate list
  245. ** to be visited (and turned black) later. (Open upvalues are already
  246. ** linked in 'headuv' list.)
  247. */
  248. static void reallymarkobject (global_State *g, GCObject *o) {
  249.   lua_assert(iswhite(o) && !isdead(g, o));
  250.   white2gray(o);
  251.   switch (gch(o)->tt) {
  252.     case LUA_TSTRING: {
  253.       return;  /* for strings, gray is as good as black */
  254.     }
  255.     case LUA_TUSERDATA: {
  256.       Table *mt = gco2u(o)->metatable;
  257.       markobject(g, mt);
  258.       markobject(g, gco2u(o)->env);
  259.       gray2black(o);  /* all pointers marked */
  260.       return;
  261.     }
  262.     case LUA_TUPVAL: {
  263.       UpVal *uv = gco2uv(o);
  264.       markvalue(g, uv->v);
  265.       if (uv->v == &uv->u.value)  /* closed? (open upvalues remain gray) */
  266.         gray2black(o);  /* make it black */
  267.       return;
  268.     }
  269.     case LUA_TFUNCTION: {
  270.       gco2cl(o)->c.gclist = g->gray;
  271.       g->gray = o;
  272.       break;
  273.     }
  274.     case LUA_TTABLE: {
  275.       linktable(gco2t(o), &g->gray);
  276.       break;
  277.     }
  278.     case LUA_TTHREAD: {
  279.       gco2th(o)->gclist = g->gray;
  280.       g->gray = o;
  281.       break;
  282.     }
  283.     case LUA_TPROTO: {
  284.       gco2p(o)->gclist = g->gray;
  285.       g->gray = o;
  286.       break;
  287.     }
  288.     default: lua_assert(0);
  289.   }
  290. }
  291.  
  292.  
  293. /*
  294. ** mark metamethods for basic types
  295. */
  296. static void markmt (global_State *g) {
  297.   int i;
  298.   for (i=0; i < LUA_NUMTAGS; i++)
  299.     markobject(g, g->mt[i]);
  300. }
  301.  
  302.  
  303. /*
  304. ** mark all objects in list of being-finalized
  305. */
  306. static void markbeingfnz (global_State *g) {
  307.   GCObject *o;
  308.   for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
  309.     makewhite(g, o);
  310.     reallymarkobject(g, o);
  311.   }
  312. }
  313.  
  314.  
  315. /*
  316. ** mark all values stored in marked open upvalues. (See comment in
  317. ** 'lstate.h'.)
  318. */
  319. static void remarkupvals (global_State *g) {
  320.   UpVal *uv;
  321.   for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
  322.     if (isgray(obj2gco(uv)))
  323.       markvalue(g, uv->v);
  324.   }
  325. }
  326.  
  327.  
  328. /*
  329. ** mark root set and reset all gray lists, to start a new
  330. ** incremental (or full) collection
  331. */
  332. static void markroot (global_State *g) {
  333.   g->gray = g->grayagain = NULL;
  334.   g->weak = g->allweak = g->ephemeron = NULL;
  335.   markobject(g, g->mainthread);
  336.   markvalue(g, &g->l_registry);
  337.   markmt(g);
  338.   markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
  339. }
  340.  
  341. /* }====================================================== */
  342.  
  343.  
  344. /*
  345. ** {======================================================
  346. ** Traverse functions
  347. ** =======================================================
  348. */
  349.  
  350. static void traverseweakvalue (global_State *g, Table *h) {
  351.   Node *n, *limit = gnodelast(h);
  352.   /* if there is array part, assume it may have white values (do not
  353.      traverse it just to check) */
  354.   int hasclears = (h->sizearray > 0);
  355.   for (n = gnode(h, 0); n < limit; n++) {
  356.     checkdeadkey(n);
  357.     if (ttisnil(gval(n)))  /* entry is empty? */
  358.       removeentry(n);  /* remove it */
  359.     else {
  360.       lua_assert(!ttisnil(gkey(n)));
  361.       markvalue(g, gkey(n));  /* mark key */
  362.       if (!hasclears && iscleared(gval(n)))  /* is there a white value? */
  363.         hasclears = 1;  /* table will have to be cleared */
  364.     }
  365.   }
  366.   if (hasclears)
  367.     linktable(h, &g->weak);  /* has to be cleared later */
  368.   else  /* no white values */
  369.     linktable(h, &g->grayagain);  /* no need to clean */
  370. }
  371.  
  372.  
  373. static int traverseephemeron (global_State *g, Table *h) {
  374.   int marked = 0;  /* true if an object is marked in this traversal */
  375.   int hasclears = 0;  /* true if table has white keys */
  376.   int prop = 0;  /* true if table has entry "white-key -> white-value" */
  377.   Node *n, *limit = gnodelast(h);
  378.   int i;
  379.   /* traverse array part (numeric keys are 'strong') */
  380.   for (i = 0; i < h->sizearray; i++) {
  381.     if (valiswhite(&h->array[i])) {
  382.       marked = 1;
  383.       reallymarkobject(g, gcvalue(&h->array[i]));
  384.     }
  385.   }
  386.   /* traverse hash part */
  387.   for (n = gnode(h, 0); n < limit; n++) {
  388.     checkdeadkey(n);
  389.     if (ttisnil(gval(n)))  /* entry is empty? */
  390.       removeentry(n);  /* remove it */
  391.     else if (iscleared(gkey(n))) {  /* key is not marked (yet)? */
  392.       hasclears = 1;  /* table must be cleared */
  393.       if (valiswhite(gval(n)))  /* value not marked yet? */
  394.         prop = 1;  /* must propagate again */
  395.     }
  396.     else if (valiswhite(gval(n))) {  /* value not marked yet? */
  397.       marked = 1;
  398.       reallymarkobject(g, gcvalue(gval(n)));  /* mark it now */
  399.     }
  400.   }
  401.   if (prop)
  402.     linktable(h, &g->ephemeron);  /* have to propagate again */
  403.   else if (hasclears)  /* does table have white keys? */
  404.     linktable(h, &g->allweak);  /* may have to clean white keys */
  405.   else  /* no white keys */
  406.     linktable(h, &g->grayagain);  /* no need to clean */
  407.   return marked;
  408. }
  409.  
  410.  
  411. static void traversestrongtable (global_State *g, Table *h) {
  412.   Node *n, *limit = gnodelast(h);
  413.   int i;
  414.   for (i = 0; i < h->sizearray; i++)  /* traverse array part */
  415.     markvalue(g, &h->array[i]);
  416.   for (n = gnode(h, 0); n < limit; n++) {  /* traverse hash part */
  417.     checkdeadkey(n);
  418.     if (ttisnil(gval(n)))  /* entry is empty? */
  419.       removeentry(n);  /* remove it */
  420.     else {
  421.       lua_assert(!ttisnil(gkey(n)));
  422.       markvalue(g, gkey(n));  /* mark key */
  423.       markvalue(g, gval(n));  /* mark value */
  424.     }
  425.   }
  426. }
  427.  
  428.  
  429. static int traversetable (global_State *g, Table *h) {
  430.   const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
  431.   markobject(g, h->metatable);
  432.   if (mode && ttisstring(mode)) {  /* is there a weak mode? */
  433.     int weakkey = (strchr(svalue(mode), 'k') != NULL);
  434.     int weakvalue = (strchr(svalue(mode), 'v') != NULL);
  435.     if (weakkey || weakvalue) {  /* is really weak? */
  436.       black2gray(obj2gco(h));  /* keep table gray */
  437.       if (!weakkey) {  /* strong keys? */
  438.         traverseweakvalue(g, h);
  439.         return TRAVCOST + sizenode(h);
  440.       }
  441.       else if (!weakvalue) {  /* strong values? */
  442.         traverseephemeron(g, h);
  443.         return TRAVCOST + h->sizearray + sizenode(h);
  444.       }
  445.       else {
  446.         linktable(h, &g->allweak);  /* nothing to traverse now */
  447.         return TRAVCOST;
  448.       }
  449.     }  /* else go through */
  450.   }
  451.   traversestrongtable(g, h);
  452.   return TRAVCOST + h->sizearray + (2 * sizenode(h));
  453. }
  454.  
  455.  
  456. static int traverseproto (global_State *g, Proto *f) {
  457.   int i;
  458.   if (f->cache && iswhite(obj2gco(f->cache)))
  459.     f->cache = NULL;  /* allow cache to be collected */
  460.   stringmark(f->source);
  461.   for (i = 0; i < f->sizek; i++)  /* mark literals */
  462.     markvalue(g, &f->k[i]);
  463.   for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
  464.     stringmark(f->upvalues[i].name);
  465.   for (i = 0; i < f->sizep; i++)  /* mark nested protos */
  466.     markobject(g, f->p[i]);
  467.   for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
  468.     stringmark(f->locvars[i].varname);
  469.   return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars;
  470. }
  471.  
  472.  
  473. static int traverseclosure (global_State *g, Closure *cl) {
  474.   if (cl->c.isC) {
  475.     int i;
  476.     for (i=0; i<cl->c.nupvalues; i++)  /* mark its upvalues */
  477.       markvalue(g, &cl->c.upvalue[i]);
  478.   }
  479.   else {
  480.     int i;
  481.     lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
  482.     markobject(g, cl->l.p);  /* mark its prototype */
  483.     for (i=0; i<cl->l.nupvalues; i++)  /* mark its upvalues */
  484.       markobject(g, cl->l.upvals[i]);
  485.   }
  486.   return TRAVCOST + cl->c.nupvalues;
  487. }
  488.  
  489.  
  490. static int traversestack (global_State *g, lua_State *L) {
  491.   StkId o = L->stack;
  492.   if (o == NULL)
  493.     return 1;  /* stack not completely built yet */
  494.   for (; o < L->top; o++)
  495.     markvalue(g, o);
  496.   if (g->gcstate == GCSatomic) {  /* final traversal? */
  497.     StkId lim = L->stack + L->stacksize;  /* real end of stack */
  498.     for (; o < lim; o++)  /* clear not-marked stack slice */
  499.       setnilvalue(o);
  500.   }
  501.   return TRAVCOST + cast_int(o - L->stack);
  502. }
  503.  
  504.  
  505. /*
  506. ** traverse one gray object, turning it to black (except for threads,
  507. ** which are always gray).
  508. ** Returns number of values traversed.
  509. */
  510. static int propagatemark (global_State *g) {
  511.   GCObject *o = g->gray;
  512.   lua_assert(isgray(o));
  513.   gray2black(o);
  514.   switch (gch(o)->tt) {
  515.     case LUA_TTABLE: {
  516.       Table *h = gco2t(o);
  517.       g->gray = h->gclist;
  518.       return traversetable(g, h);
  519.     }
  520.     case LUA_TFUNCTION: {
  521.       Closure *cl = gco2cl(o);
  522.       g->gray = cl->c.gclist;
  523.       return traverseclosure(g, cl);
  524.     }
  525.     case LUA_TTHREAD: {
  526.       lua_State *th = gco2th(o);
  527.       g->gray = th->gclist;
  528.       th->gclist = g->grayagain;
  529.       g->grayagain = o;
  530.       black2gray(o);
  531.       return traversestack(g, th);
  532.     }
  533.     case LUA_TPROTO: {
  534.       Proto *p = gco2p(o);
  535.       g->gray = p->gclist;
  536.       return traverseproto(g, p);
  537.     }
  538.     default: lua_assert(0); return 0;
  539.   }
  540. }
  541.  
  542.  
  543. static void propagateall (global_State *g) {
  544.   while (g->gray) propagatemark(g);
  545. }
  546.  
  547.  
  548. static void propagatelist (global_State *g, GCObject *l) {
  549.   lua_assert(g->gray == NULL);  /* no grays left */
  550.   g->gray = l;
  551.   propagateall(g);  /* traverse all elements from 'l' */
  552. }
  553.  
  554. /*
  555. ** retraverse all gray lists. Because tables may be reinserted in other
  556. ** lists when traversed, traverse the original lists to avoid traversing
  557. ** twice the same table (which is not wrong, but inefficient)
  558. */
  559. static void retraversegrays (global_State *g) {
  560.   GCObject *weak = g->weak;  /* save original lists */
  561.   GCObject *grayagain = g->grayagain;
  562.   GCObject *ephemeron = g->ephemeron;
  563.   g->weak = g->grayagain = g->ephemeron = NULL;
  564.   propagateall(g);  /* traverse main gray list */
  565.   propagatelist(g, grayagain);
  566.   propagatelist(g, weak);
  567.   propagatelist(g, ephemeron);
  568. }
  569.  
  570.  
  571. static void convergeephemerons (global_State *g) {
  572.   int changed;
  573.   do {
  574.     GCObject *w;
  575.     GCObject *next = g->ephemeron;  /* get ephemeron list */
  576.     g->ephemeron = NULL;  /* tables will return to this list when traversed */
  577.     changed = 0;
  578.     while ((w = next) != NULL) {
  579.       next = gco2t(w)->gclist;
  580.       if (traverseephemeron(g, gco2t(w))) {  /* traverse marked some value? */
  581.         propagateall(g);  /* propagate changes */
  582.         changed = 1;  /* will have to revisit all ephemeron tables */
  583.       }
  584.     }
  585.   } while (changed);
  586. }
  587.  
  588. /* }====================================================== */
  589.  
  590.  
  591. /*
  592. ** {======================================================
  593. ** Sweep Functions
  594. ** =======================================================
  595. */
  596.  
  597.  
  598. /*
  599. ** clear entries with unmarked keys from all weaktables in list 'l' up
  600. ** to element 'f'
  601. */
  602. static void clearkeys (GCObject *l, GCObject *f) {
  603.   for (; l != f; l = gco2t(l)->gclist) {
  604.     Table *h = gco2t(l);
  605.     Node *n, *limit = gnodelast(h);
  606.     for (n = gnode(h, 0); n < limit; n++) {
  607.       if (!ttisnil(gval(n)) && (iscleared(gkey(n)))) {
  608.         setnilvalue(gval(n));  /* remove value ... */
  609.         removeentry(n);  /* and remove entry from table */
  610.       }
  611.     }
  612.   }
  613. }
  614.  
  615.  
  616. /*
  617. ** clear entries with unmarked values from all weaktables in list 'l' up
  618. ** to element 'f'
  619. */
  620. static void clearvalues (GCObject *l, GCObject *f) {
  621.   for (; l != f; l = gco2t(l)->gclist) {
  622.     Table *h = gco2t(l);
  623.     Node *n, *limit = gnodelast(h);
  624.     int i;
  625.     for (i = 0; i < h->sizearray; i++) {
  626.       TValue *o = &h->array[i];
  627.       if (iscleared(o))  /* value was collected? */
  628.         setnilvalue(o);  /* remove value */
  629.     }
  630.     for (n = gnode(h, 0); n < limit; n++) {
  631.       if (!ttisnil(gval(n)) && iscleared(gval(n))) {
  632.         setnilvalue(gval(n));  /* remove value ... */
  633.         removeentry(n);  /* and remove entry from table */
  634.       }
  635.     }
  636.   }
  637. }
  638.  
  639.  
  640. static void freeobj (lua_State *L, GCObject *o) {
  641.   switch (gch(o)->tt) {
  642.     case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
  643.     case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
  644.     case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
  645.     case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
  646.     case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
  647.     case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
  648.     case LUA_TSTRING: {
  649.       G(L)->strt.nuse--;
  650.       luaM_freemem(L, o, sizestring(gco2ts(o)));
  651.       break;
  652.     }
  653.     default: lua_assert(0);
  654.   }
  655. }
  656.  
  657.  
  658. #define sweepwholelist(L,p)     sweeplist(L,p,MAX_LUMEM)
  659. static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
  660.  
  661.  
  662. /*
  663. ** sweep the (open) upvalues of a thread and resize its stack and
  664. ** list of call-info structures.
  665. */
  666. static void sweepthread (lua_State *L, lua_State *L1) {
  667.   if (L1->stack == NULL) return;  /* stack not completely built yet */
  668.   sweepwholelist(L, &L1->openupval);  /* sweep open upvalues */
  669.   luaE_freeCI(L1);  /* free extra CallInfo slots */
  670.   /* should not change the stack during an emergency gc cycle */
  671.   if (G(L)->gckind != KGC_EMERGENCY)
  672.     luaD_shrinkstack(L1);
  673. }
  674.  
  675.  
  676. /*
  677. ** sweep at most 'count' elements from a list of GCObjects erasing dead
  678. ** objects, where a dead (not alive) object is one marked with the "old"
  679. ** (non current) white and not fixed.
  680. ** In non-generational mode, change all non-dead objects back to white,
  681. ** preparing for next collection cycle.
  682. ** In generational mode, keep black objects black, and also mark them as
  683. ** old; stop when hitting an old object, as all objects after that
  684. ** one will be old too.
  685. ** When object is a thread, sweep its list of open upvalues too.
  686. */
  687. static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
  688.   global_State *g = G(L);
  689.   int ow = otherwhite(g);
  690.   int toclear, toset;  /* bits to clear and to set in all live objects */
  691.   int tostop;  /* stop sweep when this is true */
  692.   l_mem debt = g->GCdebt;  /* current debt */
  693.   if (isgenerational(g)) {  /* generational mode? */
  694.     toclear = ~0;  /* clear nothing */
  695.     toset = bitmask(OLDBIT);  /* set the old bit of all surviving objects */
  696.     tostop = bitmask(OLDBIT);  /* do not sweep old generation */
  697.   }
  698.   else {  /* normal mode */
  699.     toclear = maskcolors;  /* clear all color bits + old bit */
  700.     toset = luaC_white(g);  /* make object white */
  701.     tostop = 0;  /* do not stop */
  702.   }
  703.   while (*p != NULL && count-- > 0) {
  704.     GCObject *curr = *p;
  705.     int marked = gch(curr)->marked;
  706.     if (isdeadm(ow, marked)) {  /* is 'curr' dead? */
  707.       *p = gch(curr)->next;  /* remove 'curr' from list */
  708.       freeobj(L, curr);  /* erase 'curr' */
  709.     }
  710.     else {
  711.       if (gch(curr)->tt == LUA_TTHREAD)
  712.         sweepthread(L, gco2th(curr));  /* sweep thread's upvalues */
  713.       if (testbits(marked, tostop)) {
  714.         static GCObject *nullp = NULL;
  715.         p = &nullp;  /* stop sweeping this list */
  716.         break;
  717.       }
  718.       /* update marks */
  719.       gch(curr)->marked = cast_byte((marked & toclear) | toset);
  720.       p = &gch(curr)->next;  /* go to next element */
  721.     }
  722.   }
  723.   luaE_setdebt(g, debt);  /* sweeping should not change debt */
  724.   return p;
  725. }
  726.  
  727. /* }====================================================== */
  728.  
  729.  
  730. /*
  731. ** {======================================================
  732. ** Finalization
  733. ** =======================================================
  734. */
  735.  
  736. static void checkSizes (lua_State *L) {
  737.   global_State *g = G(L);
  738.   if (g->gckind != KGC_EMERGENCY) {  /* do not change sizes in emergency */
  739.     int hs = g->strt.size / 2;  /* half the size of the string table */
  740.     if (g->strt.nuse < cast(lu_int32, hs))  /* using less than that half? */
  741.       luaS_resize(L, hs);  /* halve its size */
  742.     luaZ_freebuffer(L, &g->buff);  /* free concatenation buffer */
  743.   }
  744. }
  745.  
  746.  
  747. static GCObject *udata2finalize (global_State *g) {
  748.   GCObject *o = g->tobefnz;  /* get first element */
  749.   lua_assert(isfinalized(o));
  750.   g->tobefnz = gch(o)->next;  /* remove it from 'tobefnz' list */
  751.   gch(o)->next = g->allgc;  /* return it to 'allgc' list */
  752.   g->allgc = o;
  753.   resetbit(gch(o)->marked, SEPARATED);  /* mark that it is not in 'tobefnz' */
  754.   lua_assert(!isold(o));  /* see MOVE OLD rule */
  755.   if (!keepinvariant(g))  /* not keeping invariant? */
  756.     makewhite(g, o);  /* "sweep" object */
  757.   return o;
  758. }
  759.  
  760.  
  761. static void dothecall (lua_State *L, void *ud) {
  762.   UNUSED(ud);
  763.   luaD_call(L, L->top - 2, 0, 0);
  764. }
  765.  
  766.  
  767. static void GCTM (lua_State *L, int propagateerrors) {
  768.   global_State *g = G(L);
  769.   const TValue *tm;
  770.   TValue v;
  771.   setgcovalue(L, &v, udata2finalize(g));
  772.   tm = luaT_gettmbyobj(L, &v, TM_GC);
  773.   if (tm != NULL && ttisfunction(tm)) {  /* is there a finalizer? */
  774.     int status;
  775.     lu_byte oldah = L->allowhook;
  776.     int running  = g->gcrunning;
  777.     L->allowhook = 0;  /* stop debug hooks during GC metamethod */
  778.     g->gcrunning = 0;  /* avoid GC steps */
  779.     setobj2s(L, L->top, tm);  /* push finalizer... */
  780.     setobj2s(L, L->top + 1, &v);  /* ... and its argument */
  781.     L->top += 2;  /* and (next line) call the finalizer */
  782.     status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
  783.     L->allowhook = oldah;  /* restore hooks */
  784.     g->gcrunning = running;  /* restore state */
  785.     if (status != LUA_OK && propagateerrors) {  /* error while running __gc? */
  786.       if (status == LUA_ERRRUN) {  /* is there an error msg.? */
  787.         luaO_pushfstring(L, "error in __gc metamethod (%s)",
  788.                                         lua_tostring(L, -1));
  789.         status = LUA_ERRGCMM;  /* error in __gc metamethod */
  790.       }
  791.       luaD_throw(L, status);  /* re-send error */
  792.     }
  793.   }
  794. }
  795.  
  796.  
  797. /*
  798. ** move all unreachable objects (or 'all' objects) that need
  799. ** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
  800. */
  801. static void separatetobefnz (lua_State *L, int all) {
  802.   global_State *g = G(L);
  803.   GCObject **p = &g->finobj;
  804.   GCObject *curr;
  805.   GCObject **lastnext = &g->tobefnz;
  806.   /* find last 'next' field in 'tobefnz' list (to add elements in its end) */
  807.   while (*lastnext != NULL)
  808.     lastnext = &gch(*lastnext)->next;
  809.   while ((curr = *p) != NULL) {  /* traverse all finalizable objects */
  810.     lua_assert(!isfinalized(curr));
  811.     lua_assert(testbit(gch(curr)->marked, SEPARATED));
  812.     if (!(all || iswhite(curr)))  /* not being collected? */
  813.       p = &gch(curr)->next;  /* don't bother with it */
  814.     else {
  815.       l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
  816.       *p = gch(curr)->next;  /* remove 'curr' from 'finobj' list */
  817.       gch(curr)->next = *lastnext;  /* link at the end of 'tobefnz' list */
  818.       *lastnext = curr;
  819.       lastnext = &gch(curr)->next;
  820.     }
  821.   }
  822. }
  823.  
  824.  
  825. /*
  826. ** if object 'o' has a finalizer, remove it from 'allgc' list (must
  827. ** search the list to find it) and link it in 'finobj' list.
  828. */
  829. void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
  830.   global_State *g = G(L);
  831.   if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */
  832.       isfinalized(o) ||                           /* ... or is finalized... */
  833.       gfasttm(g, mt, TM_GC) == NULL)                /* or has no finalizer? */
  834.     return;  /* nothing to be done */
  835.   else {  /* move 'o' to 'finobj' list */
  836.     GCObject **p;
  837.     for (p = &g->allgc; *p != o; p = &gch(*p)->next) ;
  838.     *p = gch(o)->next;  /* remove 'o' from root list */
  839.     gch(o)->next = g->finobj;  /* link it in list 'finobj' */
  840.     g->finobj = o;
  841.     l_setbit(gch(o)->marked, SEPARATED);  /* mark it as such */
  842.     resetoldbit(o);  /* see MOVE OLD rule */
  843.   }
  844. }
  845.  
  846. /* }====================================================== */
  847.  
  848.  
  849. /*
  850. ** {======================================================
  851. ** GC control
  852. ** =======================================================
  853. */
  854.  
  855.  
  856. #define sweepphases  \
  857.         (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
  858.  
  859. /*
  860. ** change GC mode
  861. */
  862. void luaC_changemode (lua_State *L, int mode) {
  863.   global_State *g = G(L);
  864.   if (mode == g->gckind) return;  /* nothing to change */
  865.   if (mode == KGC_GEN) {  /* change to generational mode */
  866.     /* make sure gray lists are consistent */
  867.     luaC_runtilstate(L, bitmask(GCSpropagate));
  868.     g->lastmajormem = gettotalbytes(g);
  869.     g->gckind = KGC_GEN;
  870.   }
  871.   else {  /* change to incremental mode */
  872.     /* sweep all objects to turn them back to white
  873.        (as white has not changed, nothing extra will be collected) */
  874.     g->sweepstrgc = 0;
  875.     g->gcstate = GCSsweepstring;
  876.     g->gckind = KGC_NORMAL;
  877.     luaC_runtilstate(L, ~sweepphases);
  878.   }
  879. }
  880.  
  881.  
  882. /*
  883. ** call all pending finalizers
  884. */
  885. static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
  886.   global_State *g = G(L);
  887.   while (g->tobefnz) {
  888.     resetoldbit(g->tobefnz);
  889.     GCTM(L, propagateerrors);
  890.   }
  891. }
  892.  
  893.  
  894. void luaC_freeallobjects (lua_State *L) {
  895.   global_State *g = G(L);
  896.   int i;
  897.   separatetobefnz(L, 1);  /* separate all objects with finalizers */
  898.   lua_assert(g->finobj == NULL);
  899.   callallpendingfinalizers(L, 0);
  900.   g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
  901.   g->gckind = KGC_NORMAL;
  902.   sweepwholelist(L, &g->finobj);  /* finalizers can create objs. in 'finobj' */
  903.   sweepwholelist(L, &g->allgc);
  904.   for (i = 0; i < g->strt.size; i++)  /* free all string lists */
  905.     sweepwholelist(L, &g->strt.hash[i]);
  906.   lua_assert(g->strt.nuse == 0);
  907. }
  908.  
  909.  
  910. static void atomic (lua_State *L) {
  911.   global_State *g = G(L);
  912.   GCObject *origweak, *origall;
  913.   lua_assert(!iswhite(obj2gco(g->mainthread)));
  914.   markobject(g, L);  /* mark running thread */
  915.   /* registry and global metatables may be changed by API */
  916.   markvalue(g, &g->l_registry);
  917.   markmt(g);  /* mark basic metatables */
  918.   /* remark occasional upvalues of (maybe) dead threads */
  919.   remarkupvals(g);
  920.   /* traverse objects caught by write barrier and by 'remarkupvals' */
  921.   retraversegrays(g);
  922.   convergeephemerons(g);
  923.   /* at this point, all strongly accessible objects are marked. */
  924.   /* clear values from weak tables, before checking finalizers */
  925.   clearvalues(g->weak, NULL);
  926.   clearvalues(g->allweak, NULL);
  927.   origweak = g->weak; origall = g->allweak;
  928.   separatetobefnz(L, 0);  /* separate objects to be finalized */
  929.   markbeingfnz(g);  /* mark userdata that will be finalized */
  930.   propagateall(g);  /* remark, to propagate `preserveness' */
  931.   convergeephemerons(g);
  932.   /* at this point, all resurrected objects are marked. */
  933.   /* remove dead objects from weak tables */
  934.   clearkeys(g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
  935.   clearkeys(g->allweak, NULL);  /* clear keys from all allweak tables */
  936.   /* clear values from resurrected weak tables */
  937.   clearvalues(g->weak, origweak);
  938.   clearvalues(g->allweak, origall);
  939.   g->sweepstrgc = 0;  /* prepare to sweep strings */
  940.   g->gcstate = GCSsweepstring;
  941.   g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
  942.   /*lua_checkmemory(L);*/
  943. }
  944.  
  945.  
  946. static l_mem singlestep (lua_State *L) {
  947.   global_State *g = G(L);
  948.   switch (g->gcstate) {
  949.     case GCSpause: {
  950.       if (!isgenerational(g))
  951.         markroot(g);  /* start a new collection */
  952.       /* in any case, root must be marked */
  953.       lua_assert(!iswhite(obj2gco(g->mainthread))
  954.               && !iswhite(gcvalue(&g->l_registry)));
  955.       g->gcstate = GCSpropagate;
  956.       return GCROOTCOST;
  957.     }
  958.     case GCSpropagate: {
  959.       if (g->gray)
  960.         return propagatemark(g);
  961.       else {  /* no more `gray' objects */
  962.         g->gcstate = GCSatomic;  /* finish mark phase */
  963.         atomic(L);
  964.         return GCATOMICCOST;
  965.       }
  966.     }
  967.     case GCSsweepstring: {
  968.       if (g->sweepstrgc < g->strt.size) {
  969.         sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
  970.         return GCSWEEPCOST;
  971.       }
  972.       else {  /* no more strings to sweep */
  973.         g->sweepgc = &g->finobj;  /* prepare to sweep finalizable objects */
  974.         g->gcstate = GCSsweepudata;
  975.         return 0;
  976.       }
  977.     }
  978.     case GCSsweepudata: {
  979.       if (*g->sweepgc) {
  980.         g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
  981.         return GCSWEEPMAX*GCSWEEPCOST;
  982.       }
  983.       else {
  984.         g->sweepgc = &g->allgc;  /* go to next phase */
  985.         g->gcstate = GCSsweep;
  986.         return GCSWEEPCOST;
  987.       }
  988.     }
  989.     case GCSsweep: {
  990.       if (*g->sweepgc) {
  991.         g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
  992.         return GCSWEEPMAX*GCSWEEPCOST;
  993.       }
  994.       else {
  995.         /* sweep main thread */
  996.         GCObject *mt = obj2gco(g->mainthread);
  997.         sweeplist(L, &mt, 1);
  998.         checkSizes(L);
  999.         g->gcstate = GCSpause;  /* finish collection */
  1000.         return GCSWEEPCOST;
  1001.       }
  1002.     }
  1003.     default: lua_assert(0); return 0;
  1004.   }
  1005. }
  1006.  
  1007.  
  1008. /*
  1009. ** advances the garbage collector until it reaches a state allowed
  1010. ** by 'statemask'
  1011. */
  1012. void luaC_runtilstate (lua_State *L, int statesmask) {
  1013.   global_State *g = G(L);
  1014.   while (!testbit(statesmask, g->gcstate))
  1015.     singlestep(L);
  1016. }
  1017.  
  1018.  
  1019. static void generationalcollection (lua_State *L) {
  1020.   global_State *g = G(L);
  1021.   if (g->lastmajormem == 0) {  /* signal for another major collection? */
  1022.     luaC_fullgc(L, 0);  /* perform a full regular collection */
  1023.     g->lastmajormem = gettotalbytes(g);  /* update control */
  1024.   }
  1025.   else {
  1026.     luaC_runtilstate(L, ~bitmask(GCSpause));  /* run complete cycle */
  1027.     luaC_runtilstate(L, bitmask(GCSpause));
  1028.     if (gettotalbytes(g) > g->lastmajormem/100 * g->gcmajorinc)
  1029.       g->lastmajormem = 0;  /* signal for a major collection */
  1030.   }
  1031.   luaE_setdebt(g, stddebt(g));
  1032. }
  1033.  
  1034.  
  1035. static void step (lua_State *L) {
  1036.   global_State *g = G(L);
  1037.   l_mem lim = g->gcstepmul;  /* how much to work */
  1038.   do {  /* always perform at least one single step */
  1039.     lim -= singlestep(L);
  1040.   } while (lim > 0 && g->gcstate != GCSpause);
  1041.   if (g->gcstate != GCSpause)
  1042.     luaE_setdebt(g, g->GCdebt - GCSTEPSIZE);
  1043.   else
  1044.     luaE_setdebt(g, stddebt(g));
  1045. }
  1046.  
  1047.  
  1048. /*
  1049. ** performs a basic GC step even if the collector is stopped
  1050. */
  1051. void luaC_forcestep (lua_State *L) {
  1052.   global_State *g = G(L);
  1053.   int i;
  1054.   if (isgenerational(g)) generationalcollection(L);
  1055.   else step(L);
  1056.   for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++)
  1057.     GCTM(L, 1);  /* Call a few pending finalizers */
  1058. }
  1059.  
  1060.  
  1061. /*
  1062. ** performs a basic GC step only if collector is running
  1063. */
  1064. void luaC_step (lua_State *L) {
  1065.   if (G(L)->gcrunning) luaC_forcestep(L);
  1066. }
  1067.  
  1068.  
  1069. /*
  1070. ** performs a full GC cycle; if "isemergency", does not call
  1071. ** finalizers (which could change stack positions)
  1072. */
  1073. void luaC_fullgc (lua_State *L, int isemergency) {
  1074.   global_State *g = G(L);
  1075.   int origkind = g->gckind;
  1076.   lua_assert(origkind != KGC_EMERGENCY);
  1077.   if (!isemergency)   /* do not run finalizers during emergency GC */
  1078.     callallpendingfinalizers(L, 1);
  1079.   if (keepinvariant(g)) {  /* marking phase? */
  1080.     /* must sweep all objects to turn them back to white
  1081.        (as white has not changed, nothing will be collected) */
  1082.     g->sweepstrgc = 0;
  1083.     g->gcstate = GCSsweepstring;
  1084.   }
  1085.   g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL;
  1086.   /* finish any pending sweep phase to start a new cycle */
  1087.   luaC_runtilstate(L, bitmask(GCSpause));
  1088.   /* run entire collector */
  1089.   luaC_runtilstate(L, ~bitmask(GCSpause));
  1090.   luaC_runtilstate(L, bitmask(GCSpause));
  1091.   if (origkind == KGC_GEN) {  /* generational mode? */
  1092.     /* generational mode must always start in propagate phase */
  1093.     luaC_runtilstate(L, bitmask(GCSpropagate));
  1094.   }
  1095.   g->gckind = origkind;
  1096.   luaE_setdebt(g, stddebt(g));
  1097.   if (!isemergency)   /* do not run finalizers during emergency GC */
  1098.     callallpendingfinalizers(L, 1);
  1099. }
  1100.  
  1101. /* }====================================================== */
  1102.  
  1103.  
  1104.