Browse Source

better locality of assignment of table values

Roberto Ierusalimschy 24 years ago
parent
commit
8c8ad5f3ff
6 changed files with 48 additions and 40 deletions
  1. 3 3
      lapi.c
  2. 2 2
      lcode.c
  3. 18 18
      ltable.c
  4. 7 4
      ltable.h
  5. 6 4
      ltm.c
  6. 12 9
      lvm.c

+ 3 - 3
lapi.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lapi.c,v 1.148 2001/07/12 18:11:58 roberto Exp roberto $
+** $Id: lapi.c,v 1.149 2001/07/22 00:59:36 roberto Exp roberto $
 ** Lua API
 ** Lua API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -443,7 +443,7 @@ LUA_API void lua_rawset (lua_State *L, int index) {
   api_checknelems(L, 2);
   api_checknelems(L, 2);
   t = luaA_index(L, index);
   t = luaA_index(L, index);
   api_check(L, ttype(t) == LUA_TTABLE);
   api_check(L, ttype(t) == LUA_TTABLE);
-  setobj(luaH_set(L, hvalue(t), L->top-2), (L->top-1));
+  luaH_set(L, hvalue(t), L->top-2, L->top-1);
   L->top -= 2;
   L->top -= 2;
   lua_unlock(L);
   lua_unlock(L);
 }
 }
@@ -455,7 +455,7 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) {
   api_checknelems(L, 1);
   api_checknelems(L, 1);
   o = luaA_index(L, index);
   o = luaA_index(L, index);
   api_check(L, ttype(o) == LUA_TTABLE);
   api_check(L, ttype(o) == LUA_TTABLE);
-  setobj(luaH_setnum(L, hvalue(o), n), (L->top-1));
+  luaH_setnum(L, hvalue(o), n, L->top-1);
   L->top--;
   L->top--;
   lua_unlock(L);
   lua_unlock(L);
 }
 }

+ 2 - 2
lcode.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lcode.c,v 1.78 2001/07/24 17:19:07 roberto Exp roberto $
+** $Id: lcode.c,v 1.79 2001/08/27 15:16:28 roberto Exp roberto $
 ** Code generator for Lua
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -235,7 +235,7 @@ static int addk (FuncState *fs, TObject *k) {
                     MAXARG_Bc, l_s("constant table overflow"));
                     MAXARG_Bc, l_s("constant table overflow"));
     setobj(&f->k[fs->nk], k);
     setobj(&f->k[fs->nk], k);
     setnvalue(&o, fs->nk);
     setnvalue(&o, fs->nk);
-    setobj(luaH_set(fs->L, fs->h, k), &o);
+    luaH_set(fs->L, fs->h, k, &o);
     return fs->nk++;
     return fs->nk++;
   }
   }
 }
 }

+ 18 - 18
ltable.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltable.c,v 1.82 2001/06/26 13:20:45 roberto Exp roberto $
+** $Id: ltable.c,v 1.83 2001/07/05 20:31:14 roberto Exp roberto $
 ** Lua tables (hash)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -161,10 +161,8 @@ static void rehash (lua_State *L, Hash *t) {
     setnodevector(L, t, oldsize);  /* just rehash; keep the same size */
     setnodevector(L, t, oldsize);  /* just rehash; keep the same size */
   for (i=0; i<oldsize; i++) {
   for (i=0; i<oldsize; i++) {
     Node *old = nold+i;
     Node *old = nold+i;
-    if (ttype(val(old)) != LUA_TNIL) {
-      TObject *v = luaH_set(L, t, key(old));
-      setobj(v, val(old));
-    }
+    if (ttype(val(old)) != LUA_TNIL)
+      luaH_set(L, t, key(old), val(old));
   }
   }
   luaM_freearray(L, nold, oldsize, Node);  /* free old array */
   luaM_freearray(L, nold, oldsize, Node);  /* free old array */
 }
 }
@@ -206,7 +204,7 @@ static TObject *newkey (lua_State *L, Hash *t, const TObject *key) {
     else (t->firstfree)--;
     else (t->firstfree)--;
   }
   }
   rehash(L, t);  /* no more free places */
   rehash(L, t);  /* no more free places */
-  return luaH_set(L, t, key);  /* `rehash' invalidates this insertion */
+  return newkey(L, t, key);  /* `rehash' invalidates this insertion */
 }
 }
 
 
 
 
@@ -271,32 +269,34 @@ const TObject *luaH_get (Hash *t, const TObject *key) {
 }
 }
 
 
 
 
-TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
+void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val) {
   const TObject *p = luaH_get(t, key);
   const TObject *p = luaH_get(t, key);
-  if (p != &luaO_nilobject) return (TObject *)p;
-  else if (ttype(key) == LUA_TNIL) luaD_error(L, l_s("table index is nil"));
-  return newkey(L, t, key);
+  if (p == &luaO_nilobject) {
+    if (ttype(key) == LUA_TNIL) luaD_error(L, l_s("table index is nil"));
+    p = newkey(L, t, key);
+  }
+  settableval(p, val);
 }
 }
 
 
 
 
-TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
+void luaH_setstr (lua_State *L, Hash *t, TString *key, const TObject *val) {
   const TObject *p = luaH_getstr(t, key);
   const TObject *p = luaH_getstr(t, key);
-  if (p != &luaO_nilobject) return (TObject *)p;
-  else {
+  if (p == &luaO_nilobject) {
     TObject k;
     TObject k;
     setsvalue(&k, key);
     setsvalue(&k, key);
-    return newkey(L, t, &k);
+    p = newkey(L, t, &k);
   }
   }
+  settableval(p, val);
 }
 }
 
 
 
 
-TObject *luaH_setnum (lua_State *L, Hash *t, int key) {
+void luaH_setnum (lua_State *L, Hash *t, int key, const TObject *val) {
   const TObject *p = luaH_getnum(t, key);
   const TObject *p = luaH_getnum(t, key);
-  if (p != &luaO_nilobject) return (TObject *)p;
-  else {
+  if (p == &luaO_nilobject) {
     TObject k;
     TObject k;
     setnvalue(&k, key);
     setnvalue(&k, key);
-    return newkey(L, t, &k);
+    p = newkey(L, t, &k);
   }
   }
+  settableval(p, val);
 }
 }
 
 

+ 7 - 4
ltable.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltable.h,v 1.33 2001/06/26 13:20:45 roberto Exp roberto $
+** $Id: ltable.h,v 1.34 2001/07/05 20:31:14 roberto Exp roberto $
 ** Lua tables (hash)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -14,12 +14,15 @@
 #define key(_n)		(&(_n)->key)
 #define key(_n)		(&(_n)->key)
 #define val(_n)		(&(_n)->val)
 #define val(_n)		(&(_n)->val)
 
 
+#define settableval(p,v)	setobj((TObject *)p, v)
+
+
 const TObject *luaH_getnum (Hash *t, int key);
 const TObject *luaH_getnum (Hash *t, int key);
-TObject *luaH_setnum (lua_State *L, Hash *t, int key);
+void luaH_setnum (lua_State *L, Hash *t, int key, const TObject *val);
 const TObject *luaH_getstr (Hash *t, TString *key);
 const TObject *luaH_getstr (Hash *t, TString *key);
-TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);
+void luaH_setstr (lua_State *L, Hash *t, TString *key, const TObject *val);
 const TObject *luaH_get (Hash *t, const TObject *key);
 const TObject *luaH_get (Hash *t, const TObject *key);
-TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
+void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val);
 Hash *luaH_new (lua_State *L, int nhash);
 Hash *luaH_new (lua_State *L, int nhash);
 void luaH_free (lua_State *L, Hash *t);
 void luaH_free (lua_State *L, Hash *t);
 Node *luaH_next (lua_State *L, Hash *t, const TObject *r);
 Node *luaH_next (lua_State *L, Hash *t, const TObject *r);

+ 6 - 4
ltm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltm.c,v 1.75 2001/07/23 19:56:00 roberto Exp roberto $
+** $Id: ltm.c,v 1.76 2001/07/24 22:39:34 roberto Exp roberto $
 ** Tag methods
 ** Tag methods
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -84,11 +84,13 @@ int luaT_newtag (lua_State *L, const l_char *name, int basictype) {
                   MAX_INT, l_s("tag table overflow"));
                   MAX_INT, l_s("tag table overflow"));
   tag = G(L)->ntag;
   tag = G(L)->ntag;
   if (name) {
   if (name) {
-    TObject *v;
+    const TObject *v;
+    TObject otag;
     ts = luaS_new(L, name);
     ts = luaS_new(L, name);
-    v = luaH_setstr(L, G(L)->type2tag, ts);
+    v = luaH_getstr(G(L)->type2tag, ts);
     if (ttype(v) == LUA_TNUMBER) return (int)nvalue(v);
     if (ttype(v) == LUA_TNUMBER) return (int)nvalue(v);
-    setnvalue(v, tag);
+    setnvalue(&otag, tag);
+    luaH_setstr(L, G(L)->type2tag, ts, &otag);
   }
   }
   for (i=0; i<TM_N; i++)
   for (i=0; i<TM_N; i++)
     luaT_gettm(G(L), tag, i) = NULL;
     luaT_gettm(G(L), tag, i) = NULL;

+ 12 - 9
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 1.189 2001/06/28 14:48:44 roberto Exp roberto $
+** $Id: lvm.c,v 1.190 2001/06/28 14:57:17 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -186,7 +186,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
     int tg = hvalue(t)->htag;
     int tg = hvalue(t)->htag;
     if (hvalue(t)->htag == LUA_TTABLE ||  /* with default tag? */
     if (hvalue(t)->htag == LUA_TTABLE ||  /* with default tag? */
         (tm = luaT_gettm(G(L), tg, TM_SETTABLE)) == NULL) { /* or no TM? */
         (tm = luaT_gettm(G(L), tg, TM_SETTABLE)) == NULL) { /* or no TM? */
-      setobj(luaH_set(L, hvalue(t), key), val);  /* do a primitive set */
+      luaH_set(L, hvalue(t), key, val);  /* do a primitive set */
       return;
       return;
     }
     }
     /* else will call the tag method */
     /* else will call the tag method */
@@ -212,11 +212,14 @@ void luaV_getglobal (lua_State *L, TString *name, StkId res) {
 
 
 
 
 void luaV_setglobal (lua_State *L, TString *name, StkId val) {
 void luaV_setglobal (lua_State *L, TString *name, StkId val) {
-  TObject *oldvalue = luaH_setstr(L, L->gt, name);
+  const TObject *oldvalue = luaH_getstr(L->gt, name);
   Closure *tm;
   Closure *tm;
   if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) ||  /* no tag methods? */
   if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) ||  /* no tag methods? */
      (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
      (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
-    setobj(oldvalue, val);  /* raw set */
+    if (oldvalue == &luaO_nilobject)
+      luaH_setstr(L, L->gt, name, val);  /* raw set */
+    else
+      settableval(oldvalue, val);  /* warning: tricky optimization! */
   }
   }
   else
   else
     setTM(L, callTM(L, tm, l_s("soo"), name, oldvalue, val));
     setTM(L, callTM(L, tm, l_s("soo"), name, oldvalue, val));
@@ -317,12 +320,12 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
 static void luaV_pack (lua_State *L, StkId firstelem) {
 static void luaV_pack (lua_State *L, StkId firstelem) {
   int i;
   int i;
   Hash *htab = luaH_new(L, 0);
   Hash *htab = luaH_new(L, 0);
-  TObject *n;
+  TObject n;
   for (i=0; firstelem+i<L->top; i++)
   for (i=0; firstelem+i<L->top; i++)
-    setobj(luaH_setnum(L, htab, i+1), firstelem+i);
+    luaH_setnum(L, htab, i+1, firstelem+i);
   /* store counter in field `n' */
   /* store counter in field `n' */
-  n = luaH_setstr(L, htab, luaS_newliteral(L, l_s("n")));
-  setnvalue(n, i);
+  setnvalue(&n, i);
+  luaH_setstr(L, htab, luaS_newliteral(L, l_s("n")), &n);
   L->top = firstelem;  /* remove elements from the stack */
   L->top = firstelem;  /* remove elements from the stack */
   sethvalue(L->top, htab);
   sethvalue(L->top, htab);
   incr_top;
   incr_top;
@@ -640,7 +643,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
           n = L->top - ra - 1;
           n = L->top - ra - 1;
         bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
         bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
         for (; n > 0; n--)
         for (; n > 0; n--)
-          setobj(luaH_setnum(L, h, bc+n), ra+n);
+          luaH_setnum(L, h, bc+n, ra+n);
         break;
         break;
       }
       }
       case OP_CLOSURE: {
       case OP_CLOSURE: {