summaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-10-25 17:14:14 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-10-25 17:14:14 -0200
commit21aa7e55f2333e57b972aa4ef2c5e2785d609578 (patch)
treebdd6119f0fab0178979202bc5d0afbd6f4410469 /lgc.c
parentfffb6f3814084cddd8a58e81ae1b73ed78ea0953 (diff)
downloadlua-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.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/lgc.c b/lgc.c
index 35251ce3..cf9148e9 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
23typedef struct GCState { 23typedef 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
79static void marktable (GCState *st, Hash *h) { 79static 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
148static void traversetable (GCState *st, Hash *h) { 148static 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
199static void cleardeadnodes (Hash *h) { 201static 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
212static void cleartables (global_State *G) { 220static 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
262static void collecttable (lua_State *L) { 270static 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