new GC state to sweep 'localgc' list + small changes in sweep control

This commit is contained in:
Roberto Ierusalimschy
2013-08-30 16:14:26 -03:00
parent 8ef9e8460e
commit 1bf4faec64
5 changed files with 48 additions and 46 deletions

68
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.155 2013/08/28 18:30:26 roberto Exp roberto $
** $Id: lgc.c,v 2.156 2013/08/29 13:34:16 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -979,12 +979,9 @@ static void setpause (global_State *g, l_mem estimate) {
}
#define sweepphases (bitmask(GCSsweepudata) | bitmask(GCSsweep))
/*
** enter first sweep phase and prepare pointers for other sweep phases.
** The calls to 'sweeptolive' make pointers point to an object inside
** Enter first sweep phase.
** The call to 'sweeptolive' makes pointer point to an object inside
** the list (instead of to the header), so that the real sweep do not
** need to skip objects created between "now" and the start of the real
** sweep.
@@ -993,11 +990,9 @@ static void setpause (global_State *g, l_mem estimate) {
static int entersweep (lua_State *L) {
global_State *g = G(L);
int n = 0;
g->gcstate = GCSsweepudata;
lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
/* prepare to sweep finalizable objects and regular objects */
g->sweepfin = sweeptolive(L, &g->finobj, &n);
g->sweepgc = sweeptolive(L, &g->allgc, &n);
g->gcstate = GCSsweeplocal;
lua_assert(g->sweepgc == NULL);
g->sweepgc = sweeptolive(L, &g->localgc, &n);
return n;
}
@@ -1068,6 +1063,20 @@ static l_mem atomic (lua_State *L) {
}
static lu_mem sweepstep (lua_State *L, global_State *g,
int nextstate, GCObject **nextlist) {
if (g->sweepgc) { /* is there still something to sweep? */
g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
return (GCSWEEPMAX * GCSWEEPCOST);
}
else { /* next phase */
g->gcstate = nextstate;
g->sweepgc = nextlist;
return 0;
}
}
static lu_mem singlestep (lua_State *L) {
global_State *g = G(L);
switch (g->gcstate) {
@@ -1096,30 +1105,21 @@ static lu_mem singlestep (lua_State *L) {
sw = entersweep(L);
return work + sw * GCSWEEPCOST;
}
case GCSsweepudata: {
if (g->sweepfin) {
g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
return GCSWEEPMAX*GCSWEEPCOST;
}
else {
sweepwholelist(L, &g->localgc);
g->gcstate = GCSsweep;
return GCLOCALPAUSE / 4; /* some magic for now */
}
case GCSsweeplocal: {
return sweepstep(L, g, GCSsweepfin, &g->finobj);
}
case GCSsweep: {
if (g->sweepgc) {
g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
return GCSWEEPMAX*GCSWEEPCOST;
}
else {
/* sweep main thread */
GCObject *mt = obj2gco(g->mainthread);
sweeplist(L, &mt, 1);
checkBuffer(L);
g->gcstate = GCSpause; /* finish collection */
return GCSWEEPCOST;
}
case GCSsweepfin: {
return sweepstep(L, g, GCSsweepall, &g->allgc);
}
case GCSsweepall: {
return sweepstep(L, g, GCSsweepmainth, NULL);
}
case GCSsweepmainth: { /* sweep main thread */
GCObject *mt = obj2gco(g->mainthread);
sweeplist(L, &mt, 1);
checkBuffer(L);
g->gcstate = GCSpause; /* finish collection */
return GCSWEEPCOST;
}
default: lua_assert(0); return 0;
}