aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-05-30 15:54:49 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-05-30 15:54:49 -0300
commit50a82ec1b9adafa108756077b018925131f131e8 (patch)
tree0861e68fabf699e747fb99e635a66e7ff76ca122
parented1751bc32bd295e27881e9d6f6bb17019d59c3e (diff)
downloadlua-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.c127
-rw-r--r--ltm.c3
-rw-r--r--ltm.h3
3 files changed, 87 insertions, 46 deletions
diff --git a/lgc.c b/lgc.c
index cc984992..a9dfc412 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
23static 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
34static int markobject (lua_State *L, TObject *o); 24static 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
80static void travstack (lua_State *L) { 70static 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
154static 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*/
169static void collectstringtab (lua_State *L, int limit, stringtable *tb) { 165static 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
201static void collectstring (lua_State *L, int limit) { 188static 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
214static 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
226static 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
207static void markall (lua_State *L) { 244static 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
diff --git a/ltm.c b/ltm.c
index 410d23c0..a173879e 100644
--- a/ltm.c
+++ b/ltm.c
@@ -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
diff --git a/ltm.h b/ltm.h
index be3e51e3..48acd59f 100644
--- a/ltm.h
+++ b/ltm.h
@@ -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
38struct IM { 38struct 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