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 | ||
