diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-12-06 15:53:42 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-12-06 15:53:42 -0200 |
commit | 39a8082f50c7321d75425f08a551a1d331dcea2d (patch) | |
tree | 2a942d2647897371dc104b0271783f78cd0415f8 /lgc.c | |
parent | 531874f6ce9f47f81294beeeba6cd0c15402411c (diff) | |
download | lua-39a8082f50c7321d75425f08a551a1d331dcea2d.tar.gz lua-39a8082f50c7321d75425f08a551a1d331dcea2d.tar.bz2 lua-39a8082f50c7321d75425f08a551a1d331dcea2d.zip |
more options for controling the GC
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 32 |
1 files changed, 15 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.16 2004/11/24 18:55:56 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.17 2004/11/24 19:20:21 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 | */ |
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | 25 | ||
26 | #define GCSTEPSIZE 1000 | 26 | #define GCSTEPSIZE 1000 |
27 | #define STEPMUL 2 | ||
28 | #define GCSWEEPMAX 10 | 27 | #define GCSWEEPMAX 10 |
29 | #define GCSWEEPCOST 30 | 28 | #define GCSWEEPCOST 30 |
30 | #define GCFINALIZECOST 100 | 29 | #define GCFINALIZECOST 100 |
@@ -65,7 +64,7 @@ | |||
65 | static void removeentry (Node *n) { | 64 | static void removeentry (Node *n) { |
66 | setnilvalue(gval(n)); /* remove corresponding value ... */ | 65 | setnilvalue(gval(n)); /* remove corresponding value ... */ |
67 | if (iscollectable(gkey(n))) | 66 | if (iscollectable(gkey(n))) |
68 | setttype(gkey(n), LUA_TNONE); /* dead key; remove it */ | 67 | setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ |
69 | } | 68 | } |
70 | 69 | ||
71 | 70 | ||
@@ -184,6 +183,7 @@ static int traversetable (global_State *g, Table *h) { | |||
184 | i = sizenode(h); | 183 | i = sizenode(h); |
185 | while (i--) { | 184 | while (i--) { |
186 | Node *n = gnode(h, i); | 185 | Node *n = gnode(h, i); |
186 | lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); | ||
187 | if (ttisnil(gval(n))) | 187 | if (ttisnil(gval(n))) |
188 | removeentry(n); /* remove empty entries */ | 188 | removeentry(n); /* remove empty entries */ |
189 | else { | 189 | else { |
@@ -555,7 +555,7 @@ static void atomic (lua_State *L) { | |||
555 | g->sweepgc = &g->rootgc; | 555 | g->sweepgc = &g->rootgc; |
556 | g->gcstate = GCSsweepstring; | 556 | g->gcstate = GCSsweepstring; |
557 | aux = g->gcgenerational; | 557 | aux = g->gcgenerational; |
558 | g->gcgenerational = (g->estimate/2 <= g->prevestimate); | 558 | g->gcgenerational = g->incgc && (g->estimate/2 <= g->prevestimate); |
559 | if (!aux) /* last collection was full? */ | 559 | if (!aux) /* last collection was full? */ |
560 | g->prevestimate = g->estimate; /* keep estimate of last full collection */ | 560 | g->prevestimate = g->estimate; /* keep estimate of last full collection */ |
561 | g->estimate = g->totalbytes - udsize; /* first estimate */ | 561 | g->estimate = g->totalbytes - udsize; /* first estimate */ |
@@ -587,6 +587,7 @@ static l_mem singlestep (lua_State *L) { | |||
587 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | 587 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); |
588 | if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ | 588 | if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ |
589 | g->gcstate = GCSsweep; /* end sweep-string phase */ | 589 | g->gcstate = GCSsweep; /* end sweep-string phase */ |
590 | lua_assert(old >= g->totalbytes); | ||
590 | g->estimate -= old - g->totalbytes; | 591 | g->estimate -= old - g->totalbytes; |
591 | return GCSWEEPCOST; | 592 | return GCSWEEPCOST; |
592 | } | 593 | } |
@@ -597,6 +598,7 @@ static l_mem singlestep (lua_State *L) { | |||
597 | checkSizes(L); | 598 | checkSizes(L); |
598 | g->gcstate = GCSfinalize; /* end sweep phase */ | 599 | g->gcstate = GCSfinalize; /* end sweep phase */ |
599 | } | 600 | } |
601 | lua_assert(old >= g->totalbytes); | ||
600 | g->estimate -= old - g->totalbytes; | 602 | g->estimate -= old - g->totalbytes; |
601 | return GCSWEEPMAX*GCSWEEPCOST; | 603 | return GCSWEEPMAX*GCSWEEPCOST; |
602 | } | 604 | } |
@@ -619,23 +621,18 @@ static l_mem singlestep (lua_State *L) { | |||
619 | 621 | ||
620 | void luaC_step (lua_State *L) { | 622 | void luaC_step (lua_State *L) { |
621 | global_State *g = G(L); | 623 | global_State *g = G(L); |
622 | l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * STEPMUL; | 624 | l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * g->stepmul; |
623 | /*printf("step(%c): ", g->gcgenerational?'g':' ');*/ | ||
624 | do { | 625 | do { |
625 | /*printf("%c", "_pswf"[g->gcstate]);*/ | ||
626 | lim -= singlestep(L); | 626 | lim -= singlestep(L); |
627 | if (g->gcstate == GCSpause) | 627 | if (g->gcstate == GCSpause) |
628 | break; | 628 | break; |
629 | } while (lim > 0); | 629 | } while (lim > 0 || !g->incgc); |
630 | /*printf("\n");*/ | 630 | if (g->incgc) |
631 | if (g->gcstate != GCSpause) | ||
632 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ | 631 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ |
633 | else { | 632 | else { |
634 | /*printf("---\n");*/ | ||
635 | lua_assert(g->totalbytes >= g->estimate); | 633 | lua_assert(g->totalbytes >= g->estimate); |
634 | lua_assert(g->gcstate == GCSpause); | ||
636 | g->GCthreshold = 2*g->estimate; | 635 | g->GCthreshold = 2*g->estimate; |
637 | if (g->GCthreshold < g->totalbytes + GCSTEPSIZE) | ||
638 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; | ||
639 | } | 636 | } |
640 | } | 637 | } |
641 | 638 | ||
@@ -660,19 +657,19 @@ void luaC_fullgc (lua_State *L) { | |||
660 | } | 657 | } |
661 | markroot(L); | 658 | markroot(L); |
662 | lua_assert(!g->gcgenerational); | 659 | lua_assert(!g->gcgenerational); |
663 | while (g->gcstate != GCSfinalize) { | 660 | while (g->gcstate != GCSpause) { |
664 | singlestep(L); | 661 | singlestep(L); |
665 | g->gcgenerational = 0; /* keep it in this mode */ | 662 | g->gcgenerational = 0; /* keep it in this mode */ |
666 | } | 663 | } |
667 | g->GCthreshold = 2*g->estimate; | 664 | g->GCthreshold = 2*g->estimate; |
668 | luaC_callGCTM(L); /* call finalizers */ | ||
669 | } | 665 | } |
670 | 666 | ||
671 | 667 | ||
672 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 668 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { |
673 | global_State *g = G(L); | 669 | global_State *g = G(L); |
674 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 670 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
675 | lua_assert(g->gcgenerational || g->gcstate != GCSfinalize); | 671 | lua_assert(g->gcgenerational || |
672 | (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); | ||
676 | lua_assert(ttype(&o->gch) != LUA_TTABLE); | 673 | lua_assert(ttype(&o->gch) != LUA_TTABLE); |
677 | /* must keep invariant? */ | 674 | /* must keep invariant? */ |
678 | if (g->gcstate == GCSpropagate || g->gcgenerational) | 675 | if (g->gcstate == GCSpropagate || g->gcgenerational) |
@@ -685,7 +682,8 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | |||
685 | void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { | 682 | void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { |
686 | global_State *g = G(L); | 683 | global_State *g = G(L); |
687 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 684 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
688 | lua_assert(g->gcgenerational || g->gcstate != GCSfinalize); | 685 | lua_assert(g->gcgenerational || |
686 | (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); | ||
689 | black2gray(o); /* make table gray (again) */ | 687 | black2gray(o); /* make table gray (again) */ |
690 | gco2h(o)->gclist = g->grayagain; | 688 | gco2h(o)->gclist = g->grayagain; |
691 | g->grayagain = o; | 689 | g->grayagain = o; |