src/lj_gc.h - luajit-2.0-src

Functions defined

Macros defined

Source code

  1. /*
  2. ** Garbage collector.
  3. ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  4. */

  5. #ifndef _LJ_GC_H
  6. #define _LJ_GC_H

  7. #include "lj_obj.h"

  8. /* Garbage collector states. Order matters. */
  9. enum {
  10.   GCSpause, GCSpropagate, GCSatomic, GCSsweepstring, GCSsweep, GCSfinalize
  11. };

  12. /* Bitmasks for marked field of GCobj. */
  13. #define LJ_GC_WHITE0        0x01
  14. #define LJ_GC_WHITE1        0x02
  15. #define LJ_GC_BLACK        0x04
  16. #define LJ_GC_FINALIZED        0x08
  17. #define LJ_GC_WEAKKEY        0x08
  18. #define LJ_GC_WEAKVAL        0x10
  19. #define LJ_GC_CDATA_FIN        0x10
  20. #define LJ_GC_FIXED        0x20
  21. #define LJ_GC_SFIXED        0x40

  22. #define LJ_GC_WHITES        (LJ_GC_WHITE0 | LJ_GC_WHITE1)
  23. #define LJ_GC_COLORS        (LJ_GC_WHITES | LJ_GC_BLACK)
  24. #define LJ_GC_WEAK        (LJ_GC_WEAKKEY | LJ_GC_WEAKVAL)

  25. /* Macros to test and set GCobj colors. */
  26. #define iswhite(x)        ((x)->gch.marked & LJ_GC_WHITES)
  27. #define isblack(x)        ((x)->gch.marked & LJ_GC_BLACK)
  28. #define isgray(x)        (!((x)->gch.marked & (LJ_GC_BLACK|LJ_GC_WHITES)))
  29. #define tviswhite(x)        (tvisgcv(x) && iswhite(gcV(x)))
  30. #define otherwhite(g)        (g->gc.currentwhite ^ LJ_GC_WHITES)
  31. #define isdead(g, v)        ((v)->gch.marked & otherwhite(g) & LJ_GC_WHITES)

  32. #define curwhite(g)        ((g)->gc.currentwhite & LJ_GC_WHITES)
  33. #define newwhite(g, x)        (obj2gco(x)->gch.marked = (uint8_t)curwhite(g))
  34. #define makewhite(g, x) \
  35.   ((x)->gch.marked = ((x)->gch.marked & (uint8_t)~LJ_GC_COLORS) | curwhite(g))
  36. #define flipwhite(x)        ((x)->gch.marked ^= LJ_GC_WHITES)
  37. #define black2gray(x)        ((x)->gch.marked &= (uint8_t)~LJ_GC_BLACK)
  38. #define fixstring(s)        ((s)->marked |= LJ_GC_FIXED)
  39. #define markfinalized(x)        ((x)->gch.marked |= LJ_GC_FINALIZED)

  40. /* Collector. */
  41. LJ_FUNC size_t lj_gc_separateudata(global_State *g, int all);
  42. LJ_FUNC void lj_gc_finalize_udata(lua_State *L);
  43. #if LJ_HASFFI
  44. LJ_FUNC void lj_gc_finalize_cdata(lua_State *L);
  45. #else
  46. #define lj_gc_finalize_cdata(L)                UNUSED(L)
  47. #endif
  48. LJ_FUNC void lj_gc_freeall(global_State *g);
  49. LJ_FUNCA int LJ_FASTCALL lj_gc_step(lua_State *L);
  50. LJ_FUNCA void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L);
  51. #if LJ_HASJIT
  52. LJ_FUNC int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps);
  53. #endif
  54. LJ_FUNC void lj_gc_fullgc(lua_State *L);

  55. /* GC check: drive collector forward if the GC threshold has been reached. */
  56. #define lj_gc_check(L) \
  57.   { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
  58.       lj_gc_step(L); }
  59. #define lj_gc_check_fixtop(L) \
  60.   { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
  61.       lj_gc_step_fixtop(L); }

  62. /* Write barriers. */
  63. LJ_FUNC void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v);
  64. LJ_FUNCA void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv);
  65. LJ_FUNC void lj_gc_closeuv(global_State *g, GCupval *uv);
  66. #if LJ_HASJIT
  67. LJ_FUNC void lj_gc_barriertrace(global_State *g, uint32_t traceno);
  68. #endif

  69. /* Move the GC propagation frontier back for tables (make it gray again). */
  70. static LJ_AINLINE void lj_gc_barrierback(global_State *g, GCtab *t)
  71. {
  72.   GCobj *o = obj2gco(t);
  73.   lua_assert(isblack(o) && !isdead(g, o));
  74.   lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
  75.   black2gray(o);
  76.   setgcrefr(t->gclist, g->gc.grayagain);
  77.   setgcref(g->gc.grayagain, o);
  78. }

  79. /* Barrier for stores to table objects. TValue and GCobj variant. */
  80. #define lj_gc_anybarriert(L, t)  \
  81.   { if (LJ_UNLIKELY(isblack(obj2gco(t)))) lj_gc_barrierback(G(L), (t)); }
  82. #define lj_gc_barriert(L, t, tv) \
  83.   { if (tviswhite(tv) && isblack(obj2gco(t))) \
  84.       lj_gc_barrierback(G(L), (t)); }
  85. #define lj_gc_objbarriert(L, t, o)  \
  86.   { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) \
  87.       lj_gc_barrierback(G(L), (t)); }

  88. /* Barrier for stores to any other object. TValue and GCobj variant. */
  89. #define lj_gc_barrier(L, p, tv) \
  90.   { if (tviswhite(tv) && isblack(obj2gco(p))) \
  91.       lj_gc_barrierf(G(L), obj2gco(p), gcV(tv)); }
  92. #define lj_gc_objbarrier(L, p, o) \
  93.   { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
  94.       lj_gc_barrierf(G(L), obj2gco(p), obj2gco(o)); }

  95. /* Allocator. */
  96. LJ_FUNC void *lj_mem_realloc(lua_State *L, void *p, GCSize osz, GCSize nsz);
  97. LJ_FUNC void * LJ_FASTCALL lj_mem_newgco(lua_State *L, GCSize size);
  98. LJ_FUNC void *lj_mem_grow(lua_State *L, void *p,
  99.                           MSize *szp, MSize lim, MSize esz);

  100. #define lj_mem_new(L, s)        lj_mem_realloc(L, NULL, 0, (s))

  101. static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize)
  102. {
  103.   g->gc.total -= (GCSize)osize;
  104.   g->allocf(g->allocd, p, osize, 0);
  105. }

  106. #define lj_mem_newvec(L, n, t)        ((t *)lj_mem_new(L, (GCSize)((n)*sizeof(t))))
  107. #define lj_mem_reallocvec(L, p, on, n, t) \
  108.   ((p) = (t *)lj_mem_realloc(L, p, (on)*sizeof(t), (GCSize)((n)*sizeof(t))))
  109. #define lj_mem_growvec(L, p, n, m, t) \
  110.   ((p) = (t *)lj_mem_grow(L, (p), &(n), (m), (MSize)sizeof(t)))
  111. #define lj_mem_freevec(g, p, n, t)        lj_mem_free(g, (p), (n)*sizeof(t))

  112. #define lj_mem_newobj(L, t)        ((t *)lj_mem_newgco(L, sizeof(t)))
  113. #define lj_mem_newt(L, s, t)        ((t *)lj_mem_new(L, (s)))
  114. #define lj_mem_freet(g, p)        lj_mem_free(g, (p), sizeof(*(p)))

  115. #endif