From caceeab750ed80e94f8ec763248ae04cd90fefb5 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Sun, 18 Aug 2013 13:12:18 -0300 Subject: 'next' field for tables changed from pointer to integer (for better alignment on 64-bit machines) --- ltable.c | 68 +++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 24 deletions(-) (limited to 'ltable.c') diff --git a/ltable.c b/ltable.c index 6a7e28f0..f5b8fcf6 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.77 2013/05/29 14:05:03 roberto Exp roberto $ +** $Id: ltable.c,v 2.78 2013/06/20 15:02:49 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -79,7 +79,7 @@ static const Node dummynode_ = { {NILCONSTANT}, /* value */ - {{NILCONSTANT, NULL}} /* key */ + {{NILCONSTANT, 0}} /* key */ }; @@ -158,6 +158,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ return i-1; /* yes; that's the index (corrected to C) */ else { + int nx; Node *n = mainposition(t, key); for (;;) { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ @@ -168,9 +169,10 @@ static int findindex (lua_State *L, Table *t, StkId key) { /* hash elements are numbered after array ones */ return i + t->sizearray; } - else n = gnext(n); - if (n == NULL) + nx = gnext(n); + if (nx == 0) luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + else n += nx; } } } @@ -301,7 +303,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { t->node = luaM_newvector(L, size, Node); for (i=0; inext also goes) */ - gnext(mp) = NULL; /* now `mp' is free */ + while (othern + gnext(othern) != mp) /* find previous */ + othern += gnext(othern); + gnext(othern) = f - othern; /* re-chain with 'f' in place of 'mp' */ + *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + if (gnext(mp) != 0) { + gnext(f) += mp - f; /* correct 'next' */ + gnext(mp) = 0; /* now 'mp' is free */ + } setnilvalue(gval(mp)); } else { /* colliding node is in its own main position */ /* new node will go into free position */ - gnext(n) = gnext(mp); /* chain new position */ - gnext(mp) = n; - mp = n; + if (gnext(mp) != 0) + gnext(f) = (mp + gnext(mp)) - f; /* chain new position */ + else lua_assert(gnext(f) == 0); + gnext(mp) = f - mp; + mp = f; } } setobj2t(L, gkey(mp), key); @@ -468,11 +476,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { return &t->array[key - 1]; else { Node *n = hashint(t, key); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) return gval(n); /* that's it */ - else n = gnext(n); - } while (n); + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + }; return luaO_nilobject; } } @@ -484,11 +496,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { const TValue *luaH_getstr (Table *t, TString *key) { Node *n = hashstr(t, key); lua_assert(key->tsv.tt == LUA_TSHRSTR); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) return gval(n); /* that's it */ - else n = gnext(n); - } while (n); + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + }; return luaO_nilobject; } @@ -509,11 +525,15 @@ const TValue *luaH_get (Table *t, const TValue *key) { } default: { Node *n = mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ if (luaV_rawequalobj(gkey(n), key)) return gval(n); /* that's it */ - else n = gnext(n); - } while (n); + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + }; return luaO_nilobject; } } -- cgit v1.2.3-55-g6feb