diff options
Diffstat (limited to 'apps/plugins/lua/lgc.h')
-rw-r--r-- | apps/plugins/lua/lgc.h | 159 |
1 files changed, 103 insertions, 56 deletions
diff --git a/apps/plugins/lua/lgc.h b/apps/plugins/lua/lgc.h index 5123ccb479..84bb1cdf99 100644 --- a/apps/plugins/lua/lgc.h +++ b/apps/plugins/lua/lgc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id$ | 2 | ** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -9,65 +9,107 @@ | |||
9 | 9 | ||
10 | 10 | ||
11 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | #include "lstate.h" | ||
13 | |||
14 | /* | ||
15 | ** Collectable objects may have one of three colors: white, which | ||
16 | ** means the object is not marked; gray, which means the | ||
17 | ** object is marked, but its references may be not marked; and | ||
18 | ** black, which means that the object and all its references are marked. | ||
19 | ** The main invariant of the garbage collector, while marking objects, | ||
20 | ** is that a black object can never point to a white one. Moreover, | ||
21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, | ||
22 | ** allweak, ephemeron) so that it can be visited again before finishing | ||
23 | ** the collection cycle. These lists have no meaning when the invariant | ||
24 | ** is not being enforced (e.g., sweep phase). | ||
25 | */ | ||
26 | |||
27 | |||
28 | |||
29 | /* how much to allocate before next GC step */ | ||
30 | #if !defined(GCSTEPSIZE) | ||
31 | /* ~100 small strings */ | ||
32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) | ||
33 | #endif | ||
12 | 34 | ||
13 | 35 | ||
14 | /* | 36 | /* |
15 | ** Possible states of the Garbage Collector | 37 | ** Possible states of the Garbage Collector |
16 | */ | 38 | */ |
17 | #define GCSpause 0 | 39 | #define GCSpropagate 0 |
18 | #define GCSpropagate 1 | 40 | #define GCSatomic 1 |
19 | #define GCSsweepstring 2 | 41 | #define GCSsweepstring 2 |
20 | #define GCSsweep 3 | 42 | #define GCSsweepudata 3 |
21 | #define GCSfinalize 4 | 43 | #define GCSsweep 4 |
44 | #define GCSpause 5 | ||
45 | |||
22 | 46 | ||
47 | #define issweepphase(g) \ | ||
48 | (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) | ||
49 | |||
50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) | ||
23 | 51 | ||
24 | /* | 52 | /* |
25 | ** some userful bit tricks | 53 | ** macros to tell when main invariant (white objects cannot point to black |
54 | ** ones) must be kept. During a non-generational collection, the sweep | ||
55 | ** phase may break the invariant, as objects turned white may point to | ||
56 | ** still-black objects. The invariant is restored when sweep ends and | ||
57 | ** all objects are white again. During a generational collection, the | ||
58 | ** invariant must be kept all times. | ||
26 | */ | 59 | */ |
27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) | ||
28 | #define setbits(x,m) ((x) |= (m)) | ||
29 | #define testbits(x,m) ((x) & (m)) | ||
30 | #define bitmask(b) (1<<(b)) | ||
31 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) | ||
32 | #define l_setbit(x,b) setbits(x, bitmask(b)) | ||
33 | #define resetbit(x,b) resetbits(x, bitmask(b)) | ||
34 | #define testbit(x,b) testbits(x, bitmask(b)) | ||
35 | #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) | ||
36 | #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) | ||
37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) | ||
38 | 60 | ||
61 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) | ||
39 | 62 | ||
40 | 63 | ||
41 | /* | 64 | /* |
42 | ** Layout for bit use in `marked' field: | 65 | ** Outside the collector, the state in generational mode is kept in |
43 | ** bit 0 - object is white (type 0) | 66 | ** 'propagate', so 'keepinvariant' is always true. |
44 | ** bit 1 - object is white (type 1) | ||
45 | ** bit 2 - object is black | ||
46 | ** bit 3 - for userdata: has been finalized | ||
47 | ** bit 3 - for tables: has weak keys | ||
48 | ** bit 4 - for tables: has weak values | ||
49 | ** bit 5 - object is fixed (should not be collected) | ||
50 | ** bit 6 - object is "super" fixed (only the main thread) | ||
51 | */ | 67 | */ |
68 | #define keepinvariantout(g) \ | ||
69 | check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ | ||
70 | g->gcstate <= GCSatomic) | ||
71 | |||
52 | 72 | ||
73 | /* | ||
74 | ** some useful bit tricks | ||
75 | */ | ||
76 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) | ||
77 | #define setbits(x,m) ((x) |= (m)) | ||
78 | #define testbits(x,m) ((x) & (m)) | ||
79 | #define bitmask(b) (1<<(b)) | ||
80 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) | ||
81 | #define l_setbit(x,b) setbits(x, bitmask(b)) | ||
82 | #define resetbit(x,b) resetbits(x, bitmask(b)) | ||
83 | #define testbit(x,b) testbits(x, bitmask(b)) | ||
84 | |||
85 | |||
86 | /* Layout for bit use in `marked' field: */ | ||
87 | #define WHITE0BIT 0 /* object is white (type 0) */ | ||
88 | #define WHITE1BIT 1 /* object is white (type 1) */ | ||
89 | #define BLACKBIT 2 /* object is black */ | ||
90 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ | ||
91 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ | ||
92 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ | ||
93 | #define OLDBIT 6 /* object is old (only in generational mode) */ | ||
94 | /* bit 7 is currently used by tests (luaL_checkmemory) */ | ||
53 | 95 | ||
54 | #define WHITE0BIT 0 | ||
55 | #define WHITE1BIT 1 | ||
56 | #define BLACKBIT 2 | ||
57 | #define FINALIZEDBIT 3 | ||
58 | #define KEYWEAKBIT 3 | ||
59 | #define VALUEWEAKBIT 4 | ||
60 | #define FIXEDBIT 5 | ||
61 | #define SFIXEDBIT 6 | ||
62 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 96 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
63 | 97 | ||
64 | 98 | ||
65 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | 99 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) |
66 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | 100 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) |
67 | #define isgray(x) (!isblack(x) && !iswhite(x)) | 101 | #define isgray(x) /* neither white nor black */ \ |
102 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | ||
103 | |||
104 | #define isold(x) testbit((x)->gch.marked, OLDBIT) | ||
105 | |||
106 | /* MOVE OLD rule: whenever an object is moved to the beginning of | ||
107 | a GC list, its old bit must be cleared */ | ||
108 | #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) | ||
68 | 109 | ||
69 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | 110 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) |
70 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) | 111 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) |
112 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) | ||
71 | 113 | ||
72 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) | 114 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) |
73 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) | 115 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) |
@@ -77,34 +119,39 @@ | |||
77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 119 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
78 | 120 | ||
79 | 121 | ||
80 | #define luaC_checkGC(L) { \ | 122 | #define luaC_condGC(L,c) \ |
81 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ | 123 | {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} |
82 | if (G(L)->totalbytes >= G(L)->GCthreshold) \ | 124 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) |
83 | luaC_step(L); } | ||
84 | 125 | ||
85 | 126 | ||
86 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | 127 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ |
87 | luaC_barrierf(L,obj2gco(p),gcvalue(v)); } | 128 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } |
88 | 129 | ||
89 | #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ | 130 | #define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ |
90 | luaC_barrierback(L,t); } | 131 | luaC_barrierback_(L,p); } |
91 | 132 | ||
92 | #define luaC_objbarrier(L,p,o) \ | 133 | #define luaC_objbarrier(L,p,o) \ |
93 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ | 134 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ |
94 | luaC_barrierf(L,obj2gco(p),obj2gco(o)); } | 135 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } |
95 | 136 | ||
96 | #define luaC_objbarriert(L,t,o) \ | 137 | #define luaC_objbarrierback(L,p,o) \ |
97 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } | 138 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } |
98 | 139 | ||
99 | LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); | 140 | #define luaC_barrierproto(L,p,c) \ |
100 | LUAI_FUNC void luaC_callGCTM (lua_State *L); | 141 | { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } |
101 | LUAI_FUNC void luaC_freeall (lua_State *L); | ||
102 | LUAI_FUNC void luaC_step (lua_State *L); | ||
103 | LUAI_FUNC void luaC_fullgc (lua_State *L); | ||
104 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | ||
105 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); | ||
106 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); | ||
107 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); | ||
108 | 142 | ||
143 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | ||
144 | LUAI_FUNC void luaC_step (lua_State *L); | ||
145 | LUAI_FUNC void luaC_forcestep (lua_State *L); | ||
146 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); | ||
147 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | ||
148 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, | ||
149 | GCObject **list, int offset); | ||
150 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); | ||
151 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); | ||
152 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); | ||
153 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); | ||
154 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); | ||
155 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); | ||
109 | 156 | ||
110 | #endif | 157 | #endif |