ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_gc.h (5202B)


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