thead-specific state separated from "global" state

This commit is contained in:
Roberto Ierusalimschy
2001-01-19 11:20:30 -02:00
parent f2c451d745
commit 4ac58853dc
19 changed files with 268 additions and 257 deletions

85
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.75 2000/12/28 12:55:41 roberto Exp roberto $
** $Id: lgc.c,v 1.76 2001/01/18 15:59:09 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -54,11 +54,11 @@ static void markstack (lua_State *L, GCState *st) {
}
static void marklock (lua_State *L, GCState *st) {
static void marklock (global_State *G, GCState *st) {
int i;
for (i=0; i<L->nref; i++) {
if (L->refArray[i].st == LOCK)
markobject(st, &L->refArray[i].o);
for (i=0; i<G->nref; i++) {
if (G->refArray[i].st == LOCK)
markobject(st, &G->refArray[i].o);
}
}
@@ -73,12 +73,12 @@ static void markclosure (GCState *st, Closure *cl) {
}
static void marktagmethods (lua_State *L, GCState *st) {
static void marktagmethods (global_State *G, GCState *st) {
int e;
for (e=0; e<TM_N; e++) {
int t;
for (t=0; t<L->ntag; t++) {
Closure *cl = luaT_gettm(L, t, e);
for (t=0; t<G->ntag; t++) {
Closure *cl = luaT_gettm(G, t, e);
if (cl) markclosure(st, cl);
}
}
@@ -113,9 +113,9 @@ static void markall (lua_State *L) {
st.cmark = NULL;
st.tmark = L->gt; /* put table of globals in mark list */
L->gt->mark = NULL;
marktagmethods(L, &st); /* mark tag methods */
marktagmethods(G(L), &st); /* mark tag methods */
markstack(L, &st); /* mark stack objects */
marklock(L, &st); /* mark locked objects */
marklock(G(L), &st); /* mark locked objects */
for (;;) { /* mark tables and closures */
if (st.cmark) {
int i;
@@ -161,27 +161,26 @@ static int hasmark (const TObject *o) {
/* macro for internal debugging; check if a link of free refs is valid */
#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
static void invalidaterefs (lua_State *L) {
int n = L->nref;
static void invalidaterefs (global_State *G) {
int n = G->nref;
int i;
for (i=0; i<n; i++) {
struct Ref *r = &L->refArray[i];
struct Ref *r = &G->refArray[i];
if (r->st == HOLD && !hasmark(&r->o))
r->st = COLLECTED;
LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
lua_assert((r->st == LOCK && hasmark(&r->o)) ||
(r->st == HOLD && hasmark(&r->o)) ||
r->st == COLLECTED ||
r->st == NONEXT ||
(r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
"inconsistent ref table");
(r->st < n && VALIDLINK(L, G->refArray[r->st].st, n)));
}
LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
lua_assert(VALIDLINK(L, G->refFree, n));
}
static void collectproto (lua_State *L) {
Proto **p = &L->rootproto;
Proto **p = &G(L)->rootproto;
Proto *next;
while ((next = *p) != NULL) {
if (next->marked) {
@@ -197,7 +196,7 @@ static void collectproto (lua_State *L) {
static void collectclosure (lua_State *L) {
Closure **p = &L->rootcl;
Closure **p = &G(L)->rootcl;
Closure *next;
while ((next = *p) != NULL) {
if (ismarked(next)) {
@@ -213,7 +212,7 @@ static void collectclosure (lua_State *L) {
static void collecttable (lua_State *L) {
Hash **p = &L->roottable;
Hash **p = &G(L)->roottable;
Hash *next;
while ((next = *p) != NULL) {
if (ismarked(next)) {
@@ -236,8 +235,8 @@ static void checktab (lua_State *L, stringtable *tb) {
static void collectstrings (lua_State *L, int all) {
int i;
for (i=0; i<L->strt.size; i++) { /* for each list */
TString **p = &L->strt.hash[i];
for (i=0; i<G(L)->strt.size; i++) { /* for each list */
TString **p = &G(L)->strt.hash[i];
TString *next;
while ((next = *p) != NULL) {
if (next->marked && !all) { /* preserve? */
@@ -247,22 +246,22 @@ static void collectstrings (lua_State *L, int all) {
}
else { /* collect */
*p = next->nexthash;
L->strt.nuse--;
G(L)->strt.nuse--;
luaM_free(L, next, sizestring(next->len));
}
}
}
checktab(L, &L->strt);
checktab(L, &G(L)->strt);
}
static void collectudata (lua_State *L, int all) {
int i;
for (i=0; i<L->udt.size; i++) { /* for each list */
TString **p = &L->udt.hash[i];
for (i=0; i<G(L)->udt.size; i++) { /* for each list */
TString **p = &G(L)->udt.hash[i];
TString *next;
while ((next = *p) != NULL) {
LUA_ASSERT(next->marked <= 1, "udata cannot be fixed");
lua_assert(next->marked <= 1);
if (next->marked && !all) { /* preserve? */
next->marked = 0;
p = &next->nexthash;
@@ -270,28 +269,28 @@ static void collectudata (lua_State *L, int all) {
else { /* collect */
int tag = next->u.d.tag;
*p = next->nexthash;
next->nexthash = L->TMtable[tag].collected; /* chain udata */
L->TMtable[tag].collected = next;
L->udt.nuse--;
next->nexthash = G(L)->TMtable[tag].collected; /* chain udata */
G(L)->TMtable[tag].collected = next;
G(L)->udt.nuse--;
}
}
}
checktab(L, &L->udt);
checktab(L, &G(L)->udt);
}
#define MINBUFFER 256
static void checkMbuffer (lua_State *L) {
if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */
luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, newsize, char);
L->Mbuffsize = newsize;
if (G(L)->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
size_t newsize = G(L)->Mbuffsize/2; /* still larger than MINBUFFER */
luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, newsize, char);
G(L)->Mbuffsize = newsize;
}
}
static void callgcTM (lua_State *L, const TObject *obj) {
Closure *tm = luaT_gettmbyObj(L, obj, TM_GC);
Closure *tm = luaT_gettmbyObj(G(L), obj, TM_GC);
if (tm != NULL) {
int oldah = L->allowhooks;
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
@@ -307,12 +306,12 @@ static void callgcTM (lua_State *L, const TObject *obj) {
static void callgcTMudata (lua_State *L) {
int tag;
L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */
for (tag=L->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */
G(L)->GCthreshold = 2*G(L)->nblocks; /* avoid GC during tag methods */
for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */
TString *udata;
while ((udata = L->TMtable[tag].collected) != NULL) {
while ((udata = G(L)->TMtable[tag].collected) != NULL) {
TObject obj;
L->TMtable[tag].collected = udata->nexthash; /* remove it from list */
G(L)->TMtable[tag].collected = udata->nexthash; /* remove it from list */
setuvalue(&obj, udata);
callgcTM(L, &obj);
luaM_free(L, udata, sizeudata(udata->len));
@@ -333,16 +332,16 @@ void luaC_collect (lua_State *L, int all) {
static void luaC_collectgarbage (lua_State *L) {
markall(L);
invalidaterefs(L); /* check unlocked references */
invalidaterefs(G(L)); /* check unlocked references */
luaC_collect(L, 0);
checkMbuffer(L);
L->GCthreshold = 2*L->nblocks; /* set new threshold */
G(L)->GCthreshold = 2*G(L)->nblocks; /* set new threshold */
callgcTM(L, &luaO_nilobject);
}
void luaC_checkGC (lua_State *L) {
if (L->nblocks >= L->GCthreshold)
if (G(L)->nblocks >= G(L)->GCthreshold)
luaC_collectgarbage(L);
}