diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-25 17:14:14 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-25 17:14:14 -0200 |
commit | 21aa7e55f2333e57b972aa4ef2c5e2785d609578 (patch) | |
tree | bdd6119f0fab0178979202bc5d0afbd6f4410469 /lgc.c | |
parent | fffb6f3814084cddd8a58e81ae1b73ed78ea0953 (diff) | |
download | lua-21aa7e55f2333e57b972aa4ef2c5e2785d609578.tar.gz lua-21aa7e55f2333e57b972aa4ef2c5e2785d609578.tar.bz2 lua-21aa7e55f2333e57b972aa4ef2c5e2785d609578.zip |
optimization for array part of a Table
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 50 |
1 files changed, 29 insertions, 21 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.112 2001/10/02 16:45:03 roberto Exp $ | 2 | ** $Id: lgc.c,v 1.113 2001/10/17 21:12:57 roberto Exp $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | 22 | ||
23 | typedef struct GCState { | 23 | typedef struct GCState { |
24 | Hash *tmark; /* list of marked tables to be visited */ | 24 | Table *tmark; /* list of marked tables to be visited */ |
25 | } GCState; | 25 | } GCState; |
26 | 26 | ||
27 | 27 | ||
@@ -76,7 +76,7 @@ static void markclosure (GCState *st, Closure *cl) { | |||
76 | } | 76 | } |
77 | 77 | ||
78 | 78 | ||
79 | static void marktable (GCState *st, Hash *h) { | 79 | static void marktable (GCState *st, Table *h) { |
80 | if (!ismarked(h)) { | 80 | if (!ismarked(h)) { |
81 | h->mark = st->tmark; /* chain it for later traversal */ | 81 | h->mark = st->tmark; /* chain it for later traversal */ |
82 | st->tmark = h; | 82 | st->tmark = h; |
@@ -145,18 +145,20 @@ static void removekey (Node *n) { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | 147 | ||
148 | static void traversetable (GCState *st, Hash *h) { | 148 | static void traversetable (GCState *st, Table *h) { |
149 | int i; | 149 | int i; |
150 | int mode = h->weakmode; | 150 | int mode = h->weakmode; |
151 | if (mode == (LUA_WEAK_KEY | LUA_WEAK_VALUE)) | 151 | if (!(mode & LUA_WEAK_VALUE)) { |
152 | return; /* avoid traversing if both keys and values are weak */ | 152 | i = sizearray(h); |
153 | for (i=0; i<h->size; i++) { | 153 | while (i--) |
154 | markobject(st, &h->array[i]); | ||
155 | } | ||
156 | i = sizenode(h); | ||
157 | while (i--) { | ||
154 | Node *n = node(h, i); | 158 | Node *n = node(h, i); |
155 | if (ttype(val(n)) == LUA_TNIL) | 159 | if (ttype(val(n)) != LUA_TNIL) { |
156 | removekey(n); | ||
157 | else { | ||
158 | lua_assert(ttype(key(n)) != LUA_TNIL); | 160 | lua_assert(ttype(key(n)) != LUA_TNIL); |
159 | if (ttype(key(n)) != LUA_TNUMBER && !(mode & LUA_WEAK_KEY)) | 161 | if (!(mode & LUA_WEAK_KEY)) |
160 | markobject(st, key(n)); | 162 | markobject(st, key(n)); |
161 | if (!(mode & LUA_WEAK_VALUE)) | 163 | if (!(mode & LUA_WEAK_VALUE)) |
162 | markobject(st, val(n)); | 164 | markobject(st, val(n)); |
@@ -173,7 +175,7 @@ static void markall (lua_State *L) { | |||
173 | marktable(&st, G(L)->type2tag); | 175 | marktable(&st, G(L)->type2tag); |
174 | markobject(&st, &G(L)->registry); | 176 | markobject(&st, &G(L)->registry); |
175 | while (st.tmark) { /* mark tables */ | 177 | while (st.tmark) { /* mark tables */ |
176 | Hash *h = st.tmark; /* get first table from list */ | 178 | Table *h = st.tmark; /* get first table from list */ |
177 | st.tmark = h->mark; /* remove it from list */ | 179 | st.tmark = h->mark; /* remove it from list */ |
178 | traversetable(&st, h); | 180 | traversetable(&st, h); |
179 | } | 181 | } |
@@ -196,21 +198,27 @@ static int hasmark (const TObject *o) { | |||
196 | } | 198 | } |
197 | 199 | ||
198 | 200 | ||
199 | static void cleardeadnodes (Hash *h) { | 201 | static void cleardeadnodes (Table *h) { |
200 | int i; | 202 | int i; |
201 | for (i=0; i<h->size; i++) { | 203 | i = sizearray(h); |
204 | while (i--) { | ||
205 | TObject *o = &h->array[i]; | ||
206 | if (!hasmark(o)) | ||
207 | setnilvalue(o); /* remove value */ | ||
208 | } | ||
209 | i = sizenode(h); | ||
210 | while (i--) { | ||
202 | Node *n = node(h, i); | 211 | Node *n = node(h, i); |
203 | if (ttype(val(n)) == LUA_TNIL) continue; /* empty node */ | ||
204 | if (!hasmark(val(n)) || !hasmark(key(n))) { | 212 | if (!hasmark(val(n)) || !hasmark(key(n))) { |
205 | setnilvalue(val(n)); /* remove value */ | 213 | setnilvalue(val(n)); /* remove value ... */ |
206 | removekey(n); | 214 | removekey(n); /* ... and key */ |
207 | } | 215 | } |
208 | } | 216 | } |
209 | } | 217 | } |
210 | 218 | ||
211 | 219 | ||
212 | static void cleartables (global_State *G) { | 220 | static void cleartables (global_State *G) { |
213 | Hash *h; | 221 | Table *h; |
214 | for (h = G->roottable; h; h = h->next) { | 222 | for (h = G->roottable; h; h = h->next) { |
215 | if (h->weakmode && ismarked(h)) | 223 | if (h->weakmode && ismarked(h)) |
216 | cleardeadnodes(h); | 224 | cleardeadnodes(h); |
@@ -260,8 +268,8 @@ static void collectclosures (lua_State *L) { | |||
260 | 268 | ||
261 | 269 | ||
262 | static void collecttable (lua_State *L) { | 270 | static void collecttable (lua_State *L) { |
263 | Hash **p = &G(L)->roottable; | 271 | Table **p = &G(L)->roottable; |
264 | Hash *curr; | 272 | Table *curr; |
265 | while ((curr = *p) != NULL) { | 273 | while ((curr = *p) != NULL) { |
266 | if (ismarked(curr)) { | 274 | if (ismarked(curr)) { |
267 | curr->mark = curr; /* unmark */ | 275 | curr->mark = curr; /* unmark */ |
@@ -333,7 +341,7 @@ static void collectstrings (lua_State *L, int all) { | |||
333 | } | 341 | } |
334 | } | 342 | } |
335 | if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && | 343 | if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && |
336 | G(L)->strt.size > MINPOWER2) | 344 | G(L)->strt.size > 4) |
337 | luaS_resize(L, G(L)->strt.size/2); /* table is too big */ | 345 | luaS_resize(L, G(L)->strt.size/2); /* table is too big */ |
338 | } | 346 | } |
339 | 347 | ||