aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-26 11:18:00 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-26 11:18:00 -0200
commit7959f3aebb5b12f474b65429dedf550b28223e08 (patch)
tree206746f154ef0e211b3ce5f74bf7d9fb241d47c5
parentbce6572579a7e6c7a96895d9280396b3b33b8f3f (diff)
downloadlua-7959f3aebb5b12f474b65429dedf550b28223e08.tar.gz
lua-7959f3aebb5b12f474b65429dedf550b28223e08.tar.bz2
lua-7959f3aebb5b12f474b65429dedf550b28223e08.zip
easier way to erase 'dead' keys
-rw-r--r--lgc.c40
-rw-r--r--ltable.c28
-rw-r--r--ltable.h3
3 files changed, 29 insertions, 42 deletions
diff --git a/lgc.c b/lgc.c
index 0c84da8f..189adc6a 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.78 2001/01/22 18:01:38 roberto Exp roberto $ 2** $Id: lgc.c,v 1.79 2001/01/25 16:45:36 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -121,6 +121,29 @@ static void marktagmethods (global_State *G, GCState *st) {
121} 121}
122 122
123 123
124static void traverseclosure (GCState *st, Closure *f) {
125 int i;
126 for (i=0; i<f->nupvalues; i++) /* mark its upvalues */
127 markobject(st, &f->upvalue[i]);
128}
129
130
131static void traversetable (GCState *st, Hash *h) {
132 int i;
133 for (i=0; i<h->size; i++) {
134 Node *n = node(h, i);
135 if (ttype(val(n)) == LUA_TNIL) {
136 if (ttype(key(n)) != LUA_TNIL)
137 sethvalue(key(n), NULL); /* dead key; remove it */
138 }
139 else {
140 markobject(st, &n->key);
141 markobject(st, &n->val);
142 }
143 }
144}
145
146
124static void markall (lua_State *L) { 147static void markall (lua_State *L) {
125 GCState st; 148 GCState st;
126 st.cmark = NULL; 149 st.cmark = NULL;
@@ -131,25 +154,14 @@ static void markall (lua_State *L) {
131 marktable(&st, G(L)->type2tag); 154 marktable(&st, G(L)->type2tag);
132 for (;;) { /* mark tables and closures */ 155 for (;;) { /* mark tables and closures */
133 if (st.cmark) { 156 if (st.cmark) {
134 int i;
135 Closure *f = st.cmark; /* get first closure from list */ 157 Closure *f = st.cmark; /* get first closure from list */
136 st.cmark = f->mark; /* remove it from list */ 158 st.cmark = f->mark; /* remove it from list */
137 for (i=0; i<f->nupvalues; i++) /* mark its upvalues */ 159 traverseclosure(&st, f);
138 markobject(&st, &f->upvalue[i]);
139 } 160 }
140 else if (st.tmark) { 161 else if (st.tmark) {
141 int i;
142 Hash *h = st.tmark; /* get first table from list */ 162 Hash *h = st.tmark; /* get first table from list */
143 st.tmark = h->mark; /* remove it from list */ 163 st.tmark = h->mark; /* remove it from list */
144 for (i=0; i<h->size; i++) { 164 traversetable(&st, h);
145 Node *n = node(h, i);
146 if (ttype(key(n)) != LUA_TNIL) {
147 if (ttype(val(n)) == LUA_TNIL)
148 luaH_remove(h, key(n)); /* dead element; try to remove it */
149 markobject(&st, &n->key);
150 markobject(&st, &n->val);
151 }
152 }
153 } 165 }
154 else break; /* nothing else to mark */ 166 else break; /* nothing else to mark */
155 } 167 }
diff --git a/ltable.c b/ltable.c
index 926fb49e..a13e8c24 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.66 2001/01/24 15:45:33 roberto Exp roberto $ 2** $Id: ltable.c,v 1.67 2001/01/25 16:45:36 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -126,30 +126,6 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
126} 126}
127 127
128 128
129/*
130** try to remove a key without value from a table. To avoid problems with
131** hash, change `key' for a number with the same hash.
132*/
133void luaH_remove (Hash *t, TObject *key) {
134 if (ttype(key) == LUA_TNUMBER ||
135 (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30))
136 return; /* do not remove numbers nor small strings */
137 else {
138 /* try to find a number `n' with the same hash as `key' */
139 Node *mp = luaH_mainposition(t, key);
140 int n = mp - &t->node[0];
141 /* make sure `n' is not in `t' */
142 while (luaH_getnum(t, n) != &luaO_nilobject) {
143 if (n >= MAX_INT - t->size)
144 return; /* give up; (to avoid overflow) */
145 n += t->size;
146 }
147 setnvalue(key, n);
148 lua_assert(luaH_mainposition(t, key) == mp);
149 }
150}
151
152
153static void setnodevector (lua_State *L, Hash *t, luint32 size) { 129static void setnodevector (lua_State *L, Hash *t, luint32 size) {
154 int i; 130 int i;
155 if (size > MAX_INT) 131 if (size > MAX_INT)
@@ -227,7 +203,7 @@ static void rehash (lua_State *L, Hash *t) {
227** position), new key goes to an empty position. 203** position), new key goes to an empty position.
228*/ 204*/
229static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) { 205static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) {
230 if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */ 206 if (ttype(&mp->val) != LUA_TNIL) { /* main position is not free? */
231 Node *othern = luaH_mainposition(t, &mp->key); /* `mp' of colliding node */ 207 Node *othern = luaH_mainposition(t, &mp->key); /* `mp' of colliding node */
232 Node *n = t->firstfree; /* get a free place */ 208 Node *n = t->firstfree; /* get a free place */
233 if (othern != mp) { /* is colliding node out of its main position? */ 209 if (othern != mp) { /* is colliding node out of its main position? */
diff --git a/ltable.h b/ltable.h
index 6283a2d5..565a8606 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 1.26 2000/12/04 18:33:40 roberto Exp roberto $ 2** $Id: ltable.h,v 1.27 2001/01/10 18:56:11 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,7 +19,6 @@ void luaH_free (lua_State *L, Hash *t);
19const TObject *luaH_get (const Hash *t, const TObject *key); 19const TObject *luaH_get (const Hash *t, const TObject *key);
20const TObject *luaH_getnum (const Hash *t, lua_Number key); 20const TObject *luaH_getnum (const Hash *t, lua_Number key);
21const TObject *luaH_getstr (const Hash *t, TString *key); 21const TObject *luaH_getstr (const Hash *t, TString *key);
22void luaH_remove (Hash *t, TObject *key);
23TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); 22TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
24Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); 23Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
25TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); 24TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);