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 | /* }====================================================== */ |
