diff options
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 56 |
1 files changed, 38 insertions, 18 deletions
@@ -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 | */ | ||
551 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | 563 | static 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; |