diff options
Diffstat (limited to '')
| -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 | ||
