sweep of strings also incremental
This commit is contained in:
52
lgc.c
52
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
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -430,14 +430,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all,
|
|||||||
GCObject *curr;
|
GCObject *curr;
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
l_mem lim = *plim;
|
l_mem lim = *plim;
|
||||||
int white = otherwhite(g);
|
int dead = otherwhite(g);
|
||||||
while ((curr = *p) != NULL) {
|
while ((curr = *p) != NULL) {
|
||||||
int mark = curr->gch.marked;
|
int mark = curr->gch.marked;
|
||||||
lua_assert(all || !(mark & g->currentwhite));
|
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);
|
makewhite(g, curr);
|
||||||
p = &curr->gch.next;
|
p = &curr->gch.next;
|
||||||
lim -= objsize(curr);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*p = curr->gch.next;
|
*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;
|
int i;
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int white = otherwhite(g);
|
int dead = otherwhite(g);
|
||||||
for (i = 0; i < g->strt.size; i++) { /* for each list */
|
for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */
|
||||||
GCObject *curr;
|
GCObject *curr;
|
||||||
GCObject **p = &G(L)->strt.hash[i];
|
GCObject **p = &G(L)->strt.hash[i];
|
||||||
while ((curr = *p) != NULL) {
|
while ((curr = *p) != NULL) {
|
||||||
int mark = curr->gch.marked;
|
int mark = curr->gch.marked;
|
||||||
|
lu_mem size = sizestring(gcotots(curr)->tsv.len);
|
||||||
lua_assert(all || !(mark & g->currentwhite));
|
lua_assert(all || !(mark & g->currentwhite));
|
||||||
if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) {
|
if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) {
|
||||||
makewhite(g, curr);
|
makewhite(g, curr);
|
||||||
p = &curr->gch.next;
|
p = &curr->gch.next;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g->strt.nuse--;
|
g->strt.nuse--;
|
||||||
*p = curr->gch.next;
|
*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) {
|
void luaC_sweepall (lua_State *L) {
|
||||||
l_mem dummy = MAXLMEM;
|
l_mem dummy = MAXLMEM;
|
||||||
sweepstrings(L, 1);
|
G(L)->sweepstrgc = 0;
|
||||||
|
sweepstrings(L, 1, dummy);
|
||||||
sweeplist(L, &G(L)->rootgc, 1, &dummy);
|
sweeplist(L, &G(L)->rootgc, 1, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,7 +546,6 @@ static void markroot (lua_State *L) {
|
|||||||
makewhite(g, valtogco(g->mainthread));
|
makewhite(g, valtogco(g->mainthread));
|
||||||
markobject(g, g->mainthread);
|
markobject(g, g->mainthread);
|
||||||
markvalue(g, registry(L));
|
markvalue(g, registry(L));
|
||||||
markobject(g, g->firstudata);
|
|
||||||
markobject(g, L); /* mark running thread */
|
markobject(g, L); /* mark running thread */
|
||||||
g->gcstate = GCSpropagate;
|
g->gcstate = GCSpropagate;
|
||||||
}
|
}
|
||||||
@@ -552,14 +557,25 @@ static void atomic (lua_State *L) {
|
|||||||
marktmu(g); /* mark `preserved' userdata */
|
marktmu(g); /* mark `preserved' userdata */
|
||||||
propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */
|
propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */
|
||||||
cleartable(g->weak); /* remove collected objects from weak tables */
|
cleartable(g->weak); /* remove collected objects from weak tables */
|
||||||
/* echange current white */
|
/* flip current white */
|
||||||
g->currentwhite = otherwhite(g);
|
g->currentwhite = otherwhite(g);
|
||||||
/* first element of root list will be used as temporary head for sweep
|
/* 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);
|
makewhite(g, g->rootgc);
|
||||||
g->sweepgc = &g->rootgc->gch.next;
|
g->sweepgc = &g->rootgc->gch.next;
|
||||||
sweepstrings(L, 0);
|
g->sweepstrgc = 0;
|
||||||
g->gcstate = GCSsweep;
|
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);
|
global_State *g = G(L);
|
||||||
l_mem lim = GCSTEPSIZE;
|
l_mem lim = GCSTEPSIZE;
|
||||||
g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
|
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 */
|
g->gcstate = GCSfinalize; /* end sweep phase */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -582,6 +597,9 @@ void luaC_collectgarbage (lua_State *L) {
|
|||||||
propagatemarks(g, GCSTEPSIZE);
|
propagatemarks(g, GCSTEPSIZE);
|
||||||
/* atomic */
|
/* atomic */
|
||||||
atomic(L);
|
atomic(L);
|
||||||
|
/* GCSsweepstring */
|
||||||
|
while (g->gcstate == GCSsweepstring)
|
||||||
|
sweepstringstep(L);
|
||||||
/* GCSsweep */
|
/* GCSsweep */
|
||||||
while (g->gcstate == GCSsweep)
|
while (g->gcstate == GCSsweep)
|
||||||
sweepstep(L);
|
sweepstep(L);
|
||||||
|
|||||||
7
lgc.h
7
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
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -17,8 +17,9 @@
|
|||||||
#define GCSroot 0
|
#define GCSroot 0
|
||||||
#define GCSpropagate 1
|
#define GCSpropagate 1
|
||||||
#define GCSatomic 2
|
#define GCSatomic 2
|
||||||
#define GCSsweep 3
|
#define GCSsweepstring 3
|
||||||
#define GCSfinalize 4
|
#define GCSsweep 4
|
||||||
|
#define GCSfinalize 5
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
4
lstate.c
4
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -81,6 +81,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
|||||||
u->uv.metatable = NULL;
|
u->uv.metatable = NULL;
|
||||||
G(L)->firstudata = valtogco(u);
|
G(L)->firstudata = valtogco(u);
|
||||||
luaC_link(L, valtogco(u), LUA_TUSERDATA);
|
luaC_link(L, valtogco(u), LUA_TUSERDATA);
|
||||||
|
setbit(u->uv.marked, FIXEDBIT);
|
||||||
stack_init(L, L); /* init stack */
|
stack_init(L, L); /* init stack */
|
||||||
sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
|
sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
|
||||||
sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
|
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->panic = NULL;
|
||||||
g->gcstate = 0;
|
g->gcstate = 0;
|
||||||
g->rootgc = NULL;
|
g->rootgc = NULL;
|
||||||
|
g->sweepstrgc = 0;
|
||||||
g->currentwhite = bitmask(WHITE0BIT);
|
g->currentwhite = bitmask(WHITE0BIT);
|
||||||
g->firstudata = NULL;
|
g->firstudata = NULL;
|
||||||
g->gray = NULL;
|
g->gray = NULL;
|
||||||
|
|||||||
3
lstate.h
3
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -101,6 +101,7 @@ typedef struct global_State {
|
|||||||
GCObject *rootgc; /* list of all collectable objects */
|
GCObject *rootgc; /* list of all collectable objects */
|
||||||
GCObject *firstudata; /* udata go to the end of `rootgc' */
|
GCObject *firstudata; /* udata go to the end of `rootgc' */
|
||||||
GCObject **sweepgc; /* position of sweep in `rootgc' */
|
GCObject **sweepgc; /* position of sweep in `rootgc' */
|
||||||
|
int sweepstrgc; /* position of sweep in `strt' */
|
||||||
GCObject *gray; /* list of gray objects */
|
GCObject *gray; /* list of gray objects */
|
||||||
GCObject *weak; /* list of weak tables (to be cleared) */
|
GCObject *weak; /* list of weak tables (to be cleared) */
|
||||||
GCObject *tmudata; /* list of userdata to be GC */
|
GCObject *tmudata; /* list of userdata to be GC */
|
||||||
|
|||||||
@@ -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)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -25,9 +25,12 @@ void luaS_freeall (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
void luaS_resize (lua_State *L, int newsize) {
|
void luaS_resize (lua_State *L, int newsize) {
|
||||||
GCObject **newhash = luaM_newvector(L, newsize, GCObject *);
|
GCObject **newhash;
|
||||||
stringtable *tb = &G(L)->strt;
|
stringtable *tb;
|
||||||
int i;
|
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; i<newsize; i++) newhash[i] = NULL;
|
for (i=0; i<newsize; i++) newhash[i] = NULL;
|
||||||
/* rehash */
|
/* rehash */
|
||||||
for (i=0; i<tb->size; i++) {
|
for (i=0; i<tb->size; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user