From 9db1942bac5fb509c6e46ccc825351a6be546792 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 4 Dec 2003 15:22:42 -0200 Subject: [PATCH] sweep of strings also incremental --- lgc.c | 52 +++++++++++++++++++++++++++++++++++----------------- lgc.h | 7 ++++--- lstate.c | 4 +++- lstate.h | 3 ++- lstring.c | 9 ++++++--- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/lgc.c b/lgc.c index 183b91ef..c0ebef05 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.183 2003/12/03 12:30:41 roberto Exp roberto $ +** $Id: lgc.c,v 1.184 2003/12/03 20:03:07 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -430,14 +430,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all, GCObject *curr; global_State *g = G(L); l_mem lim = *plim; - int white = otherwhite(g); + int dead = otherwhite(g); while ((curr = *p) != NULL) { int mark = curr->gch.marked; lua_assert(all || !(mark & g->currentwhite)); - if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { + lim -= objsize(curr); + if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { makewhite(g, curr); p = &curr->gch.next; - lim -= objsize(curr); } else { *p = curr->gch.next; @@ -450,27 +450,32 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all, } -static void sweepstrings (lua_State *L, int all) { +static l_mem sweepstrings (lua_State *L, int all, l_mem lim) { int i; global_State *g = G(L); - int white = otherwhite(g); - for (i = 0; i < g->strt.size; i++) { /* for each list */ + int dead = otherwhite(g); + for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */ GCObject *curr; GCObject **p = &G(L)->strt.hash[i]; while ((curr = *p) != NULL) { int mark = curr->gch.marked; + lu_mem size = sizestring(gcotots(curr)->tsv.len); lua_assert(all || !(mark & g->currentwhite)); - if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { + if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { makewhite(g, curr); p = &curr->gch.next; } else { g->strt.nuse--; *p = curr->gch.next; - luaM_free(L, curr, sizestring(gcotots(curr)->tsv.len)); + luaM_free(L, curr, size); } + lim -= size; } + if (lim <= 0) break; } + g->sweepstrgc = i+1; + return lim; } @@ -527,7 +532,8 @@ void luaC_callGCTM (lua_State *L) { void luaC_sweepall (lua_State *L) { l_mem dummy = MAXLMEM; - sweepstrings(L, 1); + G(L)->sweepstrgc = 0; + sweepstrings(L, 1, dummy); sweeplist(L, &G(L)->rootgc, 1, &dummy); } @@ -540,7 +546,6 @@ static void markroot (lua_State *L) { makewhite(g, valtogco(g->mainthread)); markobject(g, g->mainthread); markvalue(g, registry(L)); - markobject(g, g->firstudata); markobject(g, L); /* mark running thread */ g->gcstate = GCSpropagate; } @@ -552,14 +557,25 @@ static void atomic (lua_State *L) { marktmu(g); /* mark `preserved' userdata */ propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ cleartable(g->weak); /* remove collected objects from weak tables */ - /* echange current white */ + /* flip current white */ g->currentwhite = otherwhite(g); /* first element of root list will be used as temporary head for sweep - phase, so it won't be seeped */ + phase, so it won't be swept */ makewhite(g, g->rootgc); g->sweepgc = &g->rootgc->gch.next; - sweepstrings(L, 0); - g->gcstate = GCSsweep; + g->sweepstrgc = 0; + g->gcstate = GCSsweepstring; +} + + +static void sweepstringstep (lua_State *L) { + global_State *g = G(L); + l_mem lim = sweepstrings(L, 0, GCSTEPSIZE); + if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ + lua_assert(g->sweepstrgc > g->strt.size); + g->sweepstrgc = 0; + g->gcstate = GCSsweep; /* end sweep-string phase */ + } } @@ -567,9 +583,8 @@ static void sweepstep (lua_State *L) { global_State *g = G(L); l_mem lim = GCSTEPSIZE; g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); - if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ + if (lim == GCSTEPSIZE) /* nothing more to sweep? */ g->gcstate = GCSfinalize; /* end sweep phase */ - } } @@ -582,6 +597,9 @@ void luaC_collectgarbage (lua_State *L) { propagatemarks(g, GCSTEPSIZE); /* atomic */ atomic(L); + /* GCSsweepstring */ + while (g->gcstate == GCSsweepstring) + sweepstringstep(L); /* GCSsweep */ while (g->gcstate == GCSsweep) sweepstep(L); diff --git a/lgc.h b/lgc.h index 2946947b..9193e2cb 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 1.25 2003/12/01 16:33:30 roberto Exp roberto $ +** $Id: lgc.h,v 1.26 2003/12/03 20:03:07 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -17,8 +17,9 @@ #define GCSroot 0 #define GCSpropagate 1 #define GCSatomic 2 -#define GCSsweep 3 -#define GCSfinalize 4 +#define GCSsweepstring 3 +#define GCSsweep 4 +#define GCSfinalize 5 /* diff --git a/lstate.c b/lstate.c index 99aeabdb..b52ff66d 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.131 2003/12/03 12:30:41 roberto Exp roberto $ +** $Id: lstate.c,v 1.132 2003/12/03 20:03:07 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -81,6 +81,7 @@ static void f_luaopen (lua_State *L, void *ud) { u->uv.metatable = NULL; G(L)->firstudata = valtogco(u); luaC_link(L, valtogco(u), LUA_TUSERDATA); + setbit(u->uv.marked, FIXEDBIT); stack_init(L, L); /* init stack */ sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ @@ -167,6 +168,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->panic = NULL; g->gcstate = 0; g->rootgc = NULL; + g->sweepstrgc = 0; g->currentwhite = bitmask(WHITE0BIT); g->firstudata = NULL; g->gray = NULL; diff --git a/lstate.h b/lstate.h index a0d49c65..c44828b6 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.116 2003/12/03 12:30:41 roberto Exp roberto $ +** $Id: lstate.h,v 1.117 2003/12/03 20:03:07 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -101,6 +101,7 @@ typedef struct global_State { GCObject *rootgc; /* list of all collectable objects */ GCObject *firstudata; /* udata go to the end of `rootgc' */ GCObject **sweepgc; /* position of sweep in `rootgc' */ + int sweepstrgc; /* position of sweep in `strt' */ GCObject *gray; /* list of gray objects */ GCObject *weak; /* list of weak tables (to be cleared) */ GCObject *tmudata; /* list of userdata to be GC */ diff --git a/lstring.c b/lstring.c index db0b98bf..5495542d 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.82 2003/12/03 12:30:41 roberto Exp roberto $ +** $Id: lstring.c,v 1.83 2003/12/03 20:03:07 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -25,9 +25,12 @@ void luaS_freeall (lua_State *L) { void luaS_resize (lua_State *L, int newsize) { - GCObject **newhash = luaM_newvector(L, newsize, GCObject *); - stringtable *tb = &G(L)->strt; + GCObject **newhash; + stringtable *tb; int i; + if (G(L)->sweepstrgc > 0) return; /* cannot resize during GC traverse */ + newhash = luaM_newvector(L, newsize, GCObject *); + tb = &G(L)->strt; for (i=0; isize; i++) {