aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/lgc.c b/lgc.c
index de5998e3..11119585 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.105 2001/06/15 19:17:33 roberto Exp roberto $ 2** $Id: lgc.c,v 1.106 2001/06/15 20:36:57 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*/
@@ -268,7 +268,7 @@ static void collecttable (lua_State *L) {
268} 268}
269 269
270 270
271void luaC_collectudata (lua_State *L) { 271static void collectudata (lua_State *L, int keep) {
272 Udata **p = &G(L)->rootudata; 272 Udata **p = &G(L)->rootudata;
273 Udata *curr; 273 Udata *curr;
274 while ((curr = *p) != NULL) { 274 while ((curr = *p) != NULL) {
@@ -279,8 +279,13 @@ void luaC_collectudata (lua_State *L) {
279 else { /* collect */ 279 else { /* collect */
280 int tag = curr->uv.tag; 280 int tag = curr->uv.tag;
281 *p = curr->uv.next; 281 *p = curr->uv.next;
282 curr->uv.next = G(L)->TMtable[tag].collected; /* chain udata */ 282 if (keep || /* must keep all of them (to close state)? */
283 G(L)->TMtable[tag].collected = curr; 283 luaT_gettm(G(L), tag, TM_GC)) { /* or is there a GC tag method? */
284 curr->uv.next = G(L)->TMtable[tag].collected; /* chain udata ... */
285 G(L)->TMtable[tag].collected = curr; /* ... to call its TM later */
286 }
287 else /* no tag method; delete udata */
288 luaM_free(L, curr, sizeudata(curr->uv.len));
284 } 289 }
285 } 290 }
286} 291}
@@ -327,7 +332,6 @@ static void callgcTM (lua_State *L, const TObject *obj) {
327 int oldah = L->allowhooks; 332 int oldah = L->allowhooks;
328 StkId top = L->top; 333 StkId top = L->top;
329 L->allowhooks = 0; /* stop debug hooks during GC tag methods */ 334 L->allowhooks = 0; /* stop debug hooks during GC tag methods */
330 luaD_checkstack(L, 2);
331 setclvalue(top, tm); 335 setclvalue(top, tm);
332 setobj(top+1, obj); 336 setobj(top+1, obj);
333 L->top += 2; 337 L->top += 2;
@@ -338,23 +342,35 @@ static void callgcTM (lua_State *L, const TObject *obj) {
338} 342}
339 343
340 344
341void luaC_callgcTMudata (lua_State *L) { 345static void callgcTMudata (lua_State *L) {
342 int tag; 346 int tag;
347 luaD_checkstack(L, 3);
343 for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ 348 for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */
344 Udata *udata; 349 Udata *udata;
345 while ((udata = G(L)->TMtable[tag].collected) != NULL) { 350 while ((udata = G(L)->TMtable[tag].collected) != NULL) {
346 TObject obj;
347 G(L)->TMtable[tag].collected = udata->uv.next; /* remove it from list */ 351 G(L)->TMtable[tag].collected = udata->uv.next; /* remove it from list */
348 setuvalue(&obj, udata); 352 udata->uv.next = G(L)->rootudata; /* resurect it */
349 callgcTM(L, &obj); 353 G(L)->rootudata = udata;
350 luaM_free(L, udata, sizeudata(udata->uv.len)); 354 setuvalue(L->top, udata);
355 L->top++; /* keep it in stack to avoid being (recursively) collected */
356 callgcTM(L, L->top-1);
357 uvalue(L->top-1)->uv.tag = 0; /* default tag (udata is `finalized') */
358 L->top--;
351 } 359 }
352 } 360 }
353} 361}
354 362
355 363
364void luaC_callallgcTM (lua_State *L) {
365 if (G(L)->rootudata) { /* avoid problems with incomplete states */
366 collectudata(L, 1); /* collect all udata into tag lists */
367 callgcTMudata(L); /* call their GC tag methods */
368 }
369}
370
371
356void luaC_collect (lua_State *L, int all) { 372void luaC_collect (lua_State *L, int all) {
357 luaC_collectudata(L); 373 collectudata(L, 0);
358 collectstrings(L, all); 374 collectstrings(L, all);
359 collecttable(L); 375 collecttable(L);
360 collectproto(L); 376 collectproto(L);
@@ -367,9 +383,8 @@ void luaC_collectgarbage (lua_State *L) {
367 cleartables(G(L)); 383 cleartables(G(L));
368 luaC_collect(L, 0); 384 luaC_collect(L, 0);
369 checkMbuffer(L); 385 checkMbuffer(L);
370 G(L)->GCthreshold = 2*G(L)->nblocks; /* temporary threshold (for TM) */
371 luaC_callgcTMudata(L);
372 G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ 386 G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
387 callgcTMudata(L);
373 callgcTM(L, &luaO_nilobject); 388 callgcTM(L, &luaO_nilobject);
374} 389}
375 390