From a0a384a6b14b16bce8f48d2f2d327e716ae68f3d Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 29 Jul 2003 16:25:37 -0300 Subject: [PATCH] bug: userdata to be collected still counts into new GC threshold, increasing memory consumption --- lgc.c | 22 ++++++++++++++-------- lgc.h | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lgc.c b/lgc.c index c28ea8b9..d5169fdc 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.174 2003/07/07 13:32:19 roberto Exp roberto $ +** $Id: lgc.c,v 1.175 2003/07/16 20:49:02 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -108,7 +108,8 @@ static void marktmu (GCState *st) { /* move `dead' udata that need finalization to list `tmudata' */ -void luaC_separateudata (lua_State *L) { +size_t luaC_separateudata (lua_State *L) { + size_t deadmem = 0; GCObject **p = &G(L)->rootudata; GCObject *curr; GCObject *collected = NULL; /* to collect udata with gc event */ @@ -123,6 +124,7 @@ void luaC_separateudata (lua_State *L) { p = &curr->gch.next; } else { /* must call its gc method */ + deadmem += sizeudata(gcotou(curr)->uv.len); markfinalized(gcotou(curr)); *p = curr->gch.next; curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ @@ -133,6 +135,7 @@ void luaC_separateudata (lua_State *L) { /* insert collected udata with gc event into `tmudata' list */ *lastcollected = G(L)->tmudata; G(L)->tmudata = collected; + return deadmem; } @@ -377,7 +380,7 @@ static void sweepstrings (lua_State *L, int all) { } -static void checkSizes (lua_State *L) { +static void checkSizes (lua_State *L, size_t deadmem) { /* check size of string hash */ if (G(L)->strt.nuse < cast(lu_int32, G(L)->strt.size/4) && G(L)->strt.size > MINSTRTABSIZE*2) @@ -387,7 +390,8 @@ static void checkSizes (lua_State *L) { size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; luaZ_resizebuffer(L, &G(L)->buff, newsize); } - G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ + lua_assert(G(L)->nblocks > deadmem); + G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */ } @@ -440,24 +444,26 @@ static void markroot (GCState *st, lua_State *L) { } -static void mark (lua_State *L) { +static size_t mark (lua_State *L) { + size_t deadmem; GCState st; st.g = G(L); st.tmark = NULL; st.w = NULL; markroot(&st, L); propagatemarks(&st); /* mark all reachable objects */ - luaC_separateudata(L); /* separate userdata to be preserved */ + deadmem = luaC_separateudata(L); /* separate userdata to be preserved */ marktmu(&st); /* mark `preserved' userdata */ propagatemarks(&st); /* remark, to propagate `preserveness' */ cleartable(st.w); /* remove collected objects from weak tables */ + return deadmem; } void luaC_collectgarbage (lua_State *L) { - mark(L); + size_t deadmem = mark(L); luaC_sweep(L, 0); - checkSizes(L); + checkSizes(L, deadmem); luaC_callGCTM(L); } diff --git a/lgc.h b/lgc.h index 4e66eaa8..85f3b43e 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 1.19 2003/02/28 19:45:15 roberto Exp $ +** $Id: lgc.h,v 1.20 2003/07/16 20:49:02 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -15,7 +15,7 @@ luaC_collectgarbage(L); } -void luaC_separateudata (lua_State *L); +size_t luaC_separateudata (lua_State *L); void luaC_callGCTM (lua_State *L); void luaC_sweep (lua_State *L, int all); void luaC_collectgarbage (lua_State *L);