diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-08 13:00:34 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-08 13:00:34 -0300 |
commit | 8050e75f9d11362dbb2a77cfb0384870471042b6 (patch) | |
tree | 2190255796b69dfdaf021ccac419cf70a6517af0 /lgc.c | |
parent | 3bec76abe350ef610996b850a1b9c9bbdd46ee6b (diff) | |
download | lua-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.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -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 | ||
530 | static void atomic (lua_State *L) { | 530 | static 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 | } |