diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-30 15:54:49 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-30 15:54:49 -0300 |
commit | 50a82ec1b9adafa108756077b018925131f131e8 (patch) | |
tree | 0861e68fabf699e747fb99e635a66e7ff76ca122 | |
parent | ed1751bc32bd295e27881e9d6f6bb17019d59c3e (diff) | |
download | lua-50a82ec1b9adafa108756077b018925131f131e8.tar.gz lua-50a82ec1b9adafa108756077b018925131f131e8.tar.bz2 lua-50a82ec1b9adafa108756077b018925131f131e8.zip |
gc tag methods for udata are called in (reverse) tag order
-rw-r--r-- | lgc.c | 127 | ||||
-rw-r--r-- | ltm.c | 3 | ||||
-rw-r--r-- | ltm.h | 3 |
3 files changed, 87 insertions, 46 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.50 2000/05/11 18:57:19 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.51 2000/05/24 13:54:49 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 | */ |
@@ -20,16 +20,6 @@ | |||
20 | 20 | ||
21 | 21 | ||
22 | 22 | ||
23 | static void luaD_gcTM (lua_State *L, const TObject *o) { | ||
24 | const TObject *im = luaT_getimbyObj(L, o, IM_GC); | ||
25 | if (ttype(im) != TAG_NIL) { | ||
26 | luaD_checkstack(L, 2); | ||
27 | *(L->top++) = *im; | ||
28 | *(L->top++) = *o; | ||
29 | luaD_call(L, L->top-2, 0); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | 23 | ||
34 | static int markobject (lua_State *L, TObject *o); | 24 | static int markobject (lua_State *L, TObject *o); |
35 | 25 | ||
@@ -78,9 +68,9 @@ static void tablemark (lua_State *L, Hash *h) { | |||
78 | 68 | ||
79 | 69 | ||
80 | static void travstack (lua_State *L) { | 70 | static void travstack (lua_State *L) { |
81 | int i; | 71 | StkId o; |
82 | for (i = (L->top-1)-L->stack; i>=0; i--) | 72 | for (o=L->stack; o<L->top; o++) |
83 | markobject(L, L->stack+i); | 73 | markobject(L, o); |
84 | } | 74 | } |
85 | 75 | ||
86 | 76 | ||
@@ -161,54 +151,101 @@ static void collecttable (lua_State *L) { | |||
161 | } | 151 | } |
162 | 152 | ||
163 | 153 | ||
154 | static void checktab (lua_State *L, stringtable *tb) { | ||
155 | if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10) | ||
156 | luaS_resize(L, tb, tb->size/2); /* table is too big */ | ||
157 | } | ||
158 | |||
159 | |||
164 | /* | 160 | /* |
165 | ** collect all elements with `marked' < `limit'. | 161 | ** collect all elements with `marked' <= `limit'. |
166 | ** with limit=1, that means all unmarked elements; | 162 | ** with limit=0, that means all unmarked elements; |
167 | ** with limit=MAX_INT, that means all elements. | 163 | ** with limit=MAX_INT, that means all elements. |
168 | */ | 164 | */ |
169 | static void collectstringtab (lua_State *L, int limit, stringtable *tb) { | 165 | static void collectstringtab (lua_State *L, int limit) { |
170 | int i; | 166 | int i; |
171 | TObject o; /* to call userdata `gc' tag method */ | 167 | for (i=0; i<L->strt.size; i++) { /* for each list */ |
172 | ttype(&o) = TAG_USERDATA; | 168 | TString **p = &L->strt.hash[i]; |
173 | for (i=0; i<tb->size; i++) { /* for each list */ | ||
174 | TString **p = &tb->hash[i]; | ||
175 | TString *next; | 169 | TString *next; |
176 | while ((next = *p) != NULL) { | 170 | while ((next = *p) != NULL) { |
177 | if (next->marked >= limit) { | 171 | if (next->marked > limit) { /* preserve? */ |
178 | if (next->marked < FIXMARK) /* does not change FIXMARKs */ | 172 | if (next->marked < FIXMARK) /* does not change FIXMARKs */ |
179 | next->marked = 0; | 173 | next->marked = 0; |
180 | p = &next->nexthash; | 174 | p = &next->nexthash; |
181 | } | 175 | } |
182 | else { /* collect */ | 176 | else { /* collect */ |
183 | if (tb == &L->strt) /* is string? */ | ||
184 | L->nblocks -= gcsizestring(L, next->u.s.len); | ||
185 | else { | ||
186 | tsvalue(&o) = next; | ||
187 | luaD_gcTM(L, &o); | ||
188 | L->nblocks -= gcsizeudata; | ||
189 | } | ||
190 | *p = next->nexthash; | 177 | *p = next->nexthash; |
191 | tb->nuse--; | 178 | L->strt.nuse--; |
179 | L->nblocks -= gcsizestring(L, next->u.s.len); | ||
192 | luaM_free(L, next); | 180 | luaM_free(L, next); |
193 | } | 181 | } |
194 | } | 182 | } |
195 | } | 183 | } |
196 | if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10) | 184 | checktab(L, &L->strt); |
197 | luaS_resize(L, tb, tb->size/2); /* table is too big */ | ||
198 | } | 185 | } |
199 | 186 | ||
200 | 187 | ||
201 | static void collectstring (lua_State *L, int limit) { | 188 | static void collectudatatab (lua_State *L, int all) { |
202 | collectstringtab(L, limit, &L->strt); | 189 | int i; |
203 | collectstringtab(L, limit, &L->udt); | 190 | for (i=0; i<L->udt.size; i++) { /* for each list */ |
191 | TString **p = &L->udt.hash[i]; | ||
192 | TString *next; | ||
193 | while ((next = *p) != NULL) { | ||
194 | LUA_ASSERT(L, next->marked <= 1, "udata cannot be fixed"); | ||
195 | if (next->marked > all) { /* preserve? */ | ||
196 | next->marked = 0; | ||
197 | p = &next->nexthash; | ||
198 | } | ||
199 | else { /* collect */ | ||
200 | int tag = next->u.d.tag; | ||
201 | if (tag > L->last_tag) tag = TAG_USERDATA; | ||
202 | *p = next->nexthash; | ||
203 | next->nexthash = L->IMtable[tag].collected; /* chain udata */ | ||
204 | L->IMtable[tag].collected = next; | ||
205 | L->nblocks -= gcsizeudata; | ||
206 | L->udt.nuse--; | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | checktab(L, &L->udt); | ||
211 | } | ||
212 | |||
213 | |||
214 | static void callgcTM (lua_State *L, const TObject *o) { | ||
215 | const TObject *im = luaT_getimbyObj(L, o, IM_GC); | ||
216 | if (ttype(im) != TAG_NIL) { | ||
217 | luaD_checkstack(L, 2); | ||
218 | *(L->top) = *im; | ||
219 | *(L->top+1) = *o; | ||
220 | L->top += 2; | ||
221 | luaD_call(L, L->top-2, 0); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | |||
226 | static void callgcTMudata (lua_State *L) { | ||
227 | int tag; | ||
228 | TObject o; | ||
229 | ttype(&o) = TAG_USERDATA; | ||
230 | for (tag=L->last_tag; tag>=0; tag--) { | ||
231 | TString *udata = L->IMtable[tag].collected; | ||
232 | L->IMtable[tag].collected = NULL; | ||
233 | while (udata) { | ||
234 | TString *next = udata->nexthash; | ||
235 | tsvalue(&o) = udata; | ||
236 | callgcTM(L, &o); | ||
237 | luaM_free(L, udata); | ||
238 | udata = next; | ||
239 | } | ||
240 | } | ||
204 | } | 241 | } |
205 | 242 | ||
206 | 243 | ||
207 | static void markall (lua_State *L) { | 244 | static void markall (lua_State *L) { |
245 | luaT_travtagmethods(L, markobject); /* mark tag methods */ | ||
208 | travstack(L); /* mark stack objects */ | 246 | travstack(L); /* mark stack objects */ |
209 | tablemark(L, L->gt); /* mark global variable values and names */ | 247 | tablemark(L, L->gt); /* mark global variables */ |
210 | travlock(L); /* mark locked objects */ | 248 | travlock(L); /* mark locked objects */ |
211 | luaT_travtagmethods(L, markobject); /* mark tag methods */ | ||
212 | } | 249 | } |
213 | 250 | ||
214 | 251 | ||
@@ -216,8 +253,10 @@ void luaC_collect (lua_State *L, int all) { | |||
216 | int oldah = L->allowhooks; | 253 | int oldah = L->allowhooks; |
217 | L->allowhooks = 0; /* stop debug hooks during GC */ | 254 | L->allowhooks = 0; /* stop debug hooks during GC */ |
218 | L->GCthreshold *= 4; /* to avoid GC during GC */ | 255 | L->GCthreshold *= 4; /* to avoid GC during GC */ |
256 | collectudatatab(L, all); | ||
257 | callgcTMudata(L); | ||
258 | collectstringtab(L, all?MAX_INT:0); | ||
219 | collecttable(L); | 259 | collecttable(L); |
220 | collectstring(L, all?MAX_INT:1); | ||
221 | collectproto(L); | 260 | collectproto(L); |
222 | collectclosure(L); | 261 | collectclosure(L); |
223 | L->allowhooks = oldah; /* restore hooks */ | 262 | L->allowhooks = oldah; /* restore hooks */ |
@@ -235,7 +274,7 @@ long lua_collectgarbage (lua_State *L, long limit) { | |||
235 | L->Mbuffsize /= 2; /* still larger than Mbuffnext*2 */ | 274 | L->Mbuffsize /= 2; /* still larger than Mbuffnext*2 */ |
236 | luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char); | 275 | luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char); |
237 | } | 276 | } |
238 | luaD_gcTM(L, &luaO_nilobject); | 277 | callgcTM(L, &luaO_nilobject); |
239 | return recovered; | 278 | return recovered; |
240 | } | 279 | } |
241 | 280 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 1.39 2000/03/30 16:41:51 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 1.40 2000/05/24 13:54:49 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -61,6 +61,7 @@ static void init_entry (lua_State *L, int tag) { | |||
61 | int i; | 61 | int i; |
62 | for (i=0; i<IM_N; i++) | 62 | for (i=0; i<IM_N; i++) |
63 | ttype(luaT_getim(L, tag, i)) = TAG_NIL; | 63 | ttype(luaT_getim(L, tag, i)) = TAG_NIL; |
64 | L->IMtable[tag].collected = NULL; | ||
64 | } | 65 | } |
65 | 66 | ||
66 | 67 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.h,v 1.11 2000/03/20 19:14:54 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 1.12 2000/03/30 16:41:51 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,6 +37,7 @@ typedef enum { | |||
37 | 37 | ||
38 | struct IM { | 38 | struct IM { |
39 | TObject int_method[IM_N]; | 39 | TObject int_method[IM_N]; |
40 | TString *collected; /* list of G. collected udata with this tag */ | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | 43 | ||