mirror of https://github.com/rusefi/lua.git
no more 'finalize' phase in GC; finalizers are called along the
entire cycle
This commit is contained in:
parent
d25f7f9d78
commit
0c27de2e7b
53
lgc.c
53
lgc.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.83 2010/04/30 18:37:14 roberto Exp roberto $
|
** $Id: lgc.c,v 2.84 2010/05/03 11:55:40 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
#define GCSTEPSIZE 1024
|
#define GCSTEPSIZE 1024
|
||||||
#define GCSWEEPMAX 40
|
#define GCSWEEPMAX 40
|
||||||
#define GCSWEEPCOST 1
|
#define GCSWEEPCOST 1
|
||||||
#define GCFINALIZECOST 50
|
#define GCFINALIZENUM 4
|
||||||
#define GCROOTCOST 10
|
#define GCROOTCOST 10
|
||||||
#define GCATOMICCOST 1000
|
#define GCATOMICCOST 1000
|
||||||
|
|
||||||
|
@ -115,8 +115,7 @@ static int iscleared (const TValue *o, int iskey) {
|
||||||
void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
|
void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
|
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
|
||||||
lua_assert(g->gckind == KGC_GEN ||
|
lua_assert(g->gckind == KGC_GEN || g->gcstate != GCSpause);
|
||||||
(g->gcstate != GCSfinalize && g->gcstate != GCSpause));
|
|
||||||
lua_assert(gch(o)->tt != LUA_TTABLE);
|
lua_assert(gch(o)->tt != LUA_TTABLE);
|
||||||
if (keepinvariant(g)) /* must keep invariant? */
|
if (keepinvariant(g)) /* must keep invariant? */
|
||||||
reallymarkobject(g, v); /* restore invariant */
|
reallymarkobject(g, v); /* restore invariant */
|
||||||
|
@ -643,6 +642,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
||||||
static void checkSizes (lua_State *L) {
|
static void checkSizes (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int hs = g->strt.size / 2; /* half the size of the string table */
|
int hs = g->strt.size / 2; /* half the size of the string table */
|
||||||
|
if (g->gcstate == KGC_EMERGENCY) return;
|
||||||
if (g->strt.nuse < cast(lu_int32, hs)) { /* using less than half its size? */
|
if (g->strt.nuse < cast(lu_int32, hs)) { /* using less than half its size? */
|
||||||
luaS_resize(L, hs); /* halve its size */
|
luaS_resize(L, hs); /* halve its size */
|
||||||
}
|
}
|
||||||
|
@ -755,10 +755,18 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) {
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** call all pending finalizers */
|
||||||
|
static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
|
||||||
|
global_State *g = G(L);
|
||||||
|
while (g->tobefnz) GCTM(L, propagateerrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaC_freeallobjects (lua_State *L) {
|
void luaC_freeallobjects (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int i;
|
int i;
|
||||||
while (g->tobefnz) GCTM(L, 0); /* Call all pending finalizers */
|
callallpendingfinalizers(L, 0);
|
||||||
/* following "white" makes all objects look dead */
|
/* following "white" makes all objects look dead */
|
||||||
g->currentwhite = WHITEBITS;
|
g->currentwhite = WHITEBITS;
|
||||||
sweepwholelist(L, &g->udgc);
|
sweepwholelist(L, &g->udgc);
|
||||||
|
@ -795,7 +803,7 @@ static void atomic (lua_State *L) {
|
||||||
cleartable(g->weak);
|
cleartable(g->weak);
|
||||||
cleartable(g->ephemeron);
|
cleartable(g->ephemeron);
|
||||||
cleartable(g->allweak);
|
cleartable(g->allweak);
|
||||||
lua_checkmemory(L);
|
/*lua_checkmemory(L);*/
|
||||||
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
|
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,19 +858,9 @@ static l_mem singlestep (lua_State *L) {
|
||||||
else {
|
else {
|
||||||
/* sweep main thread */
|
/* sweep main thread */
|
||||||
sweeplist(L, cast(GCObject **, &g->mainthread), 1);
|
sweeplist(L, cast(GCObject **, &g->mainthread), 1);
|
||||||
g->gcstate = GCSfinalize; /* go to next phase */
|
|
||||||
return GCSWEEPCOST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case GCSfinalize: {
|
|
||||||
if (g->tobefnz) {
|
|
||||||
GCTM(L, 1);
|
|
||||||
return GCFINALIZECOST;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
checkSizes(L);
|
checkSizes(L);
|
||||||
g->gcstate = GCSpause; /* end collection */
|
g->gcstate = GCSpause; /* finish collection */
|
||||||
return 0;
|
return GCSWEEPCOST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: lua_assert(0); return 0;
|
default: lua_assert(0); return 0;
|
||||||
|
@ -913,8 +911,11 @@ static void step (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
void luaC_step (lua_State *L) {
|
void luaC_step (lua_State *L) {
|
||||||
|
int i;
|
||||||
if (G(L)->gckind == KGC_GEN) generationalcollection(L);
|
if (G(L)->gckind == KGC_GEN) generationalcollection(L);
|
||||||
else step(L);
|
else step(L);
|
||||||
|
for (i = 0; i < GCFINALIZENUM && G(L)->tobefnz; i++)
|
||||||
|
GCTM(L, 1); /* Call a few pending finalizers */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -926,6 +927,8 @@ void luaC_fullgc (lua_State *L, int isemergency) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int origkind = g->gckind;
|
int origkind = g->gckind;
|
||||||
lua_assert(origkind == KGC_NORMAL || origkind == KGC_GEN);
|
lua_assert(origkind == KGC_NORMAL || origkind == KGC_GEN);
|
||||||
|
if (!isemergency) /* do not run finalizers during emergency GC */
|
||||||
|
callallpendingfinalizers(L, 1);
|
||||||
g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED;
|
g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED;
|
||||||
if (g->gcstate == GCSpropagate) { /* marking phase? */
|
if (g->gcstate == GCSpropagate) { /* marking phase? */
|
||||||
/* must sweep all objects to turn them back to white
|
/* must sweep all objects to turn them back to white
|
||||||
|
@ -934,16 +937,16 @@ void luaC_fullgc (lua_State *L, int isemergency) {
|
||||||
g->gcstate = GCSsweepstring;
|
g->gcstate = GCSsweepstring;
|
||||||
}
|
}
|
||||||
/* finish any pending sweep phase */
|
/* finish any pending sweep phase */
|
||||||
luaC_runtilstate(L, bit2mask(GCSpause, GCSfinalize));
|
luaC_runtilstate(L, bitmask(GCSpause));
|
||||||
g->gcstate = GCSpause; /* start a new collection */
|
/* run entire collector */
|
||||||
/* run collector up to finalizers */
|
luaC_runtilstate(L, ~bitmask(GCSpause));
|
||||||
luaC_runtilstate(L, bitmask(GCSfinalize));
|
luaC_runtilstate(L, bitmask(GCSpause));
|
||||||
g->gckind = origkind;
|
g->gckind = origkind;
|
||||||
if (!isemergency) /* do not run finalizers during emergency GC */
|
if (!isemergency) /* do not run finalizers during emergency GC */
|
||||||
luaC_runtilstate(L, bitmask(GCSpause));
|
callallpendingfinalizers(L, 1);
|
||||||
if (origkind == KGC_GEN) { /* generational mode? */
|
if (origkind == KGC_GEN) { /* generational mode? */
|
||||||
g->gcstate = GCSpause; /* collector must be always in... */
|
/* collector must be always in propagate phase */
|
||||||
luaC_runtilstate(L, bitmask(GCSpropagate)); /* ...propagate phase */
|
luaC_runtilstate(L, bitmask(GCSpropagate));
|
||||||
}
|
}
|
||||||
g->GCdebt = stddebt(g);
|
g->GCdebt = stddebt(g);
|
||||||
}
|
}
|
||||||
|
|
5
lgc.h
5
lgc.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lgc.h,v 2.33 2010/04/30 18:36:45 roberto Exp roberto $
|
** $Id: lgc.h,v 2.34 2010/05/03 11:24:30 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -33,8 +33,7 @@
|
||||||
#define GCSsweepstring 2
|
#define GCSsweepstring 2
|
||||||
#define GCSsweepudata 3
|
#define GCSsweepudata 3
|
||||||
#define GCSsweep 4
|
#define GCSsweep 4
|
||||||
#define GCSfinalize 5
|
#define GCSpause 5
|
||||||
#define GCSpause 6
|
|
||||||
|
|
||||||
|
|
||||||
#define issweepphase(g) \
|
#define issweepphase(g) \
|
||||||
|
|
6
ltests.c
6
ltests.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 2.99 2010/04/30 18:37:14 roberto Exp roberto $
|
** $Id: ltests.c,v 2.100 2010/05/03 11:55:40 roberto Exp roberto $
|
||||||
** Internal Module for Debugging of the Lua Implementation
|
** Internal Module for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -580,9 +580,9 @@ static int get_gccolor (lua_State *L) {
|
||||||
|
|
||||||
static int gc_state (lua_State *L) {
|
static int gc_state (lua_State *L) {
|
||||||
static const char *statenames[] = {"", "pause", "propagate", "atomic",
|
static const char *statenames[] = {"", "pause", "propagate", "atomic",
|
||||||
"sweepstring", "sweepudata", "sweep", "finalize"};
|
"sweepstring", "sweepudata", "sweep"};
|
||||||
static const int states[] = {0, GCSpause, GCSpropagate, GCSatomic,
|
static const int states[] = {0, GCSpause, GCSpropagate, GCSatomic,
|
||||||
GCSsweepstring, GCSsweepudata, GCSsweep, GCSfinalize};
|
GCSsweepstring, GCSsweepudata, GCSsweep};
|
||||||
int option = luaL_checkoption(L, 1, "", statenames);
|
int option = luaL_checkoption(L, 1, "", statenames);
|
||||||
if (option == 0) {
|
if (option == 0) {
|
||||||
lua_pushstring(L, statenames[G(L)->gcstate]);
|
lua_pushstring(L, statenames[G(L)->gcstate]);
|
||||||
|
|
Loading…
Reference in New Issue