lj_gc.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /*
  2. ** Garbage collector.
  3. ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
  4. **
  5. ** Major portions taken verbatim or adapted from the Lua interpreter.
  6. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
  7. */
  8. #define lj_gc_c
  9. #define LUA_CORE
  10. #include "lj_obj.h"
  11. #include "lj_gc.h"
  12. #include "lj_err.h"
  13. #include "lj_str.h"
  14. #include "lj_tab.h"
  15. #include "lj_func.h"
  16. #include "lj_udata.h"
  17. #include "lj_meta.h"
  18. #include "lj_state.h"
  19. #include "lj_frame.h"
  20. #if LJ_HASFFI
  21. #include "lj_ctype.h"
  22. #include "lj_cdata.h"
  23. #endif
  24. #include "lj_trace.h"
  25. #include "lj_vm.h"
  26. #define GCSTEPSIZE 1024u
  27. #define GCSWEEPMAX 40
  28. #define GCSWEEPCOST 10
  29. #define GCFINALIZECOST 100
  30. /* Macros to set GCobj colors and flags. */
  31. #define white2gray(x) ((x)->gch.marked &= (uint8_t)~LJ_GC_WHITES)
  32. #define gray2black(x) ((x)->gch.marked |= LJ_GC_BLACK)
  33. #define isfinalized(u) ((u)->marked & LJ_GC_FINALIZED)
  34. /* -- Mark phase ---------------------------------------------------------- */
  35. /* Mark a TValue (if needed). */
  36. #define gc_marktv(g, tv) \
  37. { lua_assert(!tvisgcv(tv) || (~itype(tv) == gcval(tv)->gch.gct)); \
  38. if (tviswhite(tv)) gc_mark(g, gcV(tv)); }
  39. /* Mark a GCobj (if needed). */
  40. #define gc_markobj(g, o) \
  41. { if (iswhite(obj2gco(o))) gc_mark(g, obj2gco(o)); }
  42. /* Mark a string object. */
  43. #define gc_mark_str(s) ((s)->marked &= (uint8_t)~LJ_GC_WHITES)
  44. /* Mark a white GCobj. */
  45. static void gc_mark(global_State *g, GCobj *o)
  46. {
  47. int gct = o->gch.gct;
  48. lua_assert(iswhite(o) && !isdead(g, o));
  49. white2gray(o);
  50. if (LJ_UNLIKELY(gct == ~LJ_TUDATA)) {
  51. GCtab *mt = tabref(gco2ud(o)->metatable);
  52. gray2black(o); /* Userdata are never gray. */
  53. if (mt) gc_markobj(g, mt);
  54. gc_markobj(g, tabref(gco2ud(o)->env));
  55. } else if (LJ_UNLIKELY(gct == ~LJ_TUPVAL)) {
  56. GCupval *uv = gco2uv(o);
  57. gc_marktv(g, uvval(uv));
  58. if (uv->closed)
  59. gray2black(o); /* Closed upvalues are never gray. */
  60. } else if (gct != ~LJ_TSTR && gct != ~LJ_TCDATA) {
  61. lua_assert(gct == ~LJ_TFUNC || gct == ~LJ_TTAB ||
  62. gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO);
  63. setgcrefr(o->gch.gclist, g->gc.gray);
  64. setgcref(g->gc.gray, o);
  65. }
  66. }
  67. /* Mark GC roots. */
  68. static void gc_mark_gcroot(global_State *g)
  69. {
  70. ptrdiff_t i;
  71. for (i = 0; i < GCROOT_MAX; i++)
  72. if (gcref(g->gcroot[i]) != NULL)
  73. gc_markobj(g, gcref(g->gcroot[i]));
  74. }
  75. /* Start a GC cycle and mark the root set. */
  76. static void gc_mark_start(global_State *g)
  77. {
  78. setgcrefnull(g->gc.gray);
  79. setgcrefnull(g->gc.grayagain);
  80. setgcrefnull(g->gc.weak);
  81. gc_markobj(g, mainthread(g));
  82. gc_markobj(g, tabref(mainthread(g)->env));
  83. gc_marktv(g, &g->registrytv);
  84. gc_mark_gcroot(g);
  85. g->gc.state = GCSpropagate;
  86. }
  87. /* Mark open upvalues. */
  88. static void gc_mark_uv(global_State *g)
  89. {
  90. GCupval *uv;
  91. for (uv = uvnext(&g->uvhead); uv != &g->uvhead; uv = uvnext(uv)) {
  92. lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv);
  93. if (isgray(obj2gco(uv)))
  94. gc_marktv(g, uvval(uv));
  95. }
  96. }
  97. /* Mark userdata in mmudata list. */
  98. static void gc_mark_mmudata(global_State *g)
  99. {
  100. GCobj *root = gcref(g->gc.mmudata);
  101. GCobj *u = root;
  102. if (u) {
  103. do {
  104. u = gcnext(u);
  105. makewhite(g, u); /* Could be from previous GC. */
  106. gc_mark(g, u);
  107. } while (u != root);
  108. }
  109. }
  110. /* Separate userdata objects to be finalized to mmudata list. */
  111. size_t lj_gc_separateudata(global_State *g, int all)
  112. {
  113. size_t m = 0;
  114. GCRef *p = &mainthread(g)->nextgc;
  115. GCobj *o;
  116. while ((o = gcref(*p)) != NULL) {
  117. if (!(iswhite(o) || all) || isfinalized(gco2ud(o))) {
  118. p = &o->gch.nextgc; /* Nothing to do. */
  119. } else if (!lj_meta_fastg(g, tabref(gco2ud(o)->metatable), MM_gc)) {
  120. markfinalized(o); /* Done, as there's no __gc metamethod. */
  121. p = &o->gch.nextgc;
  122. } else { /* Otherwise move userdata to be finalized to mmudata list. */
  123. m += sizeudata(gco2ud(o));
  124. markfinalized(o);
  125. *p = o->gch.nextgc;
  126. if (gcref(g->gc.mmudata)) { /* Link to end of mmudata list. */
  127. GCobj *root = gcref(g->gc.mmudata);
  128. setgcrefr(o->gch.nextgc, root->gch.nextgc);
  129. setgcref(root->gch.nextgc, o);
  130. setgcref(g->gc.mmudata, o);
  131. } else { /* Create circular list. */
  132. setgcref(o->gch.nextgc, o);
  133. setgcref(g->gc.mmudata, o);
  134. }
  135. }
  136. }
  137. return m;
  138. }
  139. /* -- Propagation phase --------------------------------------------------- */
  140. /* Traverse a table. */
  141. static int gc_traverse_tab(global_State *g, GCtab *t)
  142. {
  143. int weak = 0;
  144. cTValue *mode;
  145. GCtab *mt = tabref(t->metatable);
  146. if (mt)
  147. gc_markobj(g, mt);
  148. mode = lj_meta_fastg(g, mt, MM_mode);
  149. if (mode && tvisstr(mode)) { /* Valid __mode field? */
  150. const char *modestr = strVdata(mode);
  151. int c;
  152. while ((c = *modestr++)) {
  153. if (c == 'k') weak |= LJ_GC_WEAKKEY;
  154. else if (c == 'v') weak |= LJ_GC_WEAKVAL;
  155. else if (c == 'K') weak = (int)(~0u & ~LJ_GC_WEAKVAL);
  156. }
  157. if (weak > 0) { /* Weak tables are cleared in the atomic phase. */
  158. t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak);
  159. setgcrefr(t->gclist, g->gc.weak);
  160. setgcref(g->gc.weak, obj2gco(t));
  161. }
  162. }
  163. if (weak == LJ_GC_WEAK) /* Nothing to mark if both keys/values are weak. */
  164. return 1;
  165. if (!(weak & LJ_GC_WEAKVAL)) { /* Mark array part. */
  166. MSize i, asize = t->asize;
  167. for (i = 0; i < asize; i++)
  168. gc_marktv(g, arrayslot(t, i));
  169. }
  170. if (t->hmask > 0) { /* Mark hash part. */
  171. Node *node = noderef(t->node);
  172. MSize i, hmask = t->hmask;
  173. for (i = 0; i <= hmask; i++) {
  174. Node *n = &node[i];
  175. if (!tvisnil(&n->val)) { /* Mark non-empty slot. */
  176. lua_assert(!tvisnil(&n->key));
  177. if (!(weak & LJ_GC_WEAKKEY)) gc_marktv(g, &n->key);
  178. if (!(weak & LJ_GC_WEAKVAL)) gc_marktv(g, &n->val);
  179. }
  180. }
  181. }
  182. return weak;
  183. }
  184. /* Traverse a function. */
  185. static void gc_traverse_func(global_State *g, GCfunc *fn)
  186. {
  187. gc_markobj(g, tabref(fn->c.env));
  188. if (isluafunc(fn)) {
  189. uint32_t i;
  190. lua_assert(fn->l.nupvalues <= funcproto(fn)->sizeuv);
  191. gc_markobj(g, funcproto(fn));
  192. for (i = 0; i < fn->l.nupvalues; i++) /* Mark Lua function upvalues. */
  193. gc_markobj(g, &gcref(fn->l.uvptr[i])->uv);
  194. } else {
  195. uint32_t i;
  196. for (i = 0; i < fn->c.nupvalues; i++) /* Mark C function upvalues. */
  197. gc_marktv(g, &fn->c.upvalue[i]);
  198. }
  199. }
  200. #if LJ_HASJIT
  201. /* Mark a trace. */
  202. static void gc_marktrace(global_State *g, TraceNo traceno)
  203. {
  204. GCobj *o = obj2gco(traceref(G2J(g), traceno));
  205. lua_assert(traceno != G2J(g)->cur.traceno);
  206. if (iswhite(o)) {
  207. white2gray(o);
  208. setgcrefr(o->gch.gclist, g->gc.gray);
  209. setgcref(g->gc.gray, o);
  210. }
  211. }
  212. /* Traverse a trace. */
  213. static void gc_traverse_trace(global_State *g, GCtrace *T)
  214. {
  215. IRRef ref;
  216. if (T->traceno == 0) return;
  217. for (ref = T->nk; ref < REF_TRUE; ref++) {
  218. IRIns *ir = &T->ir[ref];
  219. if (ir->o == IR_KGC)
  220. gc_markobj(g, ir_kgc(ir));
  221. }
  222. if (T->link) gc_marktrace(g, T->link);
  223. if (T->nextroot) gc_marktrace(g, T->nextroot);
  224. if (T->nextside) gc_marktrace(g, T->nextside);
  225. gc_markobj(g, gcref(T->startpt));
  226. }
  227. /* The current trace is a GC root while not anchored in the prototype (yet). */
  228. #define gc_traverse_curtrace(g) gc_traverse_trace(g, &G2J(g)->cur)
  229. #else
  230. #define gc_traverse_curtrace(g) UNUSED(g)
  231. #endif
  232. /* Traverse a prototype. */
  233. static void gc_traverse_proto(global_State *g, GCproto *pt)
  234. {
  235. ptrdiff_t i;
  236. gc_mark_str(proto_chunkname(pt));
  237. for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */
  238. gc_markobj(g, proto_kgc(pt, i));
  239. #if LJ_HASJIT
  240. if (pt->trace) gc_marktrace(g, pt->trace);
  241. #endif
  242. }
  243. /* Traverse the frame structure of a stack. */
  244. static MSize gc_traverse_frames(global_State *g, lua_State *th)
  245. {
  246. TValue *frame, *top = th->top-1, *bot = tvref(th->stack);
  247. /* Note: extra vararg frame not skipped, marks function twice (harmless). */
  248. for (frame = th->base-1; frame > bot; frame = frame_prev(frame)) {
  249. GCfunc *fn = frame_func(frame);
  250. TValue *ftop = frame;
  251. if (isluafunc(fn)) ftop += funcproto(fn)->framesize;
  252. if (ftop > top) top = ftop;
  253. gc_markobj(g, fn); /* Need to mark hidden function (or L). */
  254. }
  255. top++; /* Correct bias of -1 (frame == base-1). */
  256. if (top > tvref(th->maxstack)) top = tvref(th->maxstack);
  257. return (MSize)(top - bot); /* Return minimum needed stack size. */
  258. }
  259. /* Traverse a thread object. */
  260. static void gc_traverse_thread(global_State *g, lua_State *th)
  261. {
  262. TValue *o, *top = th->top;
  263. for (o = tvref(th->stack)+1; o < top; o++)
  264. gc_marktv(g, o);
  265. if (g->gc.state == GCSatomic) {
  266. top = tvref(th->stack) + th->stacksize;
  267. for (; o < top; o++) /* Clear unmarked slots. */
  268. setnilV(o);
  269. }
  270. gc_markobj(g, tabref(th->env));
  271. lj_state_shrinkstack(th, gc_traverse_frames(g, th));
  272. }
  273. /* Propagate one gray object. Traverse it and turn it black. */
  274. static size_t propagatemark(global_State *g)
  275. {
  276. GCobj *o = gcref(g->gc.gray);
  277. int gct = o->gch.gct;
  278. lua_assert(isgray(o));
  279. gray2black(o);
  280. setgcrefr(g->gc.gray, o->gch.gclist); /* Remove from gray list. */
  281. if (LJ_LIKELY(gct == ~LJ_TTAB)) {
  282. GCtab *t = gco2tab(o);
  283. if (gc_traverse_tab(g, t) > 0)
  284. black2gray(o); /* Keep weak tables gray. */
  285. return sizeof(GCtab) + sizeof(TValue) * t->asize +
  286. sizeof(Node) * (t->hmask + 1);
  287. } else if (LJ_LIKELY(gct == ~LJ_TFUNC)) {
  288. GCfunc *fn = gco2func(o);
  289. gc_traverse_func(g, fn);
  290. return isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
  291. sizeCfunc((MSize)fn->c.nupvalues);
  292. } else if (LJ_LIKELY(gct == ~LJ_TPROTO)) {
  293. GCproto *pt = gco2pt(o);
  294. gc_traverse_proto(g, pt);
  295. return pt->sizept;
  296. } else if (LJ_LIKELY(gct == ~LJ_TTHREAD)) {
  297. lua_State *th = gco2th(o);
  298. setgcrefr(th->gclist, g->gc.grayagain);
  299. setgcref(g->gc.grayagain, o);
  300. black2gray(o); /* Threads are never black. */
  301. gc_traverse_thread(g, th);
  302. return sizeof(lua_State) + sizeof(TValue) * th->stacksize;
  303. } else {
  304. #if LJ_HASJIT
  305. GCtrace *T = gco2trace(o);
  306. gc_traverse_trace(g, T);
  307. return ((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
  308. T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry);
  309. #else
  310. lua_assert(0);
  311. return 0;
  312. #endif
  313. }
  314. }
  315. /* Propagate all gray objects. */
  316. static size_t gc_propagate_gray(global_State *g)
  317. {
  318. size_t m = 0;
  319. while (gcref(g->gc.gray) != NULL)
  320. m += propagatemark(g);
  321. return m;
  322. }
  323. /* -- Sweep phase --------------------------------------------------------- */
  324. /* Try to shrink some common data structures. */
  325. static void gc_shrink(global_State *g, lua_State *L)
  326. {
  327. if (g->strnum <= (g->strmask >> 2) && g->strmask > LJ_MIN_STRTAB*2-1)
  328. lj_str_resize(L, g->strmask >> 1); /* Shrink string table. */
  329. if (g->tmpbuf.sz > LJ_MIN_SBUF*2)
  330. lj_str_resizebuf(L, &g->tmpbuf, g->tmpbuf.sz >> 1); /* Shrink temp buf. */
  331. }
  332. /* Type of GC free functions. */
  333. typedef void (LJ_FASTCALL *GCFreeFunc)(global_State *g, GCobj *o);
  334. /* GC free functions for LJ_TSTR .. LJ_TUDATA. ORDER LJ_T */
  335. static const GCFreeFunc gc_freefunc[] = {
  336. (GCFreeFunc)lj_str_free,
  337. (GCFreeFunc)lj_func_freeuv,
  338. (GCFreeFunc)lj_state_free,
  339. (GCFreeFunc)lj_func_freeproto,
  340. (GCFreeFunc)lj_func_free,
  341. #if LJ_HASJIT
  342. (GCFreeFunc)lj_trace_free,
  343. #else
  344. (GCFreeFunc)0,
  345. #endif
  346. #if LJ_HASFFI
  347. (GCFreeFunc)lj_cdata_free,
  348. #else
  349. (GCFreeFunc)0,
  350. #endif
  351. (GCFreeFunc)lj_tab_free,
  352. (GCFreeFunc)lj_udata_free
  353. };
  354. /* Full sweep of a GC list. */
  355. #define gc_fullsweep(g, p) gc_sweep(g, (p), LJ_MAX_MEM)
  356. /* Partial sweep of a GC list. */
  357. static GCRef *gc_sweep(global_State *g, GCRef *p, uint32_t lim)
  358. {
  359. /* Mask with other white and LJ_GC_FIXED. Or LJ_GC_SFIXED on shutdown. */
  360. int ow = otherwhite(g);
  361. GCobj *o;
  362. while ((o = gcref(*p)) != NULL && lim-- > 0) {
  363. if (o->gch.gct == ~LJ_TTHREAD) /* Need to sweep open upvalues, too. */
  364. gc_fullsweep(g, &gco2th(o)->openupval);
  365. if (((o->gch.marked ^ LJ_GC_WHITES) & ow)) { /* Black or current white? */
  366. lua_assert(!isdead(g, o) || (o->gch.marked & LJ_GC_FIXED));
  367. makewhite(g, o); /* Value is alive, change to the current white. */
  368. p = &o->gch.nextgc;
  369. } else { /* Otherwise value is dead, free it. */
  370. lua_assert(isdead(g, o) || ow == LJ_GC_SFIXED);
  371. setgcrefr(*p, o->gch.nextgc);
  372. if (o == gcref(g->gc.root))
  373. setgcrefr(g->gc.root, o->gch.nextgc); /* Adjust list anchor. */
  374. gc_freefunc[o->gch.gct - ~LJ_TSTR](g, o);
  375. }
  376. }
  377. return p;
  378. }
  379. /* Check whether we can clear a key or a value slot from a table. */
  380. static int gc_mayclear(cTValue *o, int val)
  381. {
  382. if (tvisgcv(o)) { /* Only collectable objects can be weak references. */
  383. if (tvisstr(o)) { /* But strings cannot be used as weak references. */
  384. gc_mark_str(strV(o)); /* And need to be marked. */
  385. return 0;
  386. }
  387. if (iswhite(gcV(o)))
  388. return 1; /* Object is about to be collected. */
  389. if (tvisudata(o) && val && isfinalized(udataV(o)))
  390. return 1; /* Finalized userdata is dropped only from values. */
  391. }
  392. return 0; /* Cannot clear. */
  393. }
  394. /* Clear collected entries from weak tables. */
  395. static void gc_clearweak(GCobj *o)
  396. {
  397. while (o) {
  398. GCtab *t = gco2tab(o);
  399. lua_assert((t->marked & LJ_GC_WEAK));
  400. if ((t->marked & LJ_GC_WEAKVAL)) {
  401. MSize i, asize = t->asize;
  402. for (i = 0; i < asize; i++) {
  403. /* Clear array slot when value is about to be collected. */
  404. TValue *tv = arrayslot(t, i);
  405. if (gc_mayclear(tv, 1))
  406. setnilV(tv);
  407. }
  408. }
  409. if (t->hmask > 0) {
  410. Node *node = noderef(t->node);
  411. MSize i, hmask = t->hmask;
  412. for (i = 0; i <= hmask; i++) {
  413. Node *n = &node[i];
  414. /* Clear hash slot when key or value is about to be collected. */
  415. if (!tvisnil(&n->val) && (gc_mayclear(&n->key, 0) ||
  416. gc_mayclear(&n->val, 1)))
  417. setnilV(&n->val);
  418. }
  419. }
  420. o = gcref(t->gclist);
  421. }
  422. }
  423. /* Call a userdata or cdata finalizer. */
  424. static void gc_call_finalizer(global_State *g, lua_State *L,
  425. cTValue *mo, GCobj *o)
  426. {
  427. /* Save and restore lots of state around the __gc callback. */
  428. uint8_t oldh = hook_save(g);
  429. MSize oldt = g->gc.threshold;
  430. int errcode;
  431. TValue *top;
  432. lj_trace_abort(g);
  433. top = L->top;
  434. L->top = top+2;
  435. hook_entergc(g); /* Disable hooks and new traces during __gc. */
  436. g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */
  437. copyTV(L, top, mo);
  438. setgcV(L, top+1, o, ~o->gch.gct);
  439. errcode = lj_vm_pcall(L, top+1, 1+0, -1); /* Stack: |mo|o| -> | */
  440. hook_restore(g, oldh);
  441. g->gc.threshold = oldt; /* Restore GC threshold. */
  442. if (errcode)
  443. lj_err_throw(L, errcode); /* Propagate errors. */
  444. }
  445. /* Finalize one userdata or cdata object from the mmudata list. */
  446. static void gc_finalize(lua_State *L)
  447. {
  448. global_State *g = G(L);
  449. GCobj *o = gcnext(gcref(g->gc.mmudata));
  450. cTValue *mo;
  451. lua_assert(gcref(g->jit_L) == NULL); /* Must not be called on trace. */
  452. /* Unchain from list of userdata to be finalized. */
  453. if (o == gcref(g->gc.mmudata))
  454. setgcrefnull(g->gc.mmudata);
  455. else
  456. setgcrefr(gcref(g->gc.mmudata)->gch.nextgc, o->gch.nextgc);
  457. #if LJ_HASFFI
  458. if (o->gch.gct == ~LJ_TCDATA) {
  459. TValue tmp, *tv;
  460. /* Add cdata back to the GC list and make it white. */
  461. setgcrefr(o->gch.nextgc, g->gc.root);
  462. setgcref(g->gc.root, o);
  463. makewhite(g, o);
  464. o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
  465. /* Resolve finalizer. */
  466. setcdataV(L, &tmp, gco2cd(o));
  467. tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp);
  468. if (!tvisnil(tv)) {
  469. g->gc.nocdatafin = 0;
  470. copyTV(L, &tmp, tv);
  471. setnilV(tv); /* Clear entry in finalizer table. */
  472. gc_call_finalizer(g, L, &tmp, o);
  473. }
  474. return;
  475. }
  476. #endif
  477. /* Add userdata back to the main userdata list and make it white. */
  478. setgcrefr(o->gch.nextgc, mainthread(g)->nextgc);
  479. setgcref(mainthread(g)->nextgc, o);
  480. makewhite(g, o);
  481. /* Resolve the __gc metamethod. */
  482. mo = lj_meta_fastg(g, tabref(gco2ud(o)->metatable), MM_gc);
  483. if (mo)
  484. gc_call_finalizer(g, L, mo, o);
  485. }
  486. /* Finalize all userdata objects from mmudata list. */
  487. void lj_gc_finalize_udata(lua_State *L)
  488. {
  489. while (gcref(G(L)->gc.mmudata) != NULL)
  490. gc_finalize(L);
  491. }
  492. #if LJ_HASFFI
  493. /* Finalize all cdata objects from finalizer table. */
  494. void lj_gc_finalize_cdata(lua_State *L)
  495. {
  496. global_State *g = G(L);
  497. CTState *cts = ctype_ctsG(g);
  498. if (cts) {
  499. GCtab *t = cts->finalizer;
  500. Node *node = noderef(t->node);
  501. ptrdiff_t i;
  502. setgcrefnull(t->metatable); /* Mark finalizer table as disabled. */
  503. for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
  504. if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) {
  505. GCobj *o = gcV(&node[i].key);
  506. TValue tmp;
  507. makewhite(g, o);
  508. o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
  509. copyTV(L, &tmp, &node[i].val);
  510. setnilV(&node[i].val);
  511. gc_call_finalizer(g, L, &tmp, o);
  512. }
  513. }
  514. }
  515. #endif
  516. /* Free all remaining GC objects. */
  517. void lj_gc_freeall(global_State *g)
  518. {
  519. MSize i, strmask;
  520. /* Free everything, except super-fixed objects (the main thread). */
  521. g->gc.currentwhite = LJ_GC_WHITES | LJ_GC_SFIXED;
  522. gc_fullsweep(g, &g->gc.root);
  523. strmask = g->strmask;
  524. for (i = 0; i <= strmask; i++) /* Free all string hash chains. */
  525. gc_fullsweep(g, &g->strhash[i]);
  526. }
  527. /* -- Collector ----------------------------------------------------------- */
  528. /* Atomic part of the GC cycle, transitioning from mark to sweep phase. */
  529. static void atomic(global_State *g, lua_State *L)
  530. {
  531. size_t udsize;
  532. gc_mark_uv(g); /* Need to remark open upvalues (the thread may be dead). */
  533. gc_propagate_gray(g); /* Propagate any left-overs. */
  534. setgcrefr(g->gc.gray, g->gc.weak); /* Empty the list of weak tables. */
  535. setgcrefnull(g->gc.weak);
  536. lua_assert(!iswhite(obj2gco(mainthread(g))));
  537. gc_markobj(g, L); /* Mark running thread. */
  538. gc_traverse_curtrace(g); /* Traverse current trace. */
  539. gc_mark_gcroot(g); /* Mark GC roots (again). */
  540. gc_propagate_gray(g); /* Propagate all of the above. */
  541. setgcrefr(g->gc.gray, g->gc.grayagain); /* Empty the 2nd chance list. */
  542. setgcrefnull(g->gc.grayagain);
  543. gc_propagate_gray(g); /* Propagate it. */
  544. udsize = lj_gc_separateudata(g, 0); /* Separate userdata to be finalized. */
  545. gc_mark_mmudata(g); /* Mark them. */
  546. udsize += gc_propagate_gray(g); /* And propagate the marks. */
  547. /* All marking done, clear weak tables. */
  548. gc_clearweak(gcref(g->gc.weak));
  549. /* Prepare for sweep phase. */
  550. g->gc.currentwhite = (uint8_t)otherwhite(g); /* Flip current white. */
  551. g->strempty.marked = g->gc.currentwhite;
  552. setmref(g->gc.sweep, &g->gc.root);
  553. g->gc.estimate = g->gc.total - (MSize)udsize; /* Initial estimate. */
  554. }
  555. /* GC state machine. Returns a cost estimate for each step performed. */
  556. static size_t gc_onestep(lua_State *L)
  557. {
  558. global_State *g = G(L);
  559. switch (g->gc.state) {
  560. case GCSpause:
  561. gc_mark_start(g); /* Start a new GC cycle by marking all GC roots. */
  562. return 0;
  563. case GCSpropagate:
  564. if (gcref(g->gc.gray) != NULL)
  565. return propagatemark(g); /* Propagate one gray object. */
  566. g->gc.state = GCSatomic; /* End of mark phase. */
  567. return 0;
  568. case GCSatomic:
  569. if (gcref(g->jit_L)) /* Don't run atomic phase on trace. */
  570. return LJ_MAX_MEM;
  571. atomic(g, L);
  572. g->gc.state = GCSsweepstring; /* Start of sweep phase. */
  573. g->gc.sweepstr = 0;
  574. return 0;
  575. case GCSsweepstring: {
  576. MSize old = g->gc.total;
  577. gc_fullsweep(g, &g->strhash[g->gc.sweepstr++]); /* Sweep one chain. */
  578. if (g->gc.sweepstr > g->strmask)
  579. g->gc.state = GCSsweep; /* All string hash chains sweeped. */
  580. lua_assert(old >= g->gc.total);
  581. g->gc.estimate -= old - g->gc.total;
  582. return GCSWEEPCOST;
  583. }
  584. case GCSsweep: {
  585. MSize old = g->gc.total;
  586. setmref(g->gc.sweep, gc_sweep(g, mref(g->gc.sweep, GCRef), GCSWEEPMAX));
  587. if (gcref(*mref(g->gc.sweep, GCRef)) == NULL) {
  588. gc_shrink(g, L);
  589. if (gcref(g->gc.mmudata)) { /* Need any finalizations? */
  590. g->gc.state = GCSfinalize;
  591. #if LJ_HASFFI
  592. g->gc.nocdatafin = 1;
  593. #endif
  594. } else { /* Otherwise skip this phase to help the JIT. */
  595. g->gc.state = GCSpause; /* End of GC cycle. */
  596. g->gc.debt = 0;
  597. }
  598. }
  599. lua_assert(old >= g->gc.total);
  600. g->gc.estimate -= old - g->gc.total;
  601. return GCSWEEPMAX*GCSWEEPCOST;
  602. }
  603. case GCSfinalize:
  604. if (gcref(g->gc.mmudata) != NULL) {
  605. if (gcref(g->jit_L)) /* Don't call finalizers on trace. */
  606. return LJ_MAX_MEM;
  607. gc_finalize(L); /* Finalize one userdata object. */
  608. if (g->gc.estimate > GCFINALIZECOST)
  609. g->gc.estimate -= GCFINALIZECOST;
  610. return GCFINALIZECOST;
  611. }
  612. #if LJ_HASFFI
  613. if (!g->gc.nocdatafin) lj_tab_rehash(L, ctype_ctsG(g)->finalizer);
  614. #endif
  615. g->gc.state = GCSpause; /* End of GC cycle. */
  616. g->gc.debt = 0;
  617. return 0;
  618. default:
  619. lua_assert(0);
  620. return 0;
  621. }
  622. }
  623. /* Perform a limited amount of incremental GC steps. */
  624. int LJ_FASTCALL lj_gc_step(lua_State *L)
  625. {
  626. global_State *g = G(L);
  627. MSize lim;
  628. int32_t ostate = g->vmstate;
  629. setvmstate(g, GC);
  630. lim = (GCSTEPSIZE/100) * g->gc.stepmul;
  631. if (lim == 0)
  632. lim = LJ_MAX_MEM;
  633. if (g->gc.total > g->gc.threshold)
  634. g->gc.debt += g->gc.total - g->gc.threshold;
  635. do {
  636. lim -= (MSize)gc_onestep(L);
  637. if (g->gc.state == GCSpause) {
  638. g->gc.threshold = (g->gc.estimate/100) * g->gc.pause;
  639. g->vmstate = ostate;
  640. return 1; /* Finished a GC cycle. */
  641. }
  642. } while ((int32_t)lim > 0);
  643. if (g->gc.debt < GCSTEPSIZE) {
  644. g->gc.threshold = g->gc.total + GCSTEPSIZE;
  645. g->vmstate = ostate;
  646. return -1;
  647. } else {
  648. g->gc.debt -= GCSTEPSIZE;
  649. g->gc.threshold = g->gc.total;
  650. g->vmstate = ostate;
  651. return 0;
  652. }
  653. }
  654. /* Ditto, but fix the stack top first. */
  655. void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L)
  656. {
  657. if (curr_funcisL(L)) L->top = curr_topL(L);
  658. lj_gc_step(L);
  659. }
  660. #if LJ_HASJIT
  661. /* Perform multiple GC steps. Called from JIT-compiled code. */
  662. int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps)
  663. {
  664. lua_State *L = gco2th(gcref(g->jit_L));
  665. L->base = mref(G(L)->jit_base, TValue);
  666. L->top = curr_topL(L);
  667. while (steps-- > 0 && lj_gc_step(L) == 0)
  668. ;
  669. /* Return 1 to force a trace exit. */
  670. return (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize);
  671. }
  672. #endif
  673. /* Perform a full GC cycle. */
  674. void lj_gc_fullgc(lua_State *L)
  675. {
  676. global_State *g = G(L);
  677. int32_t ostate = g->vmstate;
  678. setvmstate(g, GC);
  679. if (g->gc.state <= GCSatomic) { /* Caught somewhere in the middle. */
  680. setmref(g->gc.sweep, &g->gc.root); /* Sweep everything (preserving it). */
  681. setgcrefnull(g->gc.gray); /* Reset lists from partial propagation. */
  682. setgcrefnull(g->gc.grayagain);
  683. setgcrefnull(g->gc.weak);
  684. g->gc.state = GCSsweepstring; /* Fast forward to the sweep phase. */
  685. g->gc.sweepstr = 0;
  686. }
  687. while (g->gc.state == GCSsweepstring || g->gc.state == GCSsweep)
  688. gc_onestep(L); /* Finish sweep. */
  689. lua_assert(g->gc.state == GCSfinalize || g->gc.state == GCSpause);
  690. /* Now perform a full GC. */
  691. g->gc.state = GCSpause;
  692. do { gc_onestep(L); } while (g->gc.state != GCSpause);
  693. g->gc.threshold = (g->gc.estimate/100) * g->gc.pause;
  694. g->vmstate = ostate;
  695. }
  696. /* -- Write barriers ------------------------------------------------------ */
  697. /* Move the GC propagation frontier forward. */
  698. void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v)
  699. {
  700. lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
  701. lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
  702. lua_assert(o->gch.gct != ~LJ_TTAB);
  703. /* Preserve invariant during propagation. Otherwise it doesn't matter. */
  704. if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic)
  705. gc_mark(g, v); /* Move frontier forward. */
  706. else
  707. makewhite(g, o); /* Make it white to avoid the following barrier. */
  708. }
  709. /* Specialized barrier for closed upvalue. Pass &uv->tv. */
  710. void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv)
  711. {
  712. #define TV2MARKED(x) \
  713. (*((uint8_t *)(x) - offsetof(GCupval, tv) + offsetof(GCupval, marked)))
  714. if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic)
  715. gc_mark(g, gcV(tv));
  716. else
  717. TV2MARKED(tv) = (TV2MARKED(tv) & (uint8_t)~LJ_GC_COLORS) | curwhite(g);
  718. #undef TV2MARKED
  719. }
  720. /* Close upvalue. Also needs a write barrier. */
  721. void lj_gc_closeuv(global_State *g, GCupval *uv)
  722. {
  723. GCobj *o = obj2gco(uv);
  724. /* Copy stack slot to upvalue itself and point to the copy. */
  725. copyTV(mainthread(g), &uv->tv, uvval(uv));
  726. setmref(uv->v, &uv->tv);
  727. uv->closed = 1;
  728. setgcrefr(o->gch.nextgc, g->gc.root);
  729. setgcref(g->gc.root, o);
  730. if (isgray(o)) { /* A closed upvalue is never gray, so fix this. */
  731. if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic) {
  732. gray2black(o); /* Make it black and preserve invariant. */
  733. if (tviswhite(&uv->tv))
  734. lj_gc_barrierf(g, o, gcV(&uv->tv));
  735. } else {
  736. makewhite(g, o); /* Make it white, i.e. sweep the upvalue. */
  737. lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
  738. }
  739. }
  740. }
  741. #if LJ_HASJIT
  742. /* Mark a trace if it's saved during the propagation phase. */
  743. void lj_gc_barriertrace(global_State *g, uint32_t traceno)
  744. {
  745. if (g->gc.state == GCSpropagate || g->gc.state == GCSatomic)
  746. gc_marktrace(g, traceno);
  747. }
  748. #endif
  749. /* -- Allocator ----------------------------------------------------------- */
  750. /* Call pluggable memory allocator to allocate or resize a fragment. */
  751. void *lj_mem_realloc(lua_State *L, void *p, MSize osz, MSize nsz)
  752. {
  753. global_State *g = G(L);
  754. lua_assert((osz == 0) == (p == NULL));
  755. p = g->allocf(g->allocd, p, osz, nsz);
  756. if (p == NULL && nsz > 0)
  757. lj_err_mem(L);
  758. lua_assert((nsz == 0) == (p == NULL));
  759. lua_assert(checkptr32(p));
  760. g->gc.total = (g->gc.total - osz) + nsz;
  761. return p;
  762. }
  763. /* Allocate new GC object and link it to the root set. */
  764. void * LJ_FASTCALL lj_mem_newgco(lua_State *L, MSize size)
  765. {
  766. global_State *g = G(L);
  767. GCobj *o = (GCobj *)g->allocf(g->allocd, NULL, 0, size);
  768. if (o == NULL)
  769. lj_err_mem(L);
  770. lua_assert(checkptr32(o));
  771. g->gc.total += size;
  772. setgcrefr(o->gch.nextgc, g->gc.root);
  773. setgcref(g->gc.root, o);
  774. newwhite(g, o);
  775. return o;
  776. }
  777. /* Resize growable vector. */
  778. void *lj_mem_grow(lua_State *L, void *p, MSize *szp, MSize lim, MSize esz)
  779. {
  780. MSize sz = (*szp) << 1;
  781. if (sz < LJ_MIN_VECSZ)
  782. sz = LJ_MIN_VECSZ;
  783. if (sz > lim)
  784. sz = lim;
  785. p = lj_mem_realloc(L, p, (*szp)*esz, sz*esz);
  786. *szp = sz;
  787. return p;
  788. }