zombiezen.com/go/lua@v0.0.0-20231013005828-290725fb9140/internal/lua54/lgc.h (about)

     1  /*
     2  ** $Id: lgc.h $
     3  ** Garbage Collector
     4  ** See Copyright Notice in lua.h
     5  */
     6  
     7  #ifndef lgc_h
     8  #define lgc_h
     9  
    10  
    11  #include "lobject.h"
    12  #include "lstate.h"
    13  
    14  /*
    15  ** Collectable objects may have one of three colors: white, which means
    16  ** the object is not marked; gray, which means the object is marked, but
    17  ** its references may be not marked; and black, which means that the
    18  ** object and all its references are marked.  The main invariant of the
    19  ** garbage collector, while marking objects, is that a black object can
    20  ** never point to a white one. Moreover, any gray object must be in a
    21  ** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it
    22  ** can be visited again before finishing the collection cycle. (Open
    23  ** upvalues are an exception to this rule.)  These lists have no meaning
    24  ** when the invariant is not being enforced (e.g., sweep phase).
    25  */
    26  
    27  
    28  /*
    29  ** Possible states of the Garbage Collector
    30  */
    31  #define GCSpropagate	0
    32  #define GCSenteratomic	1
    33  #define GCSatomic	2
    34  #define GCSswpallgc	3
    35  #define GCSswpfinobj	4
    36  #define GCSswptobefnz	5
    37  #define GCSswpend	6
    38  #define GCScallfin	7
    39  #define GCSpause	8
    40  
    41  
    42  #define issweepphase(g)  \
    43  	(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
    44  
    45  
    46  /*
    47  ** macro to tell when main invariant (white objects cannot point to black
    48  ** ones) must be kept. During a collection, the sweep
    49  ** phase may break the invariant, as objects turned white may point to
    50  ** still-black objects. The invariant is restored when sweep ends and
    51  ** all objects are white again.
    52  */
    53  
    54  #define keepinvariant(g)	((g)->gcstate <= GCSatomic)
    55  
    56  
    57  /*
    58  ** some useful bit tricks
    59  */
    60  #define resetbits(x,m)		((x) &= cast_byte(~(m)))
    61  #define setbits(x,m)		((x) |= (m))
    62  #define testbits(x,m)		((x) & (m))
    63  #define bitmask(b)		(1<<(b))
    64  #define bit2mask(b1,b2)		(bitmask(b1) | bitmask(b2))
    65  #define l_setbit(x,b)		setbits(x, bitmask(b))
    66  #define resetbit(x,b)		resetbits(x, bitmask(b))
    67  #define testbit(x,b)		testbits(x, bitmask(b))
    68  
    69  
    70  /*
    71  ** Layout for bit use in 'marked' field. First three bits are
    72  ** used for object "age" in generational mode. Last bit is used
    73  ** by tests.
    74  */
    75  #define WHITE0BIT	3  /* object is white (type 0) */
    76  #define WHITE1BIT	4  /* object is white (type 1) */
    77  #define BLACKBIT	5  /* object is black */
    78  #define FINALIZEDBIT	6  /* object has been marked for finalization */
    79  
    80  #define TESTBIT		7
    81  
    82  
    83  
    84  #define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
    85  
    86  
    87  #define iswhite(x)      testbits((x)->marked, WHITEBITS)
    88  #define isblack(x)      testbit((x)->marked, BLACKBIT)
    89  #define isgray(x)  /* neither white nor black */  \
    90  	(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
    91  
    92  #define tofinalize(x)	testbit((x)->marked, FINALIZEDBIT)
    93  
    94  #define otherwhite(g)	((g)->currentwhite ^ WHITEBITS)
    95  #define isdeadm(ow,m)	((m) & (ow))
    96  #define isdead(g,v)	isdeadm(otherwhite(g), (v)->marked)
    97  
    98  #define changewhite(x)	((x)->marked ^= WHITEBITS)
    99  #define nw2black(x)  \
   100  	check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT))
   101  
   102  #define luaC_white(g)	cast_byte((g)->currentwhite & WHITEBITS)
   103  
   104  
   105  /* object age in generational mode */
   106  #define G_NEW		0	/* created in current cycle */
   107  #define G_SURVIVAL	1	/* created in previous cycle */
   108  #define G_OLD0		2	/* marked old by frw. barrier in this cycle */
   109  #define G_OLD1		3	/* first full cycle as old */
   110  #define G_OLD		4	/* really old object (not to be visited) */
   111  #define G_TOUCHED1	5	/* old object touched this cycle */
   112  #define G_TOUCHED2	6	/* old object touched in previous cycle */
   113  
   114  #define AGEBITS		7  /* all age bits (111) */
   115  
   116  #define getage(o)	((o)->marked & AGEBITS)
   117  #define setage(o,a)  ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a))
   118  #define isold(o)	(getage(o) > G_SURVIVAL)
   119  
   120  #define changeage(o,f,t)  \
   121  	check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t)))
   122  
   123  
   124  /* Default Values for GC parameters */
   125  #define LUAI_GENMAJORMUL         100
   126  #define LUAI_GENMINORMUL         20
   127  
   128  /* wait memory to double before starting new cycle */
   129  #define LUAI_GCPAUSE    200
   130  
   131  /*
   132  ** some gc parameters are stored divided by 4 to allow a maximum value
   133  ** up to 1023 in a 'lu_byte'.
   134  */
   135  #define getgcparam(p)	((p) * 4)
   136  #define setgcparam(p,v)	((p) = (v) / 4)
   137  
   138  #define LUAI_GCMUL      100
   139  
   140  /* how much to allocate before next GC step (log2) */
   141  #define LUAI_GCSTEPSIZE 13      /* 8 KB */
   142  
   143  
   144  /*
   145  ** Check whether the declared GC mode is generational. While in
   146  ** generational mode, the collector can go temporarily to incremental
   147  ** mode to improve performance. This is signaled by 'g->lastatomic != 0'.
   148  */
   149  #define isdecGCmodegen(g)	(g->gckind == KGC_GEN || g->lastatomic != 0)
   150  
   151  
   152  /*
   153  ** Control when GC is running:
   154  */
   155  #define GCSTPUSR	1  /* bit true when GC stopped by user */
   156  #define GCSTPGC		2  /* bit true when GC stopped by itself */
   157  #define GCSTPCLS	4  /* bit true when closing Lua state */
   158  #define gcrunning(g)	((g)->gcstp == 0)
   159  
   160  
   161  /*
   162  ** Does one step of collection when debt becomes positive. 'pre'/'pos'
   163  ** allows some adjustments to be done only when needed. macro
   164  ** 'condchangemem' is used only for heavy tests (forcing a full
   165  ** GC cycle on every opportunity)
   166  */
   167  #define luaC_condGC(L,pre,pos) \
   168  	{ if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
   169  	  condchangemem(L,pre,pos); }
   170  
   171  /* more often than not, 'pre'/'pos' are empty */
   172  #define luaC_checkGC(L)		luaC_condGC(L,(void)0,(void)0)
   173  
   174  
   175  #define luaC_objbarrier(L,p,o) (  \
   176  	(isblack(p) && iswhite(o)) ? \
   177  	luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
   178  
   179  #define luaC_barrier(L,p,v) (  \
   180  	iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0))
   181  
   182  #define luaC_objbarrierback(L,p,o) (  \
   183  	(isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0))
   184  
   185  #define luaC_barrierback(L,p,v) (  \
   186  	iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0))
   187  
   188  LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
   189  LUAI_FUNC void luaC_freeallobjects (lua_State *L);
   190  LUAI_FUNC void luaC_step (lua_State *L);
   191  LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
   192  LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
   193  LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
   194  LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz,
   195                                                   size_t offset);
   196  LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
   197  LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
   198  LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
   199  LUAI_FUNC void luaC_changemode (lua_State *L, int newmode);
   200  
   201  
   202  #endif