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