aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c8
-rw-r--r--lgc.c23
-rw-r--r--lmem.c5
-rw-r--r--lstate.c15
-rw-r--r--lstate.h10
5 files changed, 35 insertions, 26 deletions
diff --git a/lapi.c b/lapi.c
index b4dbc8ed..73cf1108 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.141 2010/11/26 14:32:31 roberto Exp roberto $ 2** $Id: lapi.c,v 2.142 2010/12/20 18:17:46 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*/
@@ -964,7 +964,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
964 break; 964 break;
965 } 965 }
966 case LUA_GCRESTART: { 966 case LUA_GCRESTART: {
967 g->GCdebt = 0; 967 luaE_setdebt(g, 0);
968 g->gcrunning = 1; 968 g->gcrunning = 1;
969 break; 969 break;
970 } 970 }
@@ -975,11 +975,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
975 } 975 }
976 case LUA_GCCOUNT: { 976 case LUA_GCCOUNT: {
977 /* GC values are expressed in Kbytes: #bytes/2^10 */ 977 /* GC values are expressed in Kbytes: #bytes/2^10 */
978 res = cast_int(g->totalbytes >> 10); 978 res = cast_int(gettotalbytes(g) >> 10);
979 break; 979 break;
980 } 980 }
981 case LUA_GCCOUNTB: { 981 case LUA_GCCOUNTB: {
982 res = cast_int(g->totalbytes & 0x3ff); 982 res = cast_int(gettotalbytes(g) & 0x3ff);
983 break; 983 break;
984 } 984 }
985 case LUA_GCSTEP: { 985 case LUA_GCSTEP: {
diff --git a/lgc.c b/lgc.c
index bc9f0d4a..933b035b 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.105 2010/12/03 11:48:25 roberto Exp roberto $ 2** $Id: lgc.c,v 2.106 2010/12/20 18:17:46 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*/
@@ -51,7 +51,7 @@
51** standard negative debt for GC; a reasonable "time" to wait before 51** standard negative debt for GC; a reasonable "time" to wait before
52** starting a new cycle 52** starting a new cycle
53*/ 53*/
54#define stddebt(g) (-cast(l_mem, g->totalbytes/100) * g->gcpause) 54#define stddebt(g) (-cast(l_mem, gettotalbytes(g)/100) * g->gcpause)
55 55
56 56
57/* 57/*
@@ -634,6 +634,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
634 int ow = otherwhite(g); 634 int ow = otherwhite(g);
635 int toclear, toset; /* bits to clear and to set in all live objects */ 635 int toclear, toset; /* bits to clear and to set in all live objects */
636 int tostop; /* stop sweep when this is true */ 636 int tostop; /* stop sweep when this is true */
637 l_mem debt = g->GCdebt; /* current debt */
637 if (isgenerational(g)) { /* generational mode? */ 638 if (isgenerational(g)) { /* generational mode? */
638 toclear = ~0; /* clear nothing */ 639 toclear = ~0; /* clear nothing */
639 toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ 640 toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */
@@ -656,13 +657,15 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
656 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ 657 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
657 if (testbits(marked, tostop)) { 658 if (testbits(marked, tostop)) {
658 static GCObject *nullp = NULL; 659 static GCObject *nullp = NULL;
659 return &nullp; /* stop sweeping this list */ 660 p = &nullp; /* stop sweeping this list */
661 break;
660 } 662 }
661 /* update marks */ 663 /* update marks */
662 gch(curr)->marked = cast_byte((marked & toclear) | toset); 664 gch(curr)->marked = cast_byte((marked & toclear) | toset);
663 p = &gch(curr)->next; /* go to next element */ 665 p = &gch(curr)->next; /* go to next element */
664 } 666 }
665 } 667 }
668 luaE_setdebt(g, debt); /* sweeping should not change debt */
666 return p; 669 return p;
667} 670}
668 671
@@ -807,7 +810,7 @@ void luaC_changemode (lua_State *L, int mode) {
807 if (mode == KGC_GEN) { /* change to generational mode */ 810 if (mode == KGC_GEN) { /* change to generational mode */
808 /* make sure gray lists are consistent */ 811 /* make sure gray lists are consistent */
809 luaC_runtilstate(L, bitmask(GCSpropagate)); 812 luaC_runtilstate(L, bitmask(GCSpropagate));
810 g->lastmajormem = g->totalbytes; 813 g->lastmajormem = gettotalbytes(g);
811 g->gckind = KGC_GEN; 814 g->gckind = KGC_GEN;
812 } 815 }
813 else { /* change to incremental mode */ 816 else { /* change to incremental mode */
@@ -958,15 +961,15 @@ static void generationalcollection (lua_State *L) {
958 global_State *g = G(L); 961 global_State *g = G(L);
959 if (g->lastmajormem == 0) { /* signal for another major collection? */ 962 if (g->lastmajormem == 0) { /* signal for another major collection? */
960 luaC_fullgc(L, 0); /* perform a full regular collection */ 963 luaC_fullgc(L, 0); /* perform a full regular collection */
961 g->lastmajormem = g->totalbytes; /* update control */ 964 g->lastmajormem = gettotalbytes(g); /* update control */
962 } 965 }
963 else { 966 else {
964 luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ 967 luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */
965 luaC_runtilstate(L, bitmask(GCSpause)); 968 luaC_runtilstate(L, bitmask(GCSpause));
966 if (g->totalbytes > g->lastmajormem/100 * g->gcmajorinc) 969 if (gettotalbytes(g) > g->lastmajormem/100 * g->gcmajorinc)
967 g->lastmajormem = 0; /* signal for a major collection */ 970 g->lastmajormem = 0; /* signal for a major collection */
968 } 971 }
969 g->GCdebt = stddebt(g); 972 luaE_setdebt(g, stddebt(g));
970} 973}
971 974
972 975
@@ -977,9 +980,9 @@ static void step (lua_State *L) {
977 lim -= singlestep(L); 980 lim -= singlestep(L);
978 } while (lim > 0 && g->gcstate != GCSpause); 981 } while (lim > 0 && g->gcstate != GCSpause);
979 if (g->gcstate != GCSpause) 982 if (g->gcstate != GCSpause)
980 g->GCdebt -= GCSTEPSIZE; 983 luaE_setdebt(g, g->GCdebt - GCSTEPSIZE);
981 else 984 else
982 g->GCdebt = stddebt(g); 985 luaE_setdebt(g, stddebt(g));
983} 986}
984 987
985 988
@@ -1022,7 +1025,7 @@ void luaC_fullgc (lua_State *L, int isemergency) {
1022 luaC_runtilstate(L, bitmask(GCSpropagate)); 1025 luaC_runtilstate(L, bitmask(GCSpropagate));
1023 } 1026 }
1024 g->gckind = origkind; 1027 g->gckind = origkind;
1025 g->GCdebt = stddebt(g); 1028 luaE_setdebt(g, stddebt(g));
1026 if (!isemergency) /* do not run finalizers during emergency GC */ 1029 if (!isemergency) /* do not run finalizers during emergency GC */
1027 callallpendingfinalizers(L, 1); 1030 callallpendingfinalizers(L, 1);
1028} 1031}
diff --git a/lmem.c b/lmem.c
index 31c03364..090caa9a 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.79 2010/05/05 18:49:56 roberto Exp roberto $ 2** $Id: lmem.c,v 1.80 2010/12/20 18:17:46 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -94,8 +94,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
94 luaD_throw(L, LUA_ERRMEM); 94 luaD_throw(L, LUA_ERRMEM);
95 } 95 }
96 lua_assert((nsize == 0) == (newblock == NULL)); 96 lua_assert((nsize == 0) == (newblock == NULL));
97 g->totalbytes = (g->totalbytes - realosize) + nsize; 97 g->GCdebt = (g->GCdebt + nsize) - realosize;
98 g->GCdebt += nsize; /* give some credit to garbage collector */
99#if defined(TRACEMEM) 98#if defined(TRACEMEM)
100 { /* auxiliary patch to monitor garbage collection. 99 { /* auxiliary patch to monitor garbage collection.
101 ** To plot, gnuplot with following command: 100 ** To plot, gnuplot with following command:
diff --git a/lstate.c b/lstate.c
index d13a3ad5..fa67e855 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.87 2010/11/26 14:32:31 roberto Exp roberto $ 2** $Id: lstate.c,v 2.88 2010/12/20 18:17:46 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*/
@@ -65,11 +65,14 @@ typedef struct LG {
65#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 65#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
66 66
67 67
68
69/* 68/*
70** maximum number of nested calls made by error-handling function 69** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
70** invariant
71*/ 71*/
72#define LUAI_EXTRACALLS 10 72void luaE_setdebt (global_State *g, l_mem debt) {
73 g->totalbytes -= (debt - g->GCdebt);
74 g->GCdebt = debt;
75}
73 76
74 77
75CallInfo *luaE_extendCI (lua_State *L) { 78CallInfo *luaE_extendCI (lua_State *L) {
@@ -154,7 +157,6 @@ static void f_luaopen (lua_State *L, void *ud) {
154 /* pre-create memory-error message */ 157 /* pre-create memory-error message */
155 g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 158 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
156 luaS_fix(g->memerrmsg); /* it should never be collected */ 159 luaS_fix(g->memerrmsg); /* it should never be collected */
157 g->GCdebt = 0;
158 g->gcrunning = 1; /* allow gc */ 160 g->gcrunning = 1; /* allow gc */
159} 161}
160 162
@@ -188,7 +190,7 @@ static void close_state (lua_State *L) {
188 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 190 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
189 luaZ_freebuffer(L, &g->buff); 191 luaZ_freebuffer(L, &g->buff);
190 freestack(L); 192 freestack(L);
191 lua_assert(g->totalbytes == sizeof(LG)); 193 lua_assert(gettotalbytes(g) == sizeof(LG));
192 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); 194 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);
193} 195}
194 196
@@ -258,6 +260,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
258 g->gray = g->grayagain = NULL; 260 g->gray = g->grayagain = NULL;
259 g->weak = g->ephemeron = g->allweak = NULL; 261 g->weak = g->ephemeron = g->allweak = NULL;
260 g->totalbytes = sizeof(LG); 262 g->totalbytes = sizeof(LG);
263 g->GCdebt = 0;
261 g->gcpause = LUAI_GCPAUSE; 264 g->gcpause = LUAI_GCPAUSE;
262 g->gcmajorinc = LUAI_GCMAJOR; 265 g->gcmajorinc = LUAI_GCMAJOR;
263 g->gcstepmul = LUAI_GCMUL; 266 g->gcstepmul = LUAI_GCMUL;
diff --git a/lstate.h b/lstate.h
index fd1b2d66..6bf691b2 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.69 2010/11/26 14:32:31 roberto Exp roberto $ 2** $Id: lstate.h,v 2.70 2010/12/20 18:17:46 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*/
@@ -114,8 +114,8 @@ typedef struct CallInfo {
114typedef struct global_State { 114typedef struct global_State {
115 lua_Alloc frealloc; /* function to reallocate memory */ 115 lua_Alloc frealloc; /* function to reallocate memory */
116 void *ud; /* auxiliary data to `frealloc' */ 116 void *ud; /* auxiliary data to `frealloc' */
117 lu_mem totalbytes; /* number of bytes currently allocated */ 117 lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */
118 l_mem GCdebt; /* when positive, run a GC step */ 118 l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
119 lu_mem lastmajormem; /* memory in use after last major collection */ 119 lu_mem lastmajormem; /* memory in use after last major collection */
120 stringtable strt; /* hash table for strings */ 120 stringtable strt; /* hash table for strings */
121 TValue l_registry; 121 TValue l_registry;
@@ -210,6 +210,10 @@ union GCObject {
210#define obj2gco(v) (cast(GCObject *, (v))) 210#define obj2gco(v) (cast(GCObject *, (v)))
211 211
212 212
213/* actual number of total bytes allocated */
214#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt)
215
216LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
213LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 217LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
214LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 218LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
215LUAI_FUNC void luaE_freeCI (lua_State *L); 219LUAI_FUNC void luaE_freeCI (lua_State *L);