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 | |
parent | 531874f6ce9f47f81294beeeba6cd0c15402411c (diff) | |
download | lua-39a8082f50c7321d75425f08a551a1d331dcea2d.tar.gz lua-39a8082f50c7321d75425f08a551a1d331dcea2d.tar.bz2 lua-39a8082f50c7321d75425f08a551a1d331dcea2d.zip |
more options for controling the GC
-rw-r--r-- | lapi.c | 12 | ||||
-rw-r--r-- | lbaselib.c | 10 | ||||
-rw-r--r-- | lgc.c | 32 | ||||
-rw-r--r-- | lstate.c | 4 | ||||
-rw-r--r-- | lstate.h | 4 | ||||
-rw-r--r-- | lua.h | 14 | ||||
-rw-r--r-- | luaconf.h | 5 |
7 files changed, 49 insertions, 32 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.20 2004/11/24 18:55:56 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.21 2004/12/03 20:50:25 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -867,6 +867,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
867 | luaC_step(L); | 867 | luaC_step(L); |
868 | break; | 868 | break; |
869 | } | 869 | } |
870 | case LUA_GCSETSTEPMUL: { | ||
871 | res = g->stepmul; | ||
872 | g->stepmul = data; | ||
873 | break; | ||
874 | } | ||
875 | case LUA_GCSETINCMODE: { | ||
876 | res = g->incgc; | ||
877 | g->incgc = data; | ||
878 | break; | ||
879 | } | ||
870 | default: res = -1; /* invalid option */ | 880 | default: res = -1; /* invalid option */ |
871 | } | 881 | } |
872 | lua_unlock(L); | 882 | lua_unlock(L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.159 2004/09/29 21:03:14 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.160 2004/11/18 19:53:49 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -181,10 +181,10 @@ static int luaB_gcinfo (lua_State *L) { | |||
181 | 181 | ||
182 | 182 | ||
183 | static int luaB_collectgarbage (lua_State *L) { | 183 | static int luaB_collectgarbage (lua_State *L) { |
184 | static const char *const opts[] = {"stop", "restart", "collect", "count", | 184 | static const char *const opts[] = {"stop", "restart", "collect", |
185 | "step", NULL}; | 185 | "count", "step", "setstepmul", "setincmode", NULL}; |
186 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, | 186 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
187 | LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP}; | 187 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETSTEPMUL, LUA_GCSETINCMODE}; |
188 | int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); | 188 | int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); |
189 | int ex = luaL_optint(L, 2, 0); | 189 | int ex = luaL_optint(L, 2, 0); |
190 | luaL_argcheck(L, o >= 0, 1, "invalid option"); | 190 | luaL_argcheck(L, o >= 0, 1, "invalid option"); |
@@ -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; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.16 2004/11/19 15:52:40 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.17 2004/11/24 19:20:21 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -193,6 +193,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
193 | setnilvalue(gval(g->dummynode)); | 193 | setnilvalue(gval(g->dummynode)); |
194 | gnext(g->dummynode) = NULL; | 194 | gnext(g->dummynode) = NULL; |
195 | g->totalbytes = sizeof(LG); | 195 | g->totalbytes = sizeof(LG); |
196 | g->stepmul = STEPMUL; | ||
197 | g->incgc = 1; | ||
196 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { | 198 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { |
197 | /* memory allocation error: free partial state */ | 199 | /* memory allocation error: free partial state */ |
198 | close_state(L); | 200 | close_state(L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.7 2004/08/30 13:44:44 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.8 2004/09/15 20:39:42 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -85,6 +85,8 @@ typedef struct global_State { | |||
85 | lu_mem totalbytes; /* number of bytes currently allocated */ | 85 | lu_mem totalbytes; /* number of bytes currently allocated */ |
86 | lu_mem estimate; /* an estimate of number of bytes actually in use */ | 86 | lu_mem estimate; /* an estimate of number of bytes actually in use */ |
87 | lu_mem prevestimate; /* previous estimate */ | 87 | lu_mem prevestimate; /* previous estimate */ |
88 | int stepmul; /* relative `speed' of the GC */ | ||
89 | int incgc; /* 0 if GC is done non-incrementally */ | ||
88 | lua_CFunction panic; /* to be called in unprotected errors */ | 90 | lua_CFunction panic; /* to be called in unprotected errors */ |
89 | TValue _registry; | 91 | TValue _registry; |
90 | struct lua_State *mainthread; | 92 | struct lua_State *mainthread; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.194 2004/10/18 12:51:44 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.195 2004/12/01 15:50:18 roberto Exp roberto $ |
3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
5 | ** http://www.lua.org mailto:info@lua.org | 5 | ** http://www.lua.org mailto:info@lua.org |
@@ -220,11 +220,13 @@ LUA_API int lua_threadstatus (lua_State *L); | |||
220 | ** garbage-collection function and options | 220 | ** garbage-collection function and options |
221 | */ | 221 | */ |
222 | 222 | ||
223 | #define LUA_GCSTOP 0 | 223 | #define LUA_GCSTOP 0 |
224 | #define LUA_GCRESTART 1 | 224 | #define LUA_GCRESTART 1 |
225 | #define LUA_GCCOLLECT 2 | 225 | #define LUA_GCCOLLECT 2 |
226 | #define LUA_GCCOUNT 3 | 226 | #define LUA_GCCOUNT 3 |
227 | #define LUA_GCSTEP 4 | 227 | #define LUA_GCSTEP 4 |
228 | #define LUA_GCSETSTEPMUL 5 | ||
229 | #define LUA_GCSETINCMODE 6 | ||
228 | 230 | ||
229 | LUA_API int lua_gc (lua_State *L, int what, int data); | 231 | LUA_API int lua_gc (lua_State *L, int what, int data); |
230 | 232 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: luaconf.h,v 1.18 2004/12/01 15:50:18 roberto Exp roberto $ | 2 | ** $Id: luaconf.h,v 1.19 2004/12/01 15:52:54 roberto Exp roberto $ |
3 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -273,6 +273,9 @@ | |||
273 | #define lua_userstateopen(L) /* empty */ | 273 | #define lua_userstateopen(L) /* empty */ |
274 | 274 | ||
275 | 275 | ||
276 | /* initial GC parameters */ | ||
277 | #define STEPMUL 4 | ||
278 | |||
276 | #endif | 279 | #endif |
277 | 280 | ||
278 | /* }====================================================== */ | 281 | /* }====================================================== */ |