aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/lgc.c b/lgc.c
index f19ca70b..fe2fafc5 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.69 2010/03/23 20:16:06 roberto Exp roberto $ 2** $Id: lgc.c,v 2.70 2010/03/24 13:07:01 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*/
@@ -31,12 +31,13 @@
31#define GCATOMICCOST 1000 31#define GCATOMICCOST 1000
32 32
33 33
34#define maskcolors (~(bitmask(BLACKBIT)|WHITEBITS)) 34/*
35 35** 'makewhite' erases all color bits plus the old bit and then
36#define makewhitew(w,x) \ 36** sets only the current white bit
37 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | (w))) 37*/
38 38#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))
39#define makewhite(g,x) makewhitew(luaC_white(g), x) 39#define makewhite(w,x) \
40 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
40 41
41#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) 42#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS)
42#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) 43#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)
@@ -548,27 +549,46 @@ static void sweepthread (lua_State *L, lua_State *L1, int alive) {
548} 549}
549 550
550 551
552/*
553** sweep a list of GCObjects, erasing dead objects, where a dead (not
554** alive) object is one marked with the "old" (non current) white and
555** not fixed.
556** In non-generational mode, change all non-dead objects back to white,
557** preparing for next collection cycle.
558** In generational mode, keep black objects black, and also mark them
559** as old; stop when hitting an old object, as all objects after that
560** one will be old too.
561** When object is a thread, sweep its list of open upvalues too.
562*/
551static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { 563static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
552 GCObject *curr;
553 global_State *g = G(L); 564 global_State *g = G(L);
554 int gckind = g->gckind; 565 int gckind = g->gckind;
555 int deadmask = otherwhite(g); 566 int deadmask = otherwhite(g);
556 int white = luaC_white(g); 567 int white = luaC_white(g);
568 GCObject *curr;
557 while ((curr = *p) != NULL && count-- > 0) { 569 while ((curr = *p) != NULL && count-- > 0) {
558 int alive = (gch(curr)->marked ^ WHITEBITS) & deadmask; 570 int marked = gch(curr)->marked;
571 int alive = (marked ^ WHITEBITS) & deadmask;
559 if (gch(curr)->tt == LUA_TTHREAD) 572 if (gch(curr)->tt == LUA_TTHREAD)
560 sweepthread(L, gco2th(curr), alive); 573 sweepthread(L, gco2th(curr), alive);
561 if (alive) { 574 if (!alive) {
562 lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT));
563 /* in generational mode all live objects are kept black, which
564 means they grow to old generation */
565 if (gckind != KGC_GEN) makewhitew(white, curr);
566 p = &gch(curr)->next;
567 }
568 else { /* must erase `curr' */
569 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); 575 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
570 *p = gch(curr)->next; /* remove 'curr' from list */ 576 *p = gch(curr)->next; /* remove 'curr' from list */
571 freeobj(L, curr); 577 freeobj(L, curr); /* erase 'curr' */
578 }
579 else {
580 lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT));
581 if (gckind == KGC_GEN) { /* generational mode? */
582 if (testbit(gch(curr)->marked, OLDBIT)) { /* old generation? */
583 static GCObject *nullp = NULL;
584 return &nullp; /* stop sweeping this list */
585 }
586 else /* mark as old */
587 gch(curr)->marked = cast_byte(marked | bitmask(OLDBIT));
588 }
589 else /* not generational; makewhite */
590 gch(curr)->marked = cast_byte((marked & maskcolors) | white);
591 p = &gch(curr)->next;
572 } 592 }
573 } 593 }
574 return p; 594 return p;