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