root/lj_gc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. lj_gc_barrierback
  2. lj_mem_free

   1 /*
   2 ** Garbage collector.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 */
   5 
   6 #ifndef _LJ_GC_H
   7 #define _LJ_GC_H
   8 
   9 #include "lj_obj.h"
  10 
  11 /* Garbage collector states. Order matters. */
  12 enum {
  13   GCSpause, GCSpropagate, GCSatomic, GCSsweepstring, GCSsweep, GCSfinalize
  14 };
  15 
  16 /* Bitmasks for marked field of GCobj. */
  17 #define LJ_GC_WHITE0    0x01
  18 #define LJ_GC_WHITE1    0x02
  19 #define LJ_GC_BLACK     0x04
  20 #define LJ_GC_FINALIZED 0x08
  21 #define LJ_GC_WEAKKEY   0x08
  22 #define LJ_GC_WEAKVAL   0x10
  23 #define LJ_GC_CDATA_FIN 0x10
  24 #define LJ_GC_FIXED     0x20
  25 #define LJ_GC_SFIXED    0x40
  26 
  27 #define LJ_GC_WHITES    (LJ_GC_WHITE0 | LJ_GC_WHITE1)
  28 #define LJ_GC_COLORS    (LJ_GC_WHITES | LJ_GC_BLACK)
  29 #define LJ_GC_WEAK      (LJ_GC_WEAKKEY | LJ_GC_WEAKVAL)
  30 
  31 /* Macros to test and set GCobj colors. */
  32 #define iswhite(x)      ((x)->gch.marked & LJ_GC_WHITES)
  33 #define isblack(x)      ((x)->gch.marked & LJ_GC_BLACK)
  34 #define isgray(x)       (!((x)->gch.marked & (LJ_GC_BLACK|LJ_GC_WHITES)))
  35 #define tviswhite(x)    (tvisgcv(x) && iswhite(gcV(x)))
  36 #define otherwhite(g)   (g->gc.currentwhite ^ LJ_GC_WHITES)
  37 #define isdead(g, v)    ((v)->gch.marked & otherwhite(g) & LJ_GC_WHITES)
  38 
  39 #define curwhite(g)     ((g)->gc.currentwhite & LJ_GC_WHITES)
  40 #define newwhite(g, x)  (obj2gco(x)->gch.marked = (uint8_t)curwhite(g))
  41 #define makewhite(g, x) \
  42   ((x)->gch.marked = ((x)->gch.marked & (uint8_t)~LJ_GC_COLORS) | curwhite(g))
  43 #define flipwhite(x)    ((x)->gch.marked ^= LJ_GC_WHITES)
  44 #define black2gray(x)   ((x)->gch.marked &= (uint8_t)~LJ_GC_BLACK)
  45 #define fixstring(s)    ((s)->marked |= LJ_GC_FIXED)
  46 #define markfinalized(x)        ((x)->gch.marked |= LJ_GC_FINALIZED)
  47 
  48 /* Collector. */
  49 LJ_FUNC size_t lj_gc_separateudata(global_State *g, int all);
  50 LJ_FUNC void lj_gc_finalize_udata(lua_State *L);
  51 #if LJ_HASFFI
  52 LJ_FUNC void lj_gc_finalize_cdata(lua_State *L);
  53 #else
  54 #define lj_gc_finalize_cdata(L)         UNUSED(L)
  55 #endif
  56 LJ_FUNC void lj_gc_freeall(global_State *g);
  57 LJ_FUNCA int LJ_FASTCALL lj_gc_step(lua_State *L);
  58 LJ_FUNCA void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L);
  59 #if LJ_HASJIT
  60 LJ_FUNC int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps);
  61 #endif
  62 LJ_FUNC void lj_gc_fullgc(lua_State *L);
  63 
  64 /* GC check: drive collector forward if the GC threshold has been reached. */
  65 #define lj_gc_check(L) \
  66   { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
  67       lj_gc_step(L); }
  68 #define lj_gc_check_fixtop(L) \
  69   { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
  70       lj_gc_step_fixtop(L); }
  71 
  72 /* Write barriers. */
  73 LJ_FUNC void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v);
  74 LJ_FUNCA void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv);
  75 LJ_FUNC void lj_gc_closeuv(global_State *g, GCupval *uv);
  76 #if LJ_HASJIT
  77 LJ_FUNC void lj_gc_barriertrace(global_State *g, uint32_t traceno);
  78 #endif
  79 
  80 /* Move the GC propagation frontier back for tables (make it gray again). */
  81 static LJ_AINLINE void lj_gc_barrierback(global_State *g, GCtab *t)
  82 {
  83   GCobj *o = obj2gco(t);
  84   lua_assert(isblack(o) && !isdead(g, o));
  85   lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause);
  86   black2gray(o);
  87   setgcrefr(t->gclist, g->gc.grayagain);
  88   setgcref(g->gc.grayagain, o);
  89 }
  90 
  91 /* Barrier for stores to table objects. TValue and GCobj variant. */
  92 #define lj_gc_anybarriert(L, t)  \
  93   { if (LJ_UNLIKELY(isblack(obj2gco(t)))) lj_gc_barrierback(G(L), (t)); }
  94 #define lj_gc_barriert(L, t, tv) \
  95   { if (tviswhite(tv) && isblack(obj2gco(t))) \
  96       lj_gc_barrierback(G(L), (t)); }
  97 #define lj_gc_objbarriert(L, t, o)  \
  98   { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) \
  99       lj_gc_barrierback(G(L), (t)); }
 100 
 101 /* Barrier for stores to any other object. TValue and GCobj variant. */
 102 #define lj_gc_barrier(L, p, tv) \
 103   { if (tviswhite(tv) && isblack(obj2gco(p))) \
 104       lj_gc_barrierf(G(L), obj2gco(p), gcV(tv)); }
 105 #define lj_gc_objbarrier(L, p, o) \
 106   { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
 107       lj_gc_barrierf(G(L), obj2gco(p), obj2gco(o)); }
 108 
 109 /* Allocator. */
 110 LJ_FUNC void *lj_mem_realloc(lua_State *L, void *p, MSize osz, MSize nsz);
 111 LJ_FUNC void * LJ_FASTCALL lj_mem_newgco(lua_State *L, MSize size);
 112 LJ_FUNC void *lj_mem_grow(lua_State *L, void *p,
 113                           MSize *szp, MSize lim, MSize esz);
 114 
 115 #define lj_mem_new(L, s)        lj_mem_realloc(L, NULL, 0, (s))
 116 
 117 static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize)
 118 {
 119   g->gc.total -= (MSize)osize;
 120   g->allocf(g->allocd, p, osize, 0);
 121 }
 122 
 123 #define lj_mem_newvec(L, n, t)  ((t *)lj_mem_new(L, (MSize)((n)*sizeof(t))))
 124 #define lj_mem_reallocvec(L, p, on, n, t) \
 125   ((p) = (t *)lj_mem_realloc(L, p, (on)*sizeof(t), (MSize)((n)*sizeof(t))))
 126 #define lj_mem_growvec(L, p, n, m, t) \
 127   ((p) = (t *)lj_mem_grow(L, (p), &(n), (m), (MSize)sizeof(t)))
 128 #define lj_mem_freevec(g, p, n, t)      lj_mem_free(g, (p), (n)*sizeof(t))
 129 
 130 #define lj_mem_newobj(L, t)     ((t *)lj_mem_newgco(L, sizeof(t)))
 131 #define lj_mem_newt(L, s, t)    ((t *)lj_mem_new(L, (s)))
 132 #define lj_mem_freet(g, p)      lj_mem_free(g, (p), sizeof(*(p)))
 133 
 134 #endif

/* [<][>][^][v][top][bottom][index][help] */