lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

uh oh ... I have to retract a part of the patch ...

I wrote:
> Well, it's simpler than I thought: the FPU already stores overflow and
> precision loss bits in the status word. You just have to check them after
> the fistpl instruction.

I just found out that these status bits are sticky. This means that any
previous FP instruction that didn't clear these may influence the outcome
of the next conversion operation. Unfortunately clearing these bits with
fnclex is slow and completely spoils the performance of the patch. :-(

Ugh, the 387 FPU is such a horrible design, anyway. But SSE2 is not that
common yet and doesn't help with the x86 ABI (thankfully x86-64 fixes that).

Anyway, the remainder of my patch still improves the performance over
the original lua-5.1-work2 distribution, so I appended the new version
(apply against the original).

> >                 -O     -O2    -O3 -fomit-frame-pointer
> > lua-5.0.2       3.30   3.40   3.60
> > lua-5.1-work0   3.72   4.30   3.44
> > lua-5.1-work2   4.03   4.18   3.50
> 
> lua-5.1-work2a    3.82   4.07   3.28
 
lua-5.1-work2b      3.88   4.10   3.35

Another few percent may be gotten by using the proper -march= GCC option
(many distros still set the default to pure 80386 code).

Bye,
     Mike
--- lua-5.1-work2/src/ltable.c	2004-08-31 19:57:33.000000000 +0200
+++ lua-5.1-work2b/src/ltable.c	2004-09-29 14:07:48.000000000 +0200
@@ -107,13 +107,12 @@
 ** returns the index for `key' if `key' is an appropriate key to live in
 ** the array part of the table, -1 otherwise.
 */
-static int arrayindex (const TValue *key, lua_Number lim) {
+static int arrayindex (const TValue *key, int lim) {
   if (ttisnumber(key)) {
-    lua_Number n = nvalue(key);
     int k;
-    if (n <= 0 || n > lim) return -1;  /* out of range? */
-    lua_number2int(k, n);
-    if (cast(lua_Number, k) == nvalue(key))
+    lua_number2int(k, nvalue(key));
+    if (cast(lua_Number, k) == nvalue(key) &&
+        (unsigned int)(k-1) < (unsigned int)lim)
       return k;
   }
   return -1;  /* `key' did not match some condition */
@@ -195,7 +194,7 @@
   int nums[MAXBITS+1];
   int i, lg;
   int totaluse = 0;
-  lua_Number sizelimit;  /* an upper bound for the array size */
+  int sizelimit;  /* an upper bound for the array size */
   /* count elements in array part */
   for (i=0, lg=0; lg<=MAXBITS; lg++) {  /* for each slice [2^(lg-1) to 2^lg) */
     int ttlg = twoto(lg);  /* 2^lg */
@@ -216,7 +215,7 @@
   /* count elements in hash part */
   i = sizenode(t);
   /* array part cannot be larger than twice the maximum number of elements */
-  sizelimit = cast(lua_Number, totaluse + i) * 2;
+  sizelimit = (totaluse + i) * 2;
   if (sizelimit >= MAXASIZE) sizelimit = MAXASIZE;
   while (i--) {
     Node *n = &t->node[i];
@@ -397,7 +396,7 @@
 ** search function for integers
 */
 const TValue *luaH_getnum (Table *t, int key) {
-  if (1 <= key && key <= t->sizearray)
+  if ((unsigned int)(key-1) < (unsigned int)t->sizearray)
     return &t->array[key-1];
   else {
     lua_Number nk = cast(lua_Number, key);
@@ -425,30 +424,32 @@
   return &luaO_nilobject;
 }
 
+static const TValue *luaH_getany (Table *t, const TValue *key) {
+  if (!ttisnil(key)) {
+    Node *n = luaH_mainposition(t, key);
+    do {  /* check whether `key' is somewhere in the chain */
+      if (luaO_rawequalObj(gkey(n), key)) return gval(n);  /* that's it */
+      else n = n->next;
+    } while (n);
+  }
+  return &luaO_nilobject;
+}
 
 /*
 ** main search function
 */
 const TValue *luaH_get (Table *t, const TValue *key) {
-  switch (ttype(key)) {
-    case LUA_TNIL: return &luaO_nilobject;
-    case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
-    case LUA_TNUMBER: {
-      int k;
-      lua_number2int(k, (nvalue(key)));
-      if (cast(lua_Number, k) == nvalue(key))  /* is an integer index? */
-        return luaH_getnum(t, k);  /* use specialized version */
-      /* else go through */
-    }
-    default: {
-      Node *n = luaH_mainposition(t, key);
-      do {  /* check whether `key' is somewhere in the chain */
-        if (luaO_rawequalObj(gkey(n), key)) return gval(n);  /* that's it */
-        else n = n->next;
-      } while (n);
-      return &luaO_nilobject;
-    }
+  int tt = ttype(key);
+  if (tt == LUA_TNUMBER) {
+    int k;
+    lua_number2int(k, (nvalue(key)));
+    if (cast(lua_Number, k) == nvalue(key))  /* is an integer index? */
+      return luaH_getnum(t, k);  /* use specialized version */
+    /* else go through */
+  } else if (tt == LUA_TSTRING) {
+    return luaH_getstr(t, rawtsvalue(key));
   }
+  return luaH_getany(t, key);
 }