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 | |
| 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)
| -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 | } |
