mirror of https://github.com/rusefi/lua.git
cleaner way to free all objects
This commit is contained in:
parent
0e60572606
commit
4df8800a01
6
lfunc.c
6
lfunc.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $
|
** $Id: lfunc.c,v 2.7 2005/01/19 15:54:26 roberto Exp roberto $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +57,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
|
||||||
while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
|
while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
|
||||||
lua_assert(p->v != &p->u.value);
|
lua_assert(p->v != &p->u.value);
|
||||||
if (p->v == level) { /* found a corresponding upvalue? */
|
if (p->v == level) { /* found a corresponding upvalue? */
|
||||||
if (isdead(G(L), obj2gco(p))) /* is it dead? */
|
if (isdead(g, obj2gco(p))) /* is it dead? */
|
||||||
changewhite(obj2gco(p)); /* ressurect it */
|
changewhite(obj2gco(p)); /* ressurect it */
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ void luaF_close (lua_State *L, StkId level) {
|
||||||
setobj(L, &uv->u.value, uv->v);
|
setobj(L, &uv->u.value, uv->v);
|
||||||
if (isgray(o)) {
|
if (isgray(o)) {
|
||||||
gray2black(o); /* closed upvalues are never gray */
|
gray2black(o); /* closed upvalues are never gray */
|
||||||
luaC_barrier(L, uv, uv->v);
|
luaC_barrier(L, uv, &uv->u.value);
|
||||||
}
|
}
|
||||||
uv->v = &uv->u.value; /* now current value lives here */
|
uv->v = &uv->u.value; /* now current value lives here */
|
||||||
luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
|
luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
|
||||||
|
|
54
lgc.c
54
lgc.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.21 2005/01/14 14:19:42 roberto Exp $
|
** $Id: lgc.c,v 2.22 2005/01/18 17:18:09 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -29,13 +29,11 @@
|
||||||
#define GCFINALIZECOST 100
|
#define GCFINALIZECOST 100
|
||||||
|
|
||||||
|
|
||||||
#define FIXEDMASK bitmask(FIXEDBIT)
|
|
||||||
|
|
||||||
#define maskmarks \
|
#define maskmarks \
|
||||||
cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT)))
|
cast(lu_byte, ~(bitmask(BLACKBIT)|WHITEBITS))
|
||||||
|
|
||||||
#define makewhite(g,x) \
|
#define makewhite(g,x) \
|
||||||
((x)->gch.marked = ((x)->gch.marked & maskmarks) | g->currentwhite)
|
((x)->gch.marked = ((x)->gch.marked & maskmarks) | luaC_white(g))
|
||||||
|
|
||||||
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
|
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
|
||||||
#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
|
#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
|
||||||
|
@ -60,6 +58,8 @@
|
||||||
reallymarkobject(g, obj2gco(t)); }
|
reallymarkobject(g, obj2gco(t)); }
|
||||||
|
|
||||||
|
|
||||||
|
#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpace)
|
||||||
|
|
||||||
|
|
||||||
static void removeentry (Node *n) {
|
static void removeentry (Node *n) {
|
||||||
lua_assert(ttisnil(gval(n)));
|
lua_assert(ttisnil(gval(n)));
|
||||||
|
@ -400,24 +400,23 @@ static void freeobj (lua_State *L, GCObject *o) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define sweepwholelist(L,p) sweeplist(L,p,LUA_MAXINT32)
|
#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
|
||||||
|
|
||||||
|
|
||||||
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
|
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
||||||
GCObject *curr;
|
GCObject *curr;
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int whitebit = otherwhite(g);
|
int deadmask = otherwhite(g);
|
||||||
int deadmask = whitebit | FIXEDMASK;
|
|
||||||
while ((curr = *p) != NULL && count-- > 0) {
|
while ((curr = *p) != NULL && count-- > 0) {
|
||||||
if ((curr->gch.marked ^ whitebit) & deadmask) {
|
if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
|
||||||
|
sweepwholelist(L, &gco2th(curr)->openupval);
|
||||||
|
if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
|
||||||
lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
|
lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
|
||||||
makewhite(g, curr);
|
makewhite(g, curr); /* make it white (for next cycle) */
|
||||||
if (curr->gch.tt == LUA_TTHREAD)
|
|
||||||
sweepwholelist(L, &gco2th(curr)->openupval);
|
|
||||||
p = &curr->gch.next;
|
p = &curr->gch.next;
|
||||||
}
|
}
|
||||||
else {
|
else { /* must erase `curr' */
|
||||||
lua_assert(isdead(g, curr));
|
lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
|
||||||
*p = curr->gch.next;
|
*p = curr->gch.next;
|
||||||
if (curr == g->rootgc) /* is the first element of the list? */
|
if (curr == g->rootgc) /* is the first element of the list? */
|
||||||
g->rootgc = curr->gch.next; /* adjust first */
|
g->rootgc = curr->gch.next; /* adjust first */
|
||||||
|
@ -428,21 +427,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void freelist (lua_State *L, GCObject **p) {
|
|
||||||
while (*p) {
|
|
||||||
GCObject *curr = *p;
|
|
||||||
*p = (*p)->gch.next;
|
|
||||||
if (curr != obj2gco(L))
|
|
||||||
freeobj(L, curr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void checkSizes (lua_State *L) {
|
static void checkSizes (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
/* check size of string hash */
|
/* check size of string hash */
|
||||||
if (g->strt.nuse < cast(lu_int32, G(L)->strt.size/4) &&
|
if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
|
||||||
g->strt.size > MINSTRTABSIZE*2)
|
g->strt.size > MINSTRTABSIZE*2)
|
||||||
luaS_resize(L, g->strt.size/2); /* table is too big */
|
luaS_resize(L, g->strt.size/2); /* table is too big */
|
||||||
/* check size of buffer */
|
/* check size of buffer */
|
||||||
|
@ -487,9 +475,10 @@ void luaC_callGCTM (lua_State *L) {
|
||||||
void luaC_freeall (lua_State *L) {
|
void luaC_freeall (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
int i;
|
int i;
|
||||||
freelist(L, &g->rootgc);
|
g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
|
||||||
|
sweepwholelist(L, &g->rootgc);
|
||||||
for (i = 0; i < g->strt.size; i++) /* free all string lists */
|
for (i = 0; i < g->strt.size; i++) /* free all string lists */
|
||||||
freelist(L, &G(L)->strt.hash[i]);
|
sweepwholelist(L, &g->strt.hash[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,6 +593,8 @@ static l_mem singlestep (lua_State *L) {
|
||||||
void luaC_step (lua_State *L) {
|
void luaC_step (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
|
l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
|
||||||
|
if (lim == 0)
|
||||||
|
lim = (MAX_LUMEM-1)/2; /* no limit */
|
||||||
g->gcdept += g->totalbytes - g->GCthreshold;
|
g->gcdept += g->totalbytes - g->GCthreshold;
|
||||||
do {
|
do {
|
||||||
lim -= singlestep(L);
|
lim -= singlestep(L);
|
||||||
|
@ -620,7 +611,7 @@ void luaC_step (lua_State *L) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_assert(g->totalbytes >= g->estimate);
|
lua_assert(g->totalbytes >= g->estimate);
|
||||||
g->GCthreshold = (g->estimate/100) * g->gcpace;
|
setthreshold(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,6 +628,7 @@ void luaC_fullgc (lua_State *L) {
|
||||||
g->weak = NULL;
|
g->weak = NULL;
|
||||||
g->gcstate = GCSsweepstring;
|
g->gcstate = GCSsweepstring;
|
||||||
}
|
}
|
||||||
|
lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
|
||||||
/* finish any pending sweep phase */
|
/* finish any pending sweep phase */
|
||||||
while (g->gcstate != GCSfinalize) {
|
while (g->gcstate != GCSfinalize) {
|
||||||
lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
|
lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
|
||||||
|
@ -646,7 +638,7 @@ void luaC_fullgc (lua_State *L) {
|
||||||
while (g->gcstate != GCSpause) {
|
while (g->gcstate != GCSpause) {
|
||||||
singlestep(L);
|
singlestep(L);
|
||||||
}
|
}
|
||||||
g->GCthreshold = 2*g->estimate;
|
setthreshold(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
14
lgc.h
14
lgc.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lgc.h,v 2.9 2004/09/15 20:38:15 roberto Exp $
|
** $Id: lgc.h,v 2.10 2005/01/19 15:54:26 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -47,8 +47,10 @@
|
||||||
** bit 3 - for tables: has weak keys
|
** bit 3 - for tables: has weak keys
|
||||||
** bit 4 - for tables: has weak values
|
** bit 4 - for tables: has weak values
|
||||||
** bit 5 - object is fixed (should not be collected)
|
** bit 5 - object is fixed (should not be collected)
|
||||||
|
** bit 6 - object is "super" fixed (only the main thread)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define WHITE0BIT 0
|
#define WHITE0BIT 0
|
||||||
#define WHITE1BIT 1
|
#define WHITE1BIT 1
|
||||||
#define BLACKBIT 2
|
#define BLACKBIT 2
|
||||||
|
@ -56,21 +58,23 @@
|
||||||
#define KEYWEAKBIT 3
|
#define KEYWEAKBIT 3
|
||||||
#define VALUEWEAKBIT 4
|
#define VALUEWEAKBIT 4
|
||||||
#define FIXEDBIT 5
|
#define FIXEDBIT 5
|
||||||
|
#define SFIXEDBIT 6
|
||||||
|
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
|
||||||
|
|
||||||
|
|
||||||
#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
|
#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
|
||||||
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
|
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
|
||||||
#define isgray(x) (!isblack(x) && !iswhite(x))
|
#define isgray(x) (!isblack(x) && !iswhite(x))
|
||||||
|
|
||||||
#define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT))
|
#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
|
||||||
#define isdead(g,v) ((v)->gch.marked & otherwhite(g))
|
#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
|
||||||
|
|
||||||
#define changewhite(x) ((x)->gch.marked ^= bit2mask(WHITE0BIT, WHITE1BIT))
|
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
|
||||||
#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
|
#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
|
||||||
|
|
||||||
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
|
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
|
||||||
|
|
||||||
#define luaC_white(g) cast(lu_byte, (g)->currentwhite)
|
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
|
||||||
|
|
||||||
|
|
||||||
#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
|
#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
|
||||||
|
|
9
lstate.c
9
lstate.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 2.22 2005/01/14 14:19:42 roberto Exp $
|
** $Id: lstate.c,v 2.23 2005/01/18 17:18:09 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -114,7 +114,7 @@ static void close_state (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
luaF_close(L, L->stack); /* close all upvalues for this thread */
|
luaF_close(L, L->stack); /* close all upvalues for this thread */
|
||||||
luaC_freeall(L); /* collect all objects */
|
luaC_freeall(L); /* collect all objects */
|
||||||
lua_assert(g->rootgc == NULL);
|
lua_assert(g->rootgc == obj2gco(L));
|
||||||
lua_assert(g->strt.nuse == 0);
|
lua_assert(g->strt.nuse == 0);
|
||||||
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
|
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
|
||||||
luaZ_freebuffer(L, &g->buff);
|
luaZ_freebuffer(L, &g->buff);
|
||||||
|
@ -156,8 +156,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||||
g = &((LG *)L)->g;
|
g = &((LG *)L)->g;
|
||||||
L->next = NULL;
|
L->next = NULL;
|
||||||
L->tt = LUA_TTHREAD;
|
L->tt = LUA_TTHREAD;
|
||||||
L->marked = g->currentwhite = bitmask(WHITE0BIT);
|
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
|
||||||
setbit(L->marked, FIXEDBIT);
|
L->marked = luaC_white(g);
|
||||||
|
set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
|
||||||
preinit_state(L, g);
|
preinit_state(L, g);
|
||||||
g->realloc = f;
|
g->realloc = f;
|
||||||
g->ud = ud;
|
g->ud = ud;
|
||||||
|
|
Loading…
Reference in New Issue