summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-12-06 15:53:42 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-12-06 15:53:42 -0200
commit39a8082f50c7321d75425f08a551a1d331dcea2d (patch)
tree2a942d2647897371dc104b0271783f78cd0415f8
parent531874f6ce9f47f81294beeeba6cd0c15402411c (diff)
downloadlua-39a8082f50c7321d75425f08a551a1d331dcea2d.tar.gz
lua-39a8082f50c7321d75425f08a551a1d331dcea2d.tar.bz2
lua-39a8082f50c7321d75425f08a551a1d331dcea2d.zip
more options for controling the GC
-rw-r--r--lapi.c12
-rw-r--r--lbaselib.c10
-rw-r--r--lgc.c32
-rw-r--r--lstate.c4
-rw-r--r--lstate.h4
-rw-r--r--lua.h14
-rw-r--r--luaconf.h5
7 files changed, 49 insertions, 32 deletions
diff --git a/lapi.c b/lapi.c
index a4cb91aa..9447f929 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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);
diff --git a/lbaselib.c b/lbaselib.c
index 58d43ece..f087c977 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -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
183static int luaB_collectgarbage (lua_State *L) { 183static 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");
diff --git a/lgc.c b/lgc.c
index 61f7a55a..ae6af687 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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 @@
65static void removeentry (Node *n) { 64static 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
620void luaC_step (lua_State *L) { 622void 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
672void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 668void 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) {
685void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { 682void 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;
diff --git a/lstate.c b/lstate.c
index ff5d0376..021b8a68 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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);
diff --git a/lstate.h b/lstate.h
index 836e3df5..612a785e 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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;
diff --git a/lua.h b/lua.h
index 8e005d09..80c7f1b3 100644
--- a/lua.h
+++ b/lua.h
@@ -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
229LUA_API int lua_gc (lua_State *L, int what, int data); 231LUA_API int lua_gc (lua_State *L, int what, int data);
230 232
diff --git a/luaconf.h b/luaconf.h
index 8c3aa080..c7c2ee98 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -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/* }====================================================== */