summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-04 16:52:23 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-04 16:52:23 -0200
commitfe595a45c246faf2cf12084e7aac4b772f8f72da (patch)
tree1f2c3b54cf225f90ef4d3010c8861173d8620810
parent9db1942bac5fb509c6e46ccc825351a6be546792 (diff)
downloadlua-github-fe595a45c246faf2cf12084e7aac4b772f8f72da.tar.gz
`grayagain' list
-rw-r--r--lgc.c16
-rw-r--r--lstate.c3
-rw-r--r--lstate.h3
3 files changed, 19 insertions, 3 deletions
diff --git a/lgc.c b/lgc.c
index c0ebef05..ff52fa2c 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 1.184 2003/12/03 20:03:07 roberto Exp roberto $
+** $Id: lgc.c,v 1.185 2003/12/04 17:22:42 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -38,6 +38,7 @@
#define isgray(x) (!isblack(x) && !iswhite(x))
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
+#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
@@ -323,6 +324,9 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
case LUA_TTHREAD: {
lua_State *th = gcototh(o);
g->gray = th->gclist;
+ th->gclist = g->grayagain;
+ g->grayagain = o;
+ black2gray(o);
traversestack(g, th);
break;
}
@@ -335,6 +339,11 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
case LUA_TUPVAL: {
UpVal *uv = gcotouv(o);
g->gray = uv->gclist;
+ if (uv->v != &uv->value) { /* open? */
+ uv->gclist = g->grayagain;
+ g->grayagain = o;
+ black2gray(o);
+ }
markvalue(g, &uv->value);
break;
}
@@ -553,6 +562,10 @@ static void markroot (lua_State *L) {
static void atomic (lua_State *L) {
global_State *g = G(L);
+ lua_assert(g->gray == NULL);
+ g->gray = g->grayagain;
+ g->grayagain = NULL;
+ propagatemarks(g, MAXLMEM);
g->GCthreshold = luaC_separateudata(L); /* separate userdata to be preserved */
marktmu(g); /* mark `preserved' userdata */
propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */
@@ -565,6 +578,7 @@ static void atomic (lua_State *L) {
g->sweepgc = &g->rootgc->gch.next;
g->sweepstrgc = 0;
g->gcstate = GCSsweepstring;
+ g->grayagain = NULL;
}
diff --git a/lstate.c b/lstate.c
index b52ff66d..e59f1a18 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 1.132 2003/12/03 20:03:07 roberto Exp roberto $
+** $Id: lstate.c,v 1.133 2003/12/04 17:22:42 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -172,6 +172,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->currentwhite = bitmask(WHITE0BIT);
g->firstudata = NULL;
g->gray = NULL;
+ g->grayagain = NULL;
g->weak = NULL;
g->tmudata = NULL;
setnilvalue(gkey(g->dummynode));
diff --git a/lstate.h b/lstate.h
index c44828b6..4a3ea577 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 1.117 2003/12/03 20:03:07 roberto Exp roberto $
+** $Id: lstate.h,v 1.118 2003/12/04 17:22:42 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -103,6 +103,7 @@ typedef struct global_State {
GCObject **sweepgc; /* position of sweep in `rootgc' */
int sweepstrgc; /* position of sweep in `strt' */
GCObject *gray; /* list of gray objects */
+ GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of weak tables (to be cleared) */
GCObject *tmudata; /* list of userdata to be GC */
int gcstate; /* state of garbage collector */