diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-26 11:18:00 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-26 11:18:00 -0200 |
commit | 7959f3aebb5b12f474b65429dedf550b28223e08 (patch) | |
tree | 206746f154ef0e211b3ce5f74bf7d9fb241d47c5 | |
parent | bce6572579a7e6c7a96895d9280396b3b33b8f3f (diff) | |
download | lua-7959f3aebb5b12f474b65429dedf550b28223e08.tar.gz lua-7959f3aebb5b12f474b65429dedf550b28223e08.tar.bz2 lua-7959f3aebb5b12f474b65429dedf550b28223e08.zip |
easier way to erase 'dead' keys
-rw-r--r-- | lgc.c | 40 | ||||
-rw-r--r-- | ltable.c | 28 | ||||
-rw-r--r-- | ltable.h | 3 |
3 files changed, 29 insertions, 42 deletions
@@ -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 | ||
124 | static 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 | |||
131 | static 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 | |||
124 | static void markall (lua_State *L) { | 147 | static 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 | } |
@@ -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 | */ | ||
133 | void 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 | |||
153 | static void setnodevector (lua_State *L, Hash *t, luint32 size) { | 129 | static 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 | */ |
229 | static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) { | 205 | static 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? */ |
@@ -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); | |||
19 | const TObject *luaH_get (const Hash *t, const TObject *key); | 19 | const TObject *luaH_get (const Hash *t, const TObject *key); |
20 | const TObject *luaH_getnum (const Hash *t, lua_Number key); | 20 | const TObject *luaH_getnum (const Hash *t, lua_Number key); |
21 | const TObject *luaH_getstr (const Hash *t, TString *key); | 21 | const TObject *luaH_getstr (const Hash *t, TString *key); |
22 | void luaH_remove (Hash *t, TObject *key); | ||
23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); | 22 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); |
24 | Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); | 23 | Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); |
25 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); | 24 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); |