Index: trunk/src/emx/src/emxomf/stabshll.c
===================================================================
--- trunk/src/emx/src/emxomf/stabshll.c	(revision 391)
+++ trunk/src/emx/src/emxomf/stabshll.c	(revision 392)
@@ -20,5 +20,4 @@
 Boston, MA 02111-1307, USA.  */
 
-#define HASH_DEBUG
 
 /*******************************************************************************
@@ -298,5 +297,5 @@
 
 static struct type *type_head;
-#define TYPE_HASH_MAX   128
+#define TYPE_HASH_MAX   211
 static struct type *atype_tag[TYPE_HASH_MAX];
 #ifdef HASH_DEBUG
@@ -575,8 +574,7 @@
  * @param   t     type
  */
-static unsigned type_hash (struct type *t)
+static inline unsigned type_hash (struct type *t)
 {
   register unsigned uhash = 0;
-  unsigned          uret;
   switch (t->tag)
     {
@@ -591,37 +589,39 @@
       case ty_array:        uhash = (unsigned)t->d.array.etype; break;
       case ty_bits:         uhash = (unsigned)t->d.bits.type; break;
-      case ty_func:         uhash = (unsigned)t->d.func.args; break;
-      case ty_types:        uhash = (unsigned)t->d.types.count  <<2; break;
-      case ty_args:         uhash = (unsigned)t->d.args.count   <<2; break;
-      case ty_fields:       uhash = (unsigned)t->d.fields.count <<2; break;
-      case ty_member:       uhash = (unsigned)t->d.member.type; break;
-      case ty_values:       uhash = (unsigned)t->d.values.count <<2; break;
+      case ty_func:         uhash = (unsigned)t->d.func.args ^ (unsigned)t->d.func.arg_count ^ (unsigned)t->d.func.ret ^ (unsigned)t->d.func.domain; break;
+      case ty_types:        uhash = (unsigned)t->d.types.count  << 3; break;
+      case ty_args:         uhash = (unsigned)t->d.args.count   << 3; break;
+      case ty_fields:       uhash = (unsigned)t->d.fields.count << 3; break;
+      case ty_member:       uhash = (unsigned)t->d.member.type ^ (unsigned)t->d.member.name >> 7; break;
+      case ty_values:       uhash = (unsigned)t->d.values.count << 3; break;
       case ty_memfunc:      uhash = (unsigned)t->d.memfunc.type; break;
       case ty_baseclass:    uhash = (unsigned)t->d.baseclass.type; break;
     }
   uhash += t->tag;
-  uret = uhash ^ (uhash >> 13);
-  return uret & (TYPE_HASH_MAX - 1);
-}
-
-
-/* Add a new internal type to the list of internal types.  If an
-   identical type already exists, a pointer to that type is returned.
-   Otherwise, a copy of the new type is added to the list and a
-   pointer to that type is returned.  It isn't worth my while to
-   improve the speed of this function, for instance by using
-   hashing.
-
-   Actually it is worth while optimizing it as it takes 85% of the
-   time here... or rather it was. */
-
-static struct type *type_add (struct type *src)
-{
-  unsigned ihash;
-  struct type *p;
+  return (uhash ^ uhash >> 13) % TYPE_HASH_MAX;
+}
+
+
+/**
+ * Search a list for a type.
+ * @returns pointer to the type we found.
+ * @returns NULL if not found.
+ * @param   p       Pointer to the head list.
+ * @param   src     Type to find.
+ * @param   fhash   Whether or not to follow the hash list or the main list.
+ */
+#ifdef HASH_DEBUG
+static struct type *type_find (struct type *p, const struct type *src, int fhash)
+#else
+static struct type *type_find (struct type *p, const struct type *src)
+#endif
+{
   int i;
-
-  ihash = type_hash(src);
-  for (p = atype_tag[ihash]; p != NULL; p = p->nexthash)
+  for (; p != NULL;
+#ifdef HASH_DEBUG
+       p = fhash ? p->nexthash : p->next )
+#else
+       p = p->nexthash                   )
+#endif
     if (p->tag == src->tag)
       switch (p->tag)
@@ -752,8 +752,48 @@
           abort ();
         }
-
+  return NULL;
+}
+
+
+/* Add a new internal type to the list of internal types.  If an
+   identical type already exists, a pointer to that type is returned.
+   Otherwise, a copy of the new type is added to the list and a
+   pointer to that type is returned.  It isn't worth my while to
+   improve the speed of this function, for instance by using
+   hashing.
+
+   Actually it is worth while optimizing it as it takes 85% of the
+   time here... or rather it was.
+
+   ctypes=25301 */
+
+static struct type *type_add (struct type *src)
+{
+  struct type *p;
+  unsigned ihash;
+  int i;
+
+  ihash = type_hash(src);
 #ifdef HASH_DEBUG
+  p = type_find (atype_tag[ihash], src, 1);
+#else
+  p = type_find (atype_tag[ihash], src);
+#endif
+  if (p)
+    {
+      return p;
+    }
+
+#ifdef HASH_DEBUG
+/*  {
+    struct type *pcheck = type_find (type_head, src, 0);
+    if (pcheck)
+      {
+        printf("\n\thash algorithm is borked! tag=%d\n", pcheck->tag);
+        return pcheck;
+      }
+  } */
+  ctype_tag[ihash]++;
   ctypes++;
-  ctype_tag[ihash]++;
 #endif
 
@@ -1455,39 +1495,27 @@
 static const char *nextcolon(const char *psz)
 {
-    int cNesting;                       /* <> level */
-
-    for (cNesting = 0;;psz++)
-      switch (*psz)
-        {
-          case '<':
-            #if 0
-            /* workaround for "operator<::" and "operator<::"
-             *  */
-            if (!cNesting  || (psz[1] == ':' && psz[2] == ':'))
-                return psz + 1;
-            if (!cNesting  || (psz[1] == '<' && psz[2] == ':' && psz[3] == ':'))
-                return psz + 2;
-            #else
-            /* general and faster check: < or > followed by : means the end. */
-            #endif
-            if (psz[1] == ':')
-              return psz + 1;
-            cNesting++;
-            break;
-          case '>':
-            if (psz[1] == ':')
-              return psz + 1;
-            cNesting--;
-            break;
-          case ':':
-            if (cNesting <= 0)
-              return psz;
-            break;
-          case '\0':
-            return NULL;
-        }
-      psz++;
-
-    return NULL;
+  int cNesting = 0;                     /* <> level */
+
+  for (;;psz++)
+    switch (*psz)
+      {
+        case '<':
+          if (psz[1] == ':')
+            return psz + 1;
+          cNesting++;
+          break;
+        case '>':
+          if (psz[1] == ':')
+            return psz + 1;
+          cNesting--;
+          break;
+        case ':':
+          if (cNesting <= 0)
+            return psz;
+          break;
+        case '\0':
+          return NULL;
+      }
+  return NULL;
 }
 
@@ -3594,4 +3622,5 @@
 
 #ifdef HASH_DEBUG
+fprintf(stderr, "\n");
 for (i = 0; i < TYPE_HASH_MAX; i++)
   if (i % 7 == 6)
@@ -3600,4 +3629,20 @@
     fprintf(stderr, "%3d: %4d   ", i, ctype_tag[i]);
 fprintf(stderr, "\nctypes=%d\n", ctypes);
+for (i = 0; i < TYPE_HASH_MAX; i++)
+  if (ctype_tag[i] > 1000)
+    {
+      int       j;
+      unsigned  au[ty_max];
+      memset(&au[0], 0, sizeof(au));
+      for (t1 = atype_tag[i]; t1 != NULL; t1 = t1->nexthash)
+        au[t1->tag]++;
+
+      fprintf(stderr, "\nIndex %d is overpopulated (%d):\n", i, ctype_tag[i]);
+      for (j = 0; j < 18; j++)
+        if (j % 7 == 6)
+          fprintf(stderr, "%2d: %4d\n", j, au[j]);
+        else
+          fprintf(stderr, "%2d: %4d   ", j, au[j]);
+    }
 #endif
 
