kgc.h (3467B)
1 /* 2 ** kgc.h 3 ** Garbage Collector 4 ** See Copyright Notice in klisp.h 5 */ 6 7 /* 8 ** SOURCE NOTE: This is almost textually from lua. 9 ** Parts that don't apply, or don't apply yet to klisp are in comments. 10 */ 11 12 #ifndef kgc_h 13 #define kgc_h 14 15 #include "kobject.h" 16 #include "kstate.h" 17 18 /* 19 ** Possible states of the Garbage Collector 20 */ 21 #define GCSpause 0 22 #define GCSpropagate 1 23 #define GCSsweepstring 2 24 #define GCSsweep 3 25 #define GCSfinalize 4 26 27 /* NOTE: unlike in lua the gc flags have 16 bits in klisp, 28 so resetbits is slightly different */ 29 30 /* 31 ** some useful bit tricks 32 */ 33 #define resetbits(x,m) ((x) &= cast(uint16_t, ~(m))) 34 #define setbits(x,m) ((x) |= (m)) 35 #define testbits(x,m) ((x) & (m)) 36 #define bitmask(b) (1<<(b)) 37 #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 38 #define k_setbit(x,b) setbits(x, bitmask(b)) 39 #define resetbit(x,b) resetbits(x, bitmask(b)) 40 #define testbit(x,b) testbits(x, bitmask(b)) 41 #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) 42 #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) 43 #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) 44 45 /* NOTE: in klisp there is still no userdata, threads or finalization. 46 Also the field is called gct instead of marked */ 47 48 /* 49 ** Layout for bit use in `gct' field: 50 ** bit 0 - object is white (type 0) 51 ** bit 1 - object is white (type 1) 52 ** bit 2 - object is black 53 ** bit 3 - for userdata: has been finalized 54 ** bit 3 - for tables: has weak keys 55 ** bit 4 - for tables: has weak values 56 ** bit 5 - object is fixed (should not be collected) 57 ** bit 6 - object is "super" fixed (only the main thread) 58 */ 59 60 61 #define WHITE0BIT 0 62 #define WHITE1BIT 1 63 #define BLACKBIT 2 64 #define FINALIZEDBIT 3 65 #define KEYWEAKBIT 3 66 #define VALUEWEAKBIT 4 67 #define FIXEDBIT 5 68 #define SFIXEDBIT 6 69 #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 70 71 72 #define iswhite(x) test2bits((x)->gch.gct, WHITE0BIT, WHITE1BIT) 73 #define isblack(x) testbit((x)->gch.gct, BLACKBIT) 74 #define isgray(x) (!isblack(x) && !iswhite(x)) 75 76 #define otherwhite(g) (g->currentwhite ^ WHITEBITS) 77 #define isdead(g,v) ((v)->gch.gct & otherwhite(g) & WHITEBITS) 78 79 #define changewhite(x) ((x)->gch.gct ^= WHITEBITS) 80 #define gray2black(x) k_setbit((x)->gch.gct, BLACKBIT) 81 82 #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 83 84 #define klispC_white(g) cast(uint16_t, (g)->currentwhite & WHITEBITS) 85 86 87 #define klispC_checkGC(K) { \ 88 if (G(K)->totalbytes >= G(K)->GCthreshold) \ 89 klispC_step(K); } 90 91 92 #define klispC_barrier(K,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 93 klispC_barrierf(K,obj2gco(p),gcvalue(v)); } 94 95 #define klispC_barriert(K,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ 96 klispC_barrierback(K,t); } 97 98 #define klispC_objbarrier(K,p,o) \ 99 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 100 klispC_barrierf(K,obj2gco(p),obj2gco(o)); } 101 102 #define klispC_objbarriert(K,t,o) \ 103 { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) klispC_barrierback(K,t); } 104 105 /* size_t klispC_separateudata (klisp_State *K, int all); */ 106 /* void klispC_callGCTM (klisp_State *K); */ 107 void klispC_freeall (klisp_State *K); 108 void klispC_step (klisp_State *K); 109 void klispC_fullgc (klisp_State *K); 110 void klispC_link (klisp_State *K, GCObject *o, uint8_t tt, uint8_t flags); 111 void klispC_barrierf (klisp_State *K, GCObject *o, GCObject *v); 112 void klispC_barrierback (klisp_State *K, Table *t); 113 114 #endif