diff options
| -rw-r--r-- | lgc.c | 15 | ||||
| -rw-r--r-- | lstate.c | 5 | ||||
| -rw-r--r-- | lstate.h | 3 | ||||
| -rw-r--r-- | ltable.c | 58 |
4 files changed, 46 insertions, 35 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.133 2002/03/26 18:55:50 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.134 2002/04/05 18:54:31 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 | */ |
| @@ -211,14 +211,13 @@ static void traversetable (GCState *st, Table *h) { | |||
| 211 | int weakkey = 0; | 211 | int weakkey = 0; |
| 212 | int weakvalue = 0; | 212 | int weakvalue = 0; |
| 213 | marktable(st, h->metatable); | 213 | marktable(st, h->metatable); |
| 214 | lua_assert(h->lsizenode || h->node == G(st->L)->dummynode); | ||
| 214 | mode = fasttm(st->L, h->metatable, TM_WEAKMODE); | 215 | mode = fasttm(st->L, h->metatable, TM_WEAKMODE); |
| 215 | if (mode) { /* weak table? must be cleared after GC... */ | 216 | if (mode && ttype(mode) == LUA_TSTRING) { /* weak table? */ |
| 216 | h->mark = st->toclear; /* put in the appropriate list */ | 217 | h->mark = st->toclear; /* must be cleared after GC, ... */ |
| 217 | st->toclear = h; | 218 | st->toclear = h; /* ...put in the appropriate list */ |
| 218 | if (ttype(mode) == LUA_TSTRING) { | 219 | weakkey = (strchr(svalue(mode), 'k') != NULL); |
| 219 | weakkey = (strchr(svalue(mode), 'k') != NULL); | 220 | weakvalue = (strchr(svalue(mode), 'v') != NULL); |
| 220 | weakvalue = (strchr(svalue(mode), 'v') != NULL); | ||
| 221 | } | ||
| 222 | } | 221 | } |
| 223 | if (!weakvalue) { | 222 | if (!weakvalue) { |
| 224 | i = sizearray(h); | 223 | i = sizearray(h); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 1.89 2002/04/16 17:08:28 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.90 2002/04/22 14:40:23 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -69,6 +69,9 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 69 | G(L)->rootupval = NULL; | 69 | G(L)->rootupval = NULL; |
| 70 | G(L)->rootudata = NULL; | 70 | G(L)->rootudata = NULL; |
| 71 | G(L)->tmudata = NULL; | 71 | G(L)->tmudata = NULL; |
| 72 | setnilvalue(key(G(L)->dummynode)); | ||
| 73 | setnilvalue(val(G(L)->dummynode)); | ||
| 74 | G(L)->dummynode->next = NULL; | ||
| 72 | G(L)->nblocks = sizeof(lua_State) + sizeof(global_State); | 75 | G(L)->nblocks = sizeof(lua_State) + sizeof(global_State); |
| 73 | stack_init(L, L); /* init stack */ | 76 | stack_init(L, L); /* init stack */ |
| 74 | /* create default meta table with a dummy table, and then close the loop */ | 77 | /* create default meta table with a dummy table, and then close the loop */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 1.82 2002/04/10 12:11:07 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.83 2002/04/16 17:08:28 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -113,6 +113,7 @@ typedef struct global_State { | |||
| 113 | lu_mem GCthreshold; | 113 | lu_mem GCthreshold; |
| 114 | lu_mem nblocks; /* number of `bytes' currently allocated */ | 114 | lu_mem nblocks; /* number of `bytes' currently allocated */ |
| 115 | lua_CFunction panic; /* to be called in unprotected errors */ | 115 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 116 | Node dummynode[1]; /* common node array for all empty tables */ | ||
| 116 | TString *tmname[TM_N]; /* array with tag-method names */ | 117 | TString *tmname[TM_N]; /* array with tag-method names */ |
| 117 | } global_State; | 118 | } global_State; |
| 118 | 119 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.103 2002/04/05 18:54:31 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.104 2002/04/22 14:40:23 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 | */ |
| @@ -52,13 +52,13 @@ | |||
| 52 | #define hashnum(t,n) \ | 52 | #define hashnum(t,n) \ |
| 53 | (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t)))) | 53 | (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t)))) |
| 54 | #define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t)))) | 54 | #define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t)))) |
| 55 | #define hashboolean(t,p) (node(t, p)) /* `p' in [0,1] < minimum table size */ | 55 | #define hashboolean(t,p) (node(t, lmod(p, sizenode(t)))) |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | ** for pointers, avoid modulus by power of 2, as they tend to have many | 58 | ** for pointers, avoid modulus by power of 2, as they tend to have many |
| 59 | ** 2 factors. | 59 | ** 2 factors. |
| 60 | */ | 60 | */ |
| 61 | #define hashpointer(t,p) (node(t, (IntPoint(p) % (sizenode(t)-1)))) | 61 | #define hashpointer(t,p) (node(t, (IntPoint(p) % ((sizenode(t)-1)|1)))) |
| 62 | 62 | ||
| 63 | 63 | ||
| 64 | /* | 64 | /* |
| @@ -200,12 +200,6 @@ static void numuse (const Table *t, int *narray, int *nhash) { | |||
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | 202 | ||
| 203 | /* | ||
| 204 | ** (log2 of) minimum size for hash part of a table | ||
| 205 | */ | ||
| 206 | #define MINHASHSIZE 1 | ||
| 207 | |||
| 208 | |||
| 209 | static void setarrayvector (lua_State *L, Table *t, int size) { | 203 | static void setarrayvector (lua_State *L, Table *t, int size) { |
| 210 | int i; | 204 | int i; |
| 211 | luaM_reallocvector(L, t->array, t->sizearray, size, TObject); | 205 | luaM_reallocvector(L, t->array, t->sizearray, size, TObject); |
| @@ -217,16 +211,22 @@ static void setarrayvector (lua_State *L, Table *t, int size) { | |||
| 217 | 211 | ||
| 218 | static void setnodevector (lua_State *L, Table *t, int lsize) { | 212 | static void setnodevector (lua_State *L, Table *t, int lsize) { |
| 219 | int i; | 213 | int i; |
| 220 | int size; | 214 | int size = twoto(lsize); |
| 221 | if (lsize < MINHASHSIZE) lsize = MINHASHSIZE; | 215 | if (lsize > MAXBITS) |
| 222 | else if (lsize > MAXBITS) | ||
| 223 | luaD_runerror(L, "table overflow"); | 216 | luaD_runerror(L, "table overflow"); |
| 224 | size = twoto(lsize); | 217 | if (lsize == 0) { /* no elements to hash part? */ |
| 225 | t->node = luaM_newvector(L, size, Node); | 218 | t->node = G(L)->dummynode; /* use common `dummynode' */ |
| 226 | for (i=0; i<size; i++) { | 219 | lua_assert(ttype(key(t->node)) == LUA_TNIL); /* assert invariants: */ |
| 227 | t->node[i].next = NULL; | 220 | lua_assert(ttype(val(t->node)) == LUA_TNIL); |
| 228 | setnilvalue(key(node(t, i))); | 221 | lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */ |
| 229 | setnilvalue(val(node(t, i))); | 222 | } |
| 223 | else { | ||
| 224 | t->node = luaM_newvector(L, size, Node); | ||
| 225 | for (i=0; i<size; i++) { | ||
| 226 | t->node[i].next = NULL; | ||
| 227 | setnilvalue(key(node(t, i))); | ||
| 228 | setnilvalue(val(node(t, i))); | ||
| 229 | } | ||
| 230 | } | 230 | } |
| 231 | t->lsizenode = cast(lu_byte, lsize); | 231 | t->lsizenode = cast(lu_byte, lsize); |
| 232 | t->firstfree = node(t, size-1); /* first free position to be used */ | 232 | t->firstfree = node(t, size-1); /* first free position to be used */ |
| @@ -235,14 +235,22 @@ static void setnodevector (lua_State *L, Table *t, int lsize) { | |||
| 235 | 235 | ||
| 236 | static void resize (lua_State *L, Table *t, int nasize, int nhsize) { | 236 | static void resize (lua_State *L, Table *t, int nasize, int nhsize) { |
| 237 | int i; | 237 | int i; |
| 238 | int oldasize, oldhsize; | 238 | int oldasize = t->sizearray; |
| 239 | int oldhsize = t->lsizenode; | ||
| 239 | Node *nold; | 240 | Node *nold; |
| 240 | oldasize = t->sizearray; | 241 | Node temp[1]; |
| 242 | if (oldhsize) | ||
| 243 | nold = t->node; /* save old hash ... */ | ||
| 244 | else { /* old hash is `dummynode' */ | ||
| 245 | lua_assert(t->node == G(L)->dummynode); | ||
| 246 | temp[0] = t->node[0]; /* copy it to `temp' (in case of errors) */ | ||
| 247 | nold = temp; | ||
| 248 | setnilvalue(key(G(L)->dummynode)); /* restate invariant */ | ||
| 249 | setnilvalue(val(G(L)->dummynode)); | ||
| 250 | } | ||
| 241 | if (nasize > oldasize) /* should grow array part? */ | 251 | if (nasize > oldasize) /* should grow array part? */ |
| 242 | setarrayvector(L, t, nasize); | 252 | setarrayvector(L, t, nasize); |
| 243 | /* create new hash part with appropriate size */ | 253 | /* create new hash part with appropriate size */ |
| 244 | nold = t->node; /* save old hash ... */ | ||
| 245 | oldhsize = t->lsizenode; /* ... and (log of) old size */ | ||
| 246 | setnodevector(L, t, nhsize); | 254 | setnodevector(L, t, nhsize); |
| 247 | /* re-insert elements */ | 255 | /* re-insert elements */ |
| 248 | if (nasize < oldasize) { /* array part must shrink? */ | 256 | if (nasize < oldasize) { /* array part must shrink? */ |
| @@ -262,7 +270,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { | |||
| 262 | if (ttype(val(old)) != LUA_TNIL) | 270 | if (ttype(val(old)) != LUA_TNIL) |
| 263 | luaH_set(L, t, key(old), val(old)); | 271 | luaH_set(L, t, key(old), val(old)); |
| 264 | } | 272 | } |
| 265 | luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ | 273 | if (oldhsize) |
| 274 | luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ | ||
| 266 | } | 275 | } |
| 267 | 276 | ||
| 268 | 277 | ||
| @@ -299,8 +308,7 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) { | |||
| 299 | 308 | ||
| 300 | 309 | ||
| 301 | void luaH_free (lua_State *L, Table *t) { | 310 | void luaH_free (lua_State *L, Table *t) { |
| 302 | lua_assert(t->lsizenode > 0 || t->node == NULL); | 311 | if (t->lsizenode) |
| 303 | if (t->lsizenode > 0) | ||
| 304 | luaM_freearray(L, t->node, sizenode(t), Node); | 312 | luaM_freearray(L, t->node, sizenode(t), Node); |
| 305 | luaM_freearray(L, t->array, t->sizearray, TObject); | 313 | luaM_freearray(L, t->array, t->sizearray, TObject); |
| 306 | luaM_freelem(L, t); | 314 | luaM_freelem(L, t); |
