diff options
-rw-r--r-- | lapi.c | 8 | ||||
-rw-r--r-- | lgc.c | 23 | ||||
-rw-r--r-- | lmem.c | 5 | ||||
-rw-r--r-- | lstate.c | 15 | ||||
-rw-r--r-- | lstate.h | 10 |
5 files changed, 35 insertions, 26 deletions
@@ -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: { |
@@ -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 | } |
@@ -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: |
@@ -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 | 72 | void luaE_setdebt (global_State *g, l_mem debt) { |
73 | g->totalbytes -= (debt - g->GCdebt); | ||
74 | g->GCdebt = debt; | ||
75 | } | ||
73 | 76 | ||
74 | 77 | ||
75 | CallInfo *luaE_extendCI (lua_State *L) { | 78 | CallInfo *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; |
@@ -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 { | |||
114 | typedef struct global_State { | 114 | typedef 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 | |||
216 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); | ||
213 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | 217 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
214 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 218 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
215 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 219 | LUAI_FUNC void luaE_freeCI (lua_State *L); |