diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-06 15:34:16 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-10-06 15:34:16 -0300 |
| commit | bd38017ddfeda738f3f1881043c0ec8bbea1adbc (patch) | |
| tree | 4fd935dbf16599661abc2d0c6be8ca8be083b678 | |
| parent | 652f885c30e36c3bdbecd71b70dfbf273abfe24e (diff) | |
| download | lua-bd38017ddfeda738f3f1881043c0ec8bbea1adbc.tar.gz lua-bd38017ddfeda738f3f1881043c0ec8bbea1adbc.tar.bz2 lua-bd38017ddfeda738f3f1881043c0ec8bbea1adbc.zip | |
small optimization for table size in machines with double allignment
| -rw-r--r-- | lgc.c | 4 | ||||
| -rw-r--r-- | lobject.c | 4 | ||||
| -rw-r--r-- | lobject.h | 19 | ||||
| -rw-r--r-- | lstate.c | 4 | ||||
| -rw-r--r-- | ltable.c | 38 | ||||
| -rw-r--r-- | ltable.h | 5 | ||||
| -rw-r--r-- | ltests.c | 8 |
7 files changed, 47 insertions, 35 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.11 2004/09/08 14:23:09 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.12 2004/09/15 20:38:15 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 | */ |
| @@ -367,7 +367,7 @@ static void cleartable (GCObject *l) { | |||
| 367 | while (i--) { | 367 | while (i--) { |
| 368 | Node *n = gnode(h, i); | 368 | Node *n = gnode(h, i); |
| 369 | if (!ttisnil(gval(n)) && /* non-empty entry? */ | 369 | if (!ttisnil(gval(n)) && /* non-empty entry? */ |
| 370 | (iscleared(gkey(n), 1) || iscleared(gval(n), 0))) | 370 | (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) |
| 371 | removeentry(n); /* remove entry from table */ | 371 | removeentry(n); /* remove entry from table */ |
| 372 | } | 372 | } |
| 373 | l = h->gclist; | 373 | l = h->gclist; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.3 2004/05/03 12:30:41 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.4 2004/07/09 16:01:38 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,7 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | const TValue luaO_nilobject = {LUA_TNIL, {NULL}}; | 26 | const TValue luaO_nilobject = {{NULL}, LUA_TNIL}; |
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | /* | 29 | /* |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.4 2004/03/15 21:04:33 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.5 2004/05/31 18:51:50 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -64,9 +64,11 @@ typedef union { | |||
| 64 | /* | 64 | /* |
| 65 | ** Tagged Values | 65 | ** Tagged Values |
| 66 | */ | 66 | */ |
| 67 | |||
| 68 | #define TValuefields Value value; int tt | ||
| 69 | |||
| 67 | typedef struct lua_TValue { | 70 | typedef struct lua_TValue { |
| 68 | int tt; | 71 | TValuefields; |
| 69 | Value value; | ||
| 70 | } TValue; | 72 | } TValue; |
| 71 | 73 | ||
| 72 | 74 | ||
| @@ -158,7 +160,7 @@ typedef struct lua_TValue { | |||
| 158 | 160 | ||
| 159 | #define setobj(L,obj1,obj2) \ | 161 | #define setobj(L,obj1,obj2) \ |
| 160 | { const TValue *o2=(obj2); TValue *o1=(obj1); \ | 162 | { const TValue *o2=(obj2); TValue *o1=(obj1); \ |
| 161 | o1->tt=o2->tt; o1->value = o2->value; \ | 163 | o1->value = o2->value; o1->tt=o2->tt; \ |
| 162 | checkliveness(G(L),o1); } | 164 | checkliveness(G(L),o1); } |
| 163 | 165 | ||
| 164 | 166 | ||
| @@ -308,10 +310,15 @@ typedef union Closure { | |||
| 308 | ** Tables | 310 | ** Tables |
| 309 | */ | 311 | */ |
| 310 | 312 | ||
| 313 | typedef struct TKey { | ||
| 314 | TValuefields; | ||
| 315 | struct Node *next; /* for chaining */ | ||
| 316 | } TKey; | ||
| 317 | |||
| 318 | |||
| 311 | typedef struct Node { | 319 | typedef struct Node { |
| 312 | TValue i_key; | ||
| 313 | TValue i_val; | 320 | TValue i_val; |
| 314 | struct Node *next; /* for chaining */ | 321 | TKey i_key; |
| 315 | } Node; | 322 | } Node; |
| 316 | 323 | ||
| 317 | 324 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.13 2004/09/08 14:23:09 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.14 2004/09/15 20:39:42 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 | */ |
| @@ -191,7 +191,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 191 | g->tmudata = NULL; | 191 | g->tmudata = NULL; |
| 192 | setnilvalue(gkey(g->dummynode)); | 192 | setnilvalue(gkey(g->dummynode)); |
| 193 | setnilvalue(gval(g->dummynode)); | 193 | setnilvalue(gval(g->dummynode)); |
| 194 | g->dummynode->next = NULL; | 194 | gnext(g->dummynode) = NULL; |
| 195 | g->totalbytes = sizeof(LG); | 195 | g->totalbytes = sizeof(LG); |
| 196 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { | 196 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { |
| 197 | /* memory allocation error: free partial state */ | 197 | /* memory allocation error: free partial state */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.5 2004/08/31 17:57:33 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.6 2004/09/27 18:54:45 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 | */ |
| @@ -152,7 +152,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) { | |||
| 152 | } | 152 | } |
| 153 | for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ | 153 | for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ |
| 154 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ | 154 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ |
| 155 | setobj2s(L, key, gkey(gnode(t, i))); | 155 | setobj2s(L, key, key2tval(gnode(t, i))); |
| 156 | setobj2s(L, key+1, gval(gnode(t, i))); | 156 | setobj2s(L, key+1, gval(gnode(t, i))); |
| 157 | return 1; | 157 | return 1; |
| 158 | } | 158 | } |
| @@ -215,7 +215,7 @@ static void numuse (const Table *t, int *narray, int *nhash) { | |||
| 215 | while (i--) { | 215 | while (i--) { |
| 216 | Node *n = &t->node[i]; | 216 | Node *n = &t->node[i]; |
| 217 | if (!ttisnil(gval(n))) { | 217 | if (!ttisnil(gval(n))) { |
| 218 | int k = arrayindex(gkey(n)); | 218 | int k = arrayindex(key2tval(n)); |
| 219 | if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ | 219 | if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ |
| 220 | nums[luaO_log2(k-1)+1]++; /* count as such */ | 220 | nums[luaO_log2(k-1)+1]++; /* count as such */ |
| 221 | (*narray)++; | 221 | (*narray)++; |
| @@ -245,12 +245,12 @@ static void setnodevector (lua_State *L, Table *t, int lsize) { | |||
| 245 | t->node = G(L)->dummynode; /* use common `dummynode' */ | 245 | t->node = G(L)->dummynode; /* use common `dummynode' */ |
| 246 | lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */ | 246 | lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */ |
| 247 | lua_assert(ttisnil(gval(t->node))); | 247 | lua_assert(ttisnil(gval(t->node))); |
| 248 | lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */ | 248 | lua_assert(gnext(t->node) == NULL); /* (`dummynode' must be empty) */ |
| 249 | } | 249 | } |
| 250 | else { | 250 | else { |
| 251 | t->node = luaM_newvector(L, size, Node); | 251 | t->node = luaM_newvector(L, size, Node); |
| 252 | for (i=0; i<size; i++) { | 252 | for (i=0; i<size; i++) { |
| 253 | t->node[i].next = NULL; | 253 | gnext(&t->node[i]) = NULL; |
| 254 | setnilvalue(gkey(gnode(t, i))); | 254 | setnilvalue(gkey(gnode(t, i))); |
| 255 | setnilvalue(gval(gnode(t, i))); | 255 | setnilvalue(gval(gnode(t, i))); |
| 256 | } | 256 | } |
| @@ -274,7 +274,7 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { | |||
| 274 | nold = temp; | 274 | nold = temp; |
| 275 | setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */ | 275 | setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */ |
| 276 | setnilvalue(gval(G(L)->dummynode)); | 276 | setnilvalue(gval(G(L)->dummynode)); |
| 277 | lua_assert(G(L)->dummynode->next == NULL); | 277 | lua_assert(gnext(G(L)->dummynode) == NULL); |
| 278 | } | 278 | } |
| 279 | if (nasize > oldasize) /* array part must grow? */ | 279 | if (nasize > oldasize) /* array part must grow? */ |
| 280 | setarrayvector(L, t, nasize); | 280 | setarrayvector(L, t, nasize); |
| @@ -295,7 +295,7 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { | |||
| 295 | for (i = twoto(oldhsize) - 1; i >= 0; i--) { | 295 | for (i = twoto(oldhsize) - 1; i >= 0; i--) { |
| 296 | Node *old = nold+i; | 296 | Node *old = nold+i; |
| 297 | if (!ttisnil(gval(old))) | 297 | if (!ttisnil(gval(old))) |
| 298 | setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); | 298 | setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); |
| 299 | } | 299 | } |
| 300 | if (oldhsize) | 300 | if (oldhsize) |
| 301 | luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ | 301 | luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ |
| @@ -351,24 +351,25 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 351 | TValue *val; | 351 | TValue *val; |
| 352 | Node *mp = luaH_mainposition(t, key); | 352 | Node *mp = luaH_mainposition(t, key); |
| 353 | if (!ttisnil(gval(mp))) { /* main position is not free? */ | 353 | if (!ttisnil(gval(mp))) { /* main position is not free? */ |
| 354 | Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */ | 354 | /* `mp' of colliding node */ |
| 355 | Node *othern = luaH_mainposition(t, key2tval(mp)); | ||
| 355 | Node *n = t->firstfree; /* get a free place */ | 356 | Node *n = t->firstfree; /* get a free place */ |
| 356 | if (othern != mp) { /* is colliding node out of its main position? */ | 357 | if (othern != mp) { /* is colliding node out of its main position? */ |
| 357 | /* yes; move colliding node into free position */ | 358 | /* yes; move colliding node into free position */ |
| 358 | while (othern->next != mp) othern = othern->next; /* find previous */ | 359 | while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ |
| 359 | othern->next = n; /* redo the chain with `n' in place of `mp' */ | 360 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ |
| 360 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | 361 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ |
| 361 | mp->next = NULL; /* now `mp' is free */ | 362 | gnext(mp) = NULL; /* now `mp' is free */ |
| 362 | setnilvalue(gval(mp)); | 363 | setnilvalue(gval(mp)); |
| 363 | } | 364 | } |
| 364 | else { /* colliding node is in its own main position */ | 365 | else { /* colliding node is in its own main position */ |
| 365 | /* new node will go into free position */ | 366 | /* new node will go into free position */ |
| 366 | n->next = mp->next; /* chain new position */ | 367 | gnext(n) = gnext(mp); /* chain new position */ |
| 367 | mp->next = n; | 368 | gnext(mp) = n; |
| 368 | mp = n; | 369 | mp = n; |
| 369 | } | 370 | } |
| 370 | } | 371 | } |
| 371 | setobj2t(L, gkey(mp), key); | 372 | gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; |
| 372 | luaC_barriert(L, t, key); | 373 | luaC_barriert(L, t, key); |
| 373 | lua_assert(ttisnil(gval(mp))); | 374 | lua_assert(ttisnil(gval(mp))); |
| 374 | for (;;) { /* correct `firstfree' */ | 375 | for (;;) { /* correct `firstfree' */ |
| @@ -400,7 +401,7 @@ const TValue *luaH_getnum (Table *t, int key) { | |||
| 400 | do { /* check whether `key' is somewhere in the chain */ | 401 | do { /* check whether `key' is somewhere in the chain */ |
| 401 | if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) | 402 | if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) |
| 402 | return gval(n); /* that's it */ | 403 | return gval(n); /* that's it */ |
| 403 | else n = n->next; | 404 | else n = gnext(n); |
| 404 | } while (n); | 405 | } while (n); |
| 405 | return &luaO_nilobject; | 406 | return &luaO_nilobject; |
| 406 | } | 407 | } |
| @@ -415,7 +416,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { | |||
| 415 | do { /* check whether `key' is somewhere in the chain */ | 416 | do { /* check whether `key' is somewhere in the chain */ |
| 416 | if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) | 417 | if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) |
| 417 | return gval(n); /* that's it */ | 418 | return gval(n); /* that's it */ |
| 418 | else n = n->next; | 419 | else n = gnext(n); |
| 419 | } while (n); | 420 | } while (n); |
| 420 | return &luaO_nilobject; | 421 | return &luaO_nilobject; |
| 421 | } | 422 | } |
| @@ -438,8 +439,9 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
| 438 | default: { | 439 | default: { |
| 439 | Node *n = luaH_mainposition(t, key); | 440 | Node *n = luaH_mainposition(t, key); |
| 440 | do { /* check whether `key' is somewhere in the chain */ | 441 | do { /* check whether `key' is somewhere in the chain */ |
| 441 | if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */ | 442 | if (luaO_rawequalObj(key2tval(n), key)) |
| 442 | else n = n->next; | 443 | return gval(n); /* that's it */ |
| 444 | else n = gnext(n); | ||
| 443 | } while (n); | 445 | } while (n); |
| 444 | return &luaO_nilobject; | 446 | return &luaO_nilobject; |
| 445 | } | 447 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 2.2 2004/03/26 14:02:41 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 | */ |
| @@ -13,6 +13,9 @@ | |||
| 13 | #define gnode(t,i) (&(t)->node[i]) | 13 | #define gnode(t,i) (&(t)->node[i]) |
| 14 | #define gkey(n) (&(n)->i_key) | 14 | #define gkey(n) (&(n)->i_key) |
| 15 | #define gval(n) (&(n)->i_val) | 15 | #define gval(n) (&(n)->i_val) |
| 16 | #define gnext(n) ((n)->i_key.next) | ||
| 17 | |||
| 18 | #define key2tval(n) (cast(const TValue *, gkey(n))) | ||
| 16 | 19 | ||
| 17 | 20 | ||
| 18 | const TValue *luaH_getnum (Table *t, int key); | 21 | const TValue *luaH_getnum (Table *t, int key); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.12 2004/09/21 16:54:32 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.13 2004/09/29 21:00:25 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -554,13 +554,13 @@ static int table_query (lua_State *L) { | |||
| 554 | if (!ttisnil(gval(gnode(t, i))) || | 554 | if (!ttisnil(gval(gnode(t, i))) || |
| 555 | ttisnil(gkey(gnode(t, i))) || | 555 | ttisnil(gkey(gnode(t, i))) || |
| 556 | ttisnumber(gkey(gnode(t, i)))) { | 556 | ttisnumber(gkey(gnode(t, i)))) { |
| 557 | luaA_pushobject(L, gkey(gnode(t, i))); | 557 | luaA_pushobject(L, key2tval(gnode(t, i))); |
| 558 | } | 558 | } |
| 559 | else | 559 | else |
| 560 | lua_pushliteral(L, "<undef>"); | 560 | lua_pushliteral(L, "<undef>"); |
| 561 | luaA_pushobject(L, gval(gnode(t, i))); | 561 | luaA_pushobject(L, gval(gnode(t, i))); |
| 562 | if (t->node[i].next) | 562 | if (gnext(&t->node[i])) |
| 563 | lua_pushinteger(L, t->node[i].next - t->node); | 563 | lua_pushinteger(L, gnext(&t->node[i]) - t->node); |
| 564 | else | 564 | else |
| 565 | lua_pushnil(L); | 565 | lua_pushnil(L); |
| 566 | } | 566 | } |
