diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-24 12:51:10 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-24 12:51:10 -0300 |
commit | 64d39ed1b6c1cb749a5815002509572020424bf3 (patch) | |
tree | 0761935f08ff979d17a9f5b31c45097f5213c6ff | |
parent | 4433dbb5f5ac0bb6118bc49ddf061f194c070814 (diff) | |
download | lua-64d39ed1b6c1cb749a5815002509572020424bf3.tar.gz lua-64d39ed1b6c1cb749a5815002509572020424bf3.tar.bz2 lua-64d39ed1b6c1cb749a5815002509572020424bf3.zip |
generational mode no longer sweep old objects
-rw-r--r-- | lgc.c | 56 | ||||
-rw-r--r-- | lgc.h | 4 |
2 files changed, 41 insertions, 19 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; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.27 2009/12/16 16:42:58 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.28 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 | */ |
@@ -49,6 +49,7 @@ | |||
49 | ** bit 4 - for userdata: it's in 'udgc' list or in 'tobefnz' | 49 | ** bit 4 - for userdata: it's in 'udgc' list or in 'tobefnz' |
50 | ** bit 5 - object is fixed (should not be collected) | 50 | ** bit 5 - object is fixed (should not be collected) |
51 | ** bit 6 - object is "super" fixed (only the main thread) | 51 | ** bit 6 - object is "super" fixed (only the main thread) |
52 | ** bit 7 - object is old (only in generational mode) | ||
52 | */ | 53 | */ |
53 | #define WHITE0BIT 0 | 54 | #define WHITE0BIT 0 |
54 | #define WHITE1BIT 1 | 55 | #define WHITE1BIT 1 |
@@ -57,6 +58,7 @@ | |||
57 | #define SEPARATED 4 | 58 | #define SEPARATED 4 |
58 | #define FIXEDBIT 5 | 59 | #define FIXEDBIT 5 |
59 | #define SFIXEDBIT 6 | 60 | #define SFIXEDBIT 6 |
61 | #define OLDBIT 7 | ||
60 | 62 | ||
61 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 63 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
62 | 64 | ||