summaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-10-08 13:00:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-10-08 13:00:34 -0300
commit8050e75f9d11362dbb2a77cfb0384870471042b6 (patch)
tree2190255796b69dfdaf021ccac419cf70a6517af0 /lgc.c
parent3bec76abe350ef610996b850a1b9c9bbdd46ee6b (diff)
downloadlua-8050e75f9d11362dbb2a77cfb0384870471042b6.tar.gz
lua-8050e75f9d11362dbb2a77cfb0384870471042b6.tar.bz2
lua-8050e75f9d11362dbb2a77cfb0384870471042b6.zip
bug: gc metamethod must disable GC steps (to avoid nested calls)
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/lgc.c b/lgc.c
index 34f8ed1b..a9a4f8cc 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.12 2004/09/15 20:38:15 roberto Exp roberto $ 2** $Id: lgc.c,v 2.13 2004/10/06 18:34:16 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*/
@@ -529,6 +529,7 @@ static void remarkupvals (global_State *g) {
529 529
530static void atomic (lua_State *L) { 530static void atomic (lua_State *L) {
531 global_State *g = G(L); 531 global_State *g = G(L);
532 size_t udsize; /* total size of userdata to be finalized */
532 int aux; 533 int aux;
533 /* remark objects cautch by write barrier */ 534 /* remark objects cautch by write barrier */
534 propagateall(g); 535 propagateall(g);
@@ -544,7 +545,7 @@ static void atomic (lua_State *L) {
544 g->gray = g->grayagain; 545 g->gray = g->grayagain;
545 g->grayagain = NULL; 546 g->grayagain = NULL;
546 propagateall(g); 547 propagateall(g);
547 luaC_separateudata(L, 0); /* separate userdata to be preserved */ 548 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
548 marktmu(g); /* mark `preserved' userdata */ 549 marktmu(g); /* mark `preserved' userdata */
549 propagateall(g); /* remark, to propagate `preserveness' */ 550 propagateall(g); /* remark, to propagate `preserveness' */
550 cleartable(g->weak); /* remove collected objects from weak tables */ 551 cleartable(g->weak); /* remove collected objects from weak tables */
@@ -557,7 +558,7 @@ static void atomic (lua_State *L) {
557 g->gcgenerational = (g->estimate <= 4*g->prevestimate/2); 558 g->gcgenerational = (g->estimate <= 4*g->prevestimate/2);
558 if (!aux) /* last collection was full? */ 559 if (!aux) /* last collection was full? */
559 g->prevestimate = g->estimate; /* keep estimate of last full collection */ 560 g->prevestimate = g->estimate; /* keep estimate of last full collection */
560 g->estimate = g->totalbytes; /* first estimate */ 561 g->estimate = g->totalbytes - udsize; /* first estimate */
561} 562}
562 563
563 564
@@ -601,7 +602,9 @@ static l_mem singlestep (lua_State *L) {
601 } 602 }
602 case GCSfinalize: { 603 case GCSfinalize: {
603 if (g->tmudata) { 604 if (g->tmudata) {
605 g->GCthreshold += GCFINALIZECOST; /* avoid GC steps inside method */
604 GCTM(L); 606 GCTM(L);
607 g->GCthreshold -= GCFINALIZECOST; /* correct threshold */
605 return GCFINALIZECOST; 608 return GCFINALIZECOST;
606 } 609 }
607 else { 610 else {
@@ -661,7 +664,6 @@ void luaC_fullgc (lua_State *L) {
661 singlestep(L); 664 singlestep(L);
662 g->gcgenerational = 0; /* keep it in this mode */ 665 g->gcgenerational = 0; /* keep it in this mode */
663 } 666 }
664 lua_assert(g->estimate == g->totalbytes);
665 g->GCthreshold = 2*g->estimate; 667 g->GCthreshold = 2*g->estimate;
666 luaC_callGCTM(L); /* call finalizers */ 668 luaC_callGCTM(L); /* call finalizers */
667} 669}