mirror of https://github.com/rusefi/lua.git
try to avoid sweeping new objects created with new white (and
therefore not collectable in the current cycle)
This commit is contained in:
parent
398811a313
commit
b36b4b521f
62
lgc.c
62
lgc.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lgc.c,v 2.123 2012/05/20 20:36:44 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 2.124 2012/05/21 13:18:10 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -49,6 +49,7 @@
|
|||
#define workrate(x,mul) \
|
||||
((x) < MAX_INT/80 ? ((x) * 80) / mul : ((x) / mul) * 80)
|
||||
|
||||
|
||||
/*
|
||||
** standard negative debt for GC; a reasonable "time" to wait before
|
||||
** starting a new cycle
|
||||
|
@ -738,19 +739,16 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
|||
freeobj(L, curr); /* erase 'curr' */
|
||||
}
|
||||
else {
|
||||
if (testbits(marked, tostop))
|
||||
return NULL; /* stop sweeping this list */
|
||||
if (gch(curr)->tt == LUA_TTHREAD)
|
||||
sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
|
||||
if (testbits(marked, tostop)) {
|
||||
static GCObject *nullp = NULL;
|
||||
p = &nullp; /* stop sweeping this list */
|
||||
break;
|
||||
}
|
||||
/* update marks */
|
||||
gch(curr)->marked = cast_byte((marked & toclear) | toset);
|
||||
p = &gch(curr)->next; /* go to next element */
|
||||
}
|
||||
}
|
||||
return p;
|
||||
return (*p == NULL) ? NULL : p;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
@ -865,7 +863,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
|||
GCObject **p;
|
||||
GCheader *ho = gch(o);
|
||||
/* avoid removing current sweep object */
|
||||
if (g->gcstate == GCSsweep && g->sweepgc == &ho->next) {
|
||||
if (g->sweepgc == &ho->next) {
|
||||
/* step to next object in the list */
|
||||
g->sweepgc = (ho->next == NULL) ? NULL : &gch(ho->next)->next;
|
||||
}
|
||||
|
@ -892,6 +890,24 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
|||
#define sweepphases \
|
||||
(bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
|
||||
|
||||
|
||||
/*
|
||||
** enter first sweep phase (strings) and prepare pointers for other
|
||||
** sweep phases. The calls to 'sweeplist' attempt to make pointers
|
||||
** 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.
|
||||
*/
|
||||
static void entersweep (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
g->gcstate = GCSsweepstring;
|
||||
lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
|
||||
g->sweepstrgc = 0; /* prepare to sweep strings, ... */
|
||||
g->sweepfin = sweeplist(L, &g->finobj, 1); /* finalizable objects, ... */
|
||||
g->sweepgc = sweeplist(L, &g->allgc, 1); /* and regular objects */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** change GC mode
|
||||
*/
|
||||
|
@ -907,9 +923,8 @@ void luaC_changemode (lua_State *L, int mode) {
|
|||
else { /* change to incremental mode */
|
||||
/* sweep all objects to turn them back to white
|
||||
(as white has not changed, nothing extra will be collected) */
|
||||
g->sweepstrgc = 0;
|
||||
g->gcstate = GCSsweepstring;
|
||||
g->gckind = KGC_NORMAL;
|
||||
entersweep(L);
|
||||
luaC_runtilstate(L, ~sweepphases);
|
||||
}
|
||||
}
|
||||
|
@ -972,9 +987,8 @@ static void atomic (lua_State *L) {
|
|||
/* clear values from resurrected weak tables */
|
||||
clearvalues(g, g->weak, origweak);
|
||||
clearvalues(g, g->allweak, origall);
|
||||
g->sweepstrgc = 0; /* prepare to sweep strings */
|
||||
g->gcstate = GCSsweepstring;
|
||||
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
|
||||
entersweep(L); /* prepare to sweep strings */
|
||||
/*lua_checkmemory(L);*/
|
||||
}
|
||||
|
||||
|
@ -1010,25 +1024,22 @@ static lu_mem singlestep (lua_State *L) {
|
|||
for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
|
||||
sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
|
||||
g->sweepstrgc += i;
|
||||
if (g->sweepstrgc >= g->strt.size) { /* no more strings to sweep? */
|
||||
g->sweepgc = &g->finobj; /* prepare to sweep finalizable objects */
|
||||
if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */
|
||||
g->gcstate = GCSsweepudata;
|
||||
}
|
||||
return i * GCSWEEPCOST;
|
||||
}
|
||||
case GCSsweepudata: {
|
||||
if (*g->sweepgc) {
|
||||
g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
|
||||
if (g->sweepfin) {
|
||||
g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
|
||||
return GCSWEEPMAX*GCSWEEPCOST;
|
||||
}
|
||||
else {
|
||||
g->sweepgc = &g->allgc; /* go to next phase */
|
||||
g->gcstate = GCSsweep;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case GCSsweep: {
|
||||
if (*g->sweepgc) {
|
||||
if (g->sweepgc) {
|
||||
g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
|
||||
return GCSWEEPMAX*GCSWEEPCOST;
|
||||
}
|
||||
|
@ -1121,16 +1132,19 @@ void luaC_step (lua_State *L) {
|
|||
void luaC_fullgc (lua_State *L, int isemergency) {
|
||||
global_State *g = G(L);
|
||||
int origkind = g->gckind;
|
||||
int someblack = keepinvariant(g);
|
||||
lua_assert(origkind != KGC_EMERGENCY);
|
||||
if (!isemergency) /* do not run finalizers during emergency GC */
|
||||
if (isemergency) /* do not run finalizers during emergency GC */
|
||||
g->gckind = KGC_EMERGENCY;
|
||||
else {
|
||||
g->gckind = KGC_NORMAL;
|
||||
callallpendingfinalizers(L, 1);
|
||||
if (keepinvariant(g)) { /* marking phase? */
|
||||
}
|
||||
if (someblack) { /* may there be some black objects? */
|
||||
/* must sweep all objects to turn them back to white
|
||||
(as white has not changed, nothing will be collected) */
|
||||
g->sweepstrgc = 0;
|
||||
g->gcstate = GCSsweepstring;
|
||||
entersweep(L);
|
||||
}
|
||||
g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL;
|
||||
/* finish any pending sweep phase to start a new cycle */
|
||||
luaC_runtilstate(L, bitmask(GCSpause));
|
||||
/* run entire collector */
|
||||
|
|
3
lstate.c
3
lstate.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstate.c,v 2.93 2012/02/01 21:57:15 roberto Exp roberto $
|
||||
** $Id: lstate.c,v 2.94 2012/05/11 14:06:07 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -292,6 +292,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
|||
g->allgc = NULL;
|
||||
g->finobj = NULL;
|
||||
g->tobefnz = NULL;
|
||||
g->sweepgc = g->sweepfin = NULL;
|
||||
g->gray = g->grayagain = NULL;
|
||||
g->weak = g->ephemeron = g->allweak = NULL;
|
||||
g->totalbytes = sizeof(LG);
|
||||
|
|
5
lstate.h
5
lstate.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstate.h,v 2.77 2012/02/01 21:57:15 roberto Exp roberto $
|
||||
** $Id: lstate.h,v 2.78 2012/05/20 20:36:44 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -126,7 +126,8 @@ typedef struct global_State {
|
|||
int sweepstrgc; /* position of sweep in `strt' */
|
||||
GCObject *allgc; /* list of all collectable objects */
|
||||
GCObject *finobj; /* list of collectable objects with finalizers */
|
||||
GCObject **sweepgc; /* current position of sweep */
|
||||
GCObject **sweepgc; /* current position of sweep in list 'allgc' */
|
||||
GCObject **sweepfin; /* current position of sweep in list 'finobj' */
|
||||
GCObject *gray; /* list of gray objects */
|
||||
GCObject *grayagain; /* list of objects to be traversed atomically */
|
||||
GCObject *weak; /* list of tables with weak values */
|
||||
|
|
Loading…
Reference in New Issue