diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-25 16:37:23 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-03-25 16:37:23 -0300 |
commit | 5c87f61e6b1567400d2bd8f452939bb948f16dda (patch) | |
tree | 1d0944372d58c5dab9f7271c3c3b1a70fe0be0d3 | |
parent | 3aa95981779aa8144da11f328a25bf79bd141c41 (diff) | |
download | lua-5c87f61e6b1567400d2bd8f452939bb948f16dda.tar.gz lua-5c87f61e6b1567400d2bd8f452939bb948f16dda.tar.bz2 lua-5c87f61e6b1567400d2bd8f452939bb948f16dda.zip |
major collections in generational mode
-rw-r--r-- | lapi.c | 24 | ||||
-rw-r--r-- | lgc.c | 20 | ||||
-rw-r--r-- | lstate.c | 3 | ||||
-rw-r--r-- | lstate.h | 15 |
4 files changed, 39 insertions, 23 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.114 2010/03/08 16:55:52 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.115 2010/03/22 18:28:03 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 | */ |
@@ -928,7 +928,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
928 | break; | 928 | break; |
929 | } | 929 | } |
930 | case LUA_GCRESTART: { | 930 | case LUA_GCRESTART: { |
931 | g->gckind = KGC_NORMAL; | ||
932 | g->GCthreshold = g->totalbytes; | 931 | g->GCthreshold = g->totalbytes; |
933 | break; | 932 | break; |
934 | } | 933 | } |
@@ -947,13 +946,19 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
947 | } | 946 | } |
948 | case LUA_GCSTEP: { | 947 | case LUA_GCSTEP: { |
949 | lu_mem oldts = g->GCthreshold; | 948 | lu_mem oldts = g->GCthreshold; |
950 | lu_mem a = (cast(lu_mem, data) << 10); | 949 | if (g->gckind == KGC_GEN) { /* generational mode? */ |
951 | g->GCthreshold = (a <= g->totalbytes) ? g->totalbytes - a : 0; | 950 | res = (g->lastmajormem == 0); /* 1 if will do major collection */ |
952 | while (g->GCthreshold <= g->totalbytes) { | 951 | luaC_step(L); /* do a single step */ |
953 | luaC_step(L); | 952 | } |
954 | if (g->gcstate == GCSpause) { /* end of cycle? */ | 953 | else { |
955 | res = 1; /* signal it */ | 954 | lu_mem a = (cast(lu_mem, data) << 10); |
956 | break; | 955 | g->GCthreshold = (a <= g->totalbytes) ? g->totalbytes - a : 0; |
956 | while (g->GCthreshold <= g->totalbytes) { | ||
957 | luaC_step(L); | ||
958 | if (g->gcstate == GCSpause) { /* end of cycle? */ | ||
959 | res = 1; /* signal it */ | ||
960 | break; | ||
961 | } | ||
957 | } | 962 | } |
958 | } | 963 | } |
959 | if (oldts == MAX_LUMEM) /* collector was stopped? */ | 964 | if (oldts == MAX_LUMEM) /* collector was stopped? */ |
@@ -976,6 +981,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
976 | } | 981 | } |
977 | case LUA_GCGEN: { /* change collector to generational mode */ | 982 | case LUA_GCGEN: { /* change collector to generational mode */ |
978 | luaC_runtilstate(L, bitmask(GCSpropagate)); | 983 | luaC_runtilstate(L, bitmask(GCSpropagate)); |
984 | g->lastmajormem = g->totalbytes; | ||
979 | g->gckind = KGC_GEN; | 985 | g->gckind = KGC_GEN; |
980 | break; | 986 | break; |
981 | } | 987 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.71 2010/03/24 15:51:10 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.72 2010/03/25 13:06:36 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 | */ |
@@ -835,11 +835,19 @@ static int prev = 0; | |||
835 | global_State *g = G(L); | 835 | global_State *g = G(L); |
836 | int a = g->totalbytes; | 836 | int a = g->totalbytes; |
837 | lua_assert(g->gcstate == GCSpropagate); | 837 | lua_assert(g->gcstate == GCSpropagate); |
838 | luaC_runtilstate(L, bitmask(GCSpause)); | 838 | if (g->lastmajormem == 0) { /* signal for another major collection? */ |
839 | g->gcstate = GCSpropagate; /* do not run 'markroot' */ | 839 | luaC_fullgc(L, 0); /* perform a full regular collection */ |
840 | g->lastmajormem = g->totalbytes; /* update control */ | ||
841 | } | ||
842 | else { | ||
843 | luaC_runtilstate(L, bitmask(GCSpause)); | ||
844 | g->gcstate = GCSpropagate; /* do not run 'markroot' */ | ||
845 | if (g->totalbytes > g->lastmajormem/100 * g->gcpause) | ||
846 | g->lastmajormem = 0; /* signal for a major collection */ | ||
847 | } | ||
840 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; | 848 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; |
841 | /*printf("count: %d old: %d new: %d dif: %d\n", c++, a, g->totalbytes, | 849 | /*printf("count: %d old: %d new: %d dif: %d lim: %d threshold: %d\n", |
842 | g->totalbytes - prev);*/ | 850 | c++, a, g->totalbytes, g->totalbytes - prev, g->lastmajormem, g->GCthreshold);*/ |
843 | prev = g->totalbytes; | 851 | prev = g->totalbytes; |
844 | } | 852 | } |
845 | 853 | ||
@@ -890,7 +898,7 @@ void luaC_fullgc (lua_State *L, int isemergency) { | |||
890 | if (!isemergency) /* do not run finalizers during emergency GC */ | 898 | if (!isemergency) /* do not run finalizers during emergency GC */ |
891 | luaC_runtilstate(L, bitmask(GCSpause)); | 899 | luaC_runtilstate(L, bitmask(GCSpause)); |
892 | if (origkind == KGC_GEN) { /* generational mode? */ | 900 | if (origkind == KGC_GEN) { /* generational mode? */ |
893 | g->gckind = GCSpause; /* collector must be always in... */ | 901 | g->gcstate = GCSpause; /* collector must be always in... */ |
894 | luaC_runtilstate(L, bitmask(GCSpropagate)); /* ...propagate phase */ | 902 | luaC_runtilstate(L, bitmask(GCSpropagate)); /* ...propagate phase */ |
895 | } | 903 | } |
896 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; | 904 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.72 2010/03/24 13:07:01 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.73 2010/03/25 13:06:36 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 | */ |
@@ -254,6 +254,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
254 | g->uvhead.u.l.prev = &g->uvhead; | 254 | g->uvhead.u.l.prev = &g->uvhead; |
255 | g->uvhead.u.l.next = &g->uvhead; | 255 | g->uvhead.u.l.next = &g->uvhead; |
256 | g->GCthreshold = MAX_LUMEM; /* no GC while building state */ | 256 | g->GCthreshold = MAX_LUMEM; /* no GC while building state */ |
257 | g->lastmajormem = 0; | ||
257 | g->strt.size = 0; | 258 | g->strt.size = 0; |
258 | g->strt.nuse = 0; | 259 | g->strt.nuse = 0; |
259 | g->strt.hash = NULL; | 260 | g->strt.hash = NULL; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.55 2010/03/22 18:28:03 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.56 2010/03/24 13:07:01 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,9 +114,14 @@ typedef struct CallInfo { | |||
114 | ** `global state', shared by all threads of this state | 114 | ** `global state', shared by all threads of this state |
115 | */ | 115 | */ |
116 | typedef struct global_State { | 116 | typedef struct global_State { |
117 | stringtable strt; /* hash table for strings */ | ||
118 | lua_Alloc frealloc; /* function to reallocate memory */ | 117 | lua_Alloc frealloc; /* function to reallocate memory */ |
119 | void *ud; /* auxiliary data to `frealloc' */ | 118 | void *ud; /* auxiliary data to `frealloc' */ |
119 | lu_mem totalbytes; /* number of bytes currently allocated */ | ||
120 | lu_mem GCthreshold; /* when totalbytes > GCthreshold, run GC step */ | ||
121 | lu_mem lastmajormem; /* memory in use after last major collection */ | ||
122 | stringtable strt; /* hash table for strings */ | ||
123 | TValue l_registry; | ||
124 | struct Table *l_gt; /* table of globals */ | ||
120 | unsigned short nCcalls; /* number of nested C calls */ | 125 | unsigned short nCcalls; /* number of nested C calls */ |
121 | lu_byte currentwhite; | 126 | lu_byte currentwhite; |
122 | lu_byte gcstate; /* state of garbage collector */ | 127 | lu_byte gcstate; /* state of garbage collector */ |
@@ -131,16 +136,12 @@ typedef struct global_State { | |||
131 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ | 136 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ |
132 | GCObject *allweak; /* list of all-weak tables */ | 137 | GCObject *allweak; /* list of all-weak tables */ |
133 | GCObject *tobefnz; /* list of userdata to be GC */ | 138 | GCObject *tobefnz; /* list of userdata to be GC */ |
139 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | ||
134 | Mbuffer buff; /* temporary buffer for string concatenation */ | 140 | Mbuffer buff; /* temporary buffer for string concatenation */ |
135 | lu_mem GCthreshold; /* when totalbytes > GCthreshold, run GC step */ | ||
136 | lu_mem totalbytes; /* number of bytes currently allocated */ | ||
137 | int gcpause; /* size of pause between successive GCs */ | 141 | int gcpause; /* size of pause between successive GCs */ |
138 | int gcstepmul; /* GC `granularity' */ | 142 | int gcstepmul; /* GC `granularity' */ |
139 | lua_CFunction panic; /* to be called in unprotected errors */ | 143 | lua_CFunction panic; /* to be called in unprotected errors */ |
140 | TValue l_registry; | ||
141 | struct Table *l_gt; /* table of globals */ | ||
142 | struct lua_State *mainthread; | 144 | struct lua_State *mainthread; |
143 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | ||
144 | const lua_Number *version; /* pointer to version number */ | 145 | const lua_Number *version; /* pointer to version number */ |
145 | TString *envn; /* environment variable name */ | 146 | TString *envn; /* environment variable name */ |
146 | TString *tmname[TM_N]; /* array with tag-method names */ | 147 | TString *tmname[TM_N]; /* array with tag-method names */ |