aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/lgc.c b/lgc.c
index 552164b5..bf36d025 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.96 2010/05/17 20:39:31 roberto Exp roberto $ 2** $Id: lgc.c,v 2.97 2010/06/02 18:36:58 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -127,7 +127,7 @@ static int iscleared (const TValue *o, int iskey) {
127** barrier that moves collector forward, that is, mark the white object 127** barrier that moves collector forward, that is, mark the white object
128** being pointed by a black object. 128** being pointed by a black object.
129*/ 129*/
130void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 130void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
131 global_State *g = G(L); 131 global_State *g = G(L);
132 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 132 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
133 lua_assert(isgenerational(g) || g->gcstate != GCSpause); 133 lua_assert(isgenerational(g) || g->gcstate != GCSpause);
@@ -143,19 +143,32 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
143 143
144/* 144/*
145** barrier that moves collector backward, that is, mark the black object 145** barrier that moves collector backward, that is, mark the black object
146** pointing to a white object as gray again. 146** pointing to a white object as gray again. (Current implementation
147** only works for tables; access to 'gclist' is not uniform across
148** different types.)
147*/ 149*/
148void luaC_barrierback (lua_State *L, Table *t) { 150void luaC_barrierback_ (lua_State *L, GCObject *o) {
149 global_State *g = G(L); 151 global_State *g = G(L);
150 GCObject *o = obj2gco(t);
151 lua_assert(isblack(o) && !isdead(g, o)); 152 lua_assert(isblack(o) && !isdead(g, o));
152 black2gray(o); /* make table gray (again) */ 153 black2gray(o); /* make object gray (again) */
153 t->gclist = g->grayagain; 154 gco2t(o)->gclist = g->grayagain;
154 g->grayagain = o; 155 g->grayagain = o;
155} 156}
156 157
157 158
158/* 159/*
160** barrier for prototypes
161*/
162LUAI_FUNC void luaC_barrierproto_ (lua_State *L, GCObject *p) {
163 global_State *g = G(L);
164 lua_assert(isblack(p));
165 black2gray(p); /* make object gray (again) */
166 gco2p(p)->gclist = g->clearcache;
167 g->clearcache = p;
168}
169
170
171/*
159** check color (and invariants) for an upvalue that was closed, 172** check color (and invariants) for an upvalue that was closed,
160** i.e., moved into the 'allgc' list 173** i.e., moved into the 'allgc' list
161*/ 174*/
@@ -299,7 +312,7 @@ static void remarkupvals (global_State *g) {
299static void markroot (lua_State *L) { 312static void markroot (lua_State *L) {
300 global_State *g = G(L); 313 global_State *g = G(L);
301 g->gray = g->grayagain = NULL; 314 g->gray = g->grayagain = NULL;
302 g->weak = g->allweak = g->ephemeron = NULL; 315 g->weak = g->allweak = g->ephemeron = g->clearcache = NULL;
303 markobject(g, g->mainthread); 316 markobject(g, g->mainthread);
304 markvalue(g, &g->l_registry); 317 markvalue(g, &g->l_registry);
305 markmt(g); 318 markmt(g);
@@ -409,8 +422,19 @@ static int traversetable (global_State *g, Table *h) {
409} 422}
410 423
411 424
425/*
426** if prototype's cached closure is not marked, erase it so it
427** can be collected
428*/
429static void checkcache (Proto *p) {
430 if (p->cache && iswhite(obj2gco(p->cache)))
431 p->cache = NULL; /* allow cache to be collected */
432}
433
434
412static int traverseproto (global_State *g, Proto *f) { 435static int traverseproto (global_State *g, Proto *f) {
413 int i; 436 int i;
437 checkcache(f);
414 stringmark(f->source); 438 stringmark(f->source);
415 for (i = 0; i < f->sizek; i++) /* mark literals */ 439 for (i = 0; i < f->sizek; i++) /* mark literals */
416 markvalue(g, &f->k[i]); 440 markvalue(g, &f->k[i]);
@@ -534,6 +558,15 @@ static void convergeephemerons (global_State *g) {
534*/ 558*/
535 559
536/* 560/*
561** clear cache field in all prototypes in list 'l'
562*/
563static void clearproto (GCObject *l) {
564 for (; l != NULL; l = gco2p(l)->gclist)
565 checkcache(gco2p(l));
566}
567
568
569/*
537** clear collected entries from all weaktables in list 'l' 570** clear collected entries from all weaktables in list 'l'
538*/ 571*/
539static void cleartable (GCObject *l) { 572static void cleartable (GCObject *l) {
@@ -845,6 +878,7 @@ static void atomic (lua_State *L) {
845 cleartable(g->weak); 878 cleartable(g->weak);
846 cleartable(g->ephemeron); 879 cleartable(g->ephemeron);
847 cleartable(g->allweak); 880 cleartable(g->allweak);
881 clearproto(g->clearcache);
848 g->sweepstrgc = 0; /* prepare to sweep strings */ 882 g->sweepstrgc = 0; /* prepare to sweep strings */
849 g->gcstate = GCSsweepstring; 883 g->gcstate = GCSsweepstring;
850 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 884 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */