Changeset 430 for trunk/src/gmake


Ignore:
Timestamp:
Mar 26, 2006, 2:40:00 PM (19 years ago)
Author:
bird
Message:

better hashing, more inline string stuff. (still optimizing libc)

Location:
trunk/src/gmake
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gmake/Makefile.kmk

    r429 r430  
    2121        CONFIG_NO_DEFAULT_SUFFIX_RULES \
    2222        CONFIG_NO_DEFAULT_VARIABLES \
    23         KMK
     23        KMK \
     24        VARIABLE_HASH
    2425       
    2526       
  • trunk/src/gmake/make.h

    r429 r430  
    606606                               while (((_v)=_c)==0 && errno==EINTR); }while(0)
    607607
     608#ifdef __EMX__ /* saves 40-100ms on libc. */
     609#undef strchr
     610#define strchr(s, c) \
     611  (__extension__ (__builtin_constant_p (c)                                    \
     612                  ? ((c) == '\0'                                              \
     613                     ? (char *) __rawmemchr ((s), (c))                        \
     614                     : __strchr_c ((s), ((c) & 0xff) << 8))                   \
     615                  : __strchr_g ((s), (c))))
     616static inline char *__strchr_c (const char *__s, int __c)
     617{
     618  register unsigned long int __d0;
     619  register char *__res;
     620  __asm__ __volatile__
     621    ("1:\n\t"
     622     "movb      (%0),%%al\n\t"
     623     "cmpb      %%ah,%%al\n\t"
     624     "je        2f\n\t"
     625     "leal      1(%0),%0\n\t"
     626     "testb     %%al,%%al\n\t"
     627     "jne       1b\n\t"
     628     "xorl      %0,%0\n"
     629     "2:"
     630     : "=r" (__res), "=&a" (__d0)
     631     : "0" (__s), "1" (__c),
     632       "m" ( *(struct { char __x[0xfffffff]; } *)__s)
     633     : "cc");
     634  return __res;
     635}
     636
     637static inline char *__strchr_g (__const char *__s, int __c)
     638{
     639  register unsigned long int __d0;
     640  register char *__res;
     641  __asm__ __volatile__
     642    ("movb      %%al,%%ah\n"
     643     "1:\n\t"
     644     "movb      (%0),%%al\n\t"
     645     "cmpb      %%ah,%%al\n\t"
     646     "je        2f\n\t"
     647     "leal      1(%0),%0\n\t"
     648     "testb     %%al,%%al\n\t"
     649     "jne       1b\n\t"
     650     "xorl      %0,%0\n"
     651     "2:"
     652     : "=r" (__res), "=&a" (__d0)
     653     : "0" (__s), "1" (__c),
     654       "m" ( *(struct { char __x[0xfffffff]; } *)__s)
     655     : "cc");
     656  return __res;
     657}
     658
     659static inline void *__rawmemchr (const void *__s, int __c)
     660{
     661  register unsigned long int __d0;
     662  register unsigned char *__res;
     663  __asm__ __volatile__
     664    ("cld\n\t"
     665     "repne; scasb\n\t"
     666     : "=D" (__res), "=&c" (__d0)
     667     : "a" (__c), "0" (__s), "1" (0xffffffff),
     668       "m" ( *(struct { char __x[0xfffffff]; } *)__s)
     669     : "cc");
     670  return __res - 1;
     671}
     672
     673#undef memchr
     674#define memchr(a,b,c) __memchr((a),(b),(c))
     675static inline void *__memchr (__const void *__s, int __c, size_t __n)
     676{
     677  register unsigned long int __d0;
     678  register unsigned char *__res;
     679  if (__n == 0)
     680    return NULL;
     681  __asm__ __volatile__
     682    ("repne; scasb\n\t"
     683     "je        1f\n\t"
     684     "movl      $1,%0\n"
     685     "1:"
     686     : "=D" (__res), "=&c" (__d0)
     687     : "a" (__c), "0" (__s), "1" (__n),
     688       "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
     689     : "cc");
     690  return __res - 1;
     691}
     692
     693#endif
  • trunk/src/gmake/variable.c

    r429 r430  
    103103/* Hash table of all global variable definitions.  */
    104104
     105#ifdef KMK
     106static inline unsigned long variable_hash_b(register const unsigned char *var, register int length)
     107{
     108    register unsigned long hash = 0;
     109    for (;;)
     110    {
     111        switch (length)
     112        {
     113            default:
     114            case 16: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     115            case 15: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     116            case 14: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     117            case 13: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     118            case 12: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     119            case 11: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     120            case 10: hash = *var++ + (hash << 6) + (hash << 16) - hash;
     121            case 9:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     122            case 8:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     123            case 7:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     124            case 6:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     125            case 5:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     126            case 4:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     127            case 3:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     128            case 2:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     129            case 1:  hash = *var++ + (hash << 6) + (hash << 16) - hash;
     130            case 0:
     131                break;
     132        }
     133        if (length <= 16)
     134            break;
     135        length -= 16;
     136    }
     137    return hash;
     138}
     139
     140static inline unsigned long variable_hash_a(register const unsigned char *var, register int length)
     141{
     142    register unsigned long hash = ((5381 << 5) + 5381) + *var;
     143    switch (length)
     144    {
     145        default:
     146        case 8: hash = ((hash << 5) + hash) + var[7];
     147        case 7: hash = ((hash << 5) + hash) + var[6];
     148        case 6: hash = ((hash << 5) + hash) + var[5];
     149        case 5: hash = ((hash << 5) + hash) + var[4];
     150        case 4: hash = ((hash << 5) + hash) + var[3];
     151        case 3: hash = ((hash << 5) + hash) + var[2];
     152        case 2: hash = ((hash << 5) + hash) + var[1];
     153        case 1: return hash;
     154        case 0: return 5381; /* shouldn't happen */
     155    }
     156}
     157#endif /* KMK */
     158
    105159static unsigned long
    106160variable_hash_1 (const void *keyv)
    107161{
    108162  struct variable const *key = (struct variable const *) keyv;
     163#ifdef VARIABLE_HASH
     164#ifdef VARIABLE_HASH_STRICT
     165  if (key->hash1 != variable_hash_a (key->name, key->length))
     166    __asm__("int3");
     167  if (key->hash2 && key->hash2 != variable_hash_b (key->name, key->length))
     168    __asm__("int3");
     169#endif
     170  return key->hash1;
     171#else
     172#ifdef KMK
     173  return variable_hash_a (key->name, key->length);
     174#else
    109175  return_STRING_N_HASH_1 (key->name, key->length);
     176#endif
     177#endif
    110178}
    111179
     
    113181variable_hash_2 (const void *keyv)
    114182{
     183#ifdef VARIABLE_HASH
     184  struct variable *key = (struct variable *) keyv;
     185  if (!key->hash2)
     186    key->hash2 = variable_hash_b (key->name, key->length);
     187  return key->hash2;
     188#else
    115189  struct variable const *key = (struct variable const *) keyv;
     190#ifdef KMK
     191  return variable_hash_b (key->name, key->length);
     192#else
    116193  return_STRING_N_HASH_2 (key->name, key->length);
     194#endif
     195#endif
    117196}
    118197
     
    125204  if (result)
    126205    return result;
     206#ifdef KMK /* speed */
     207  {
     208    const char *xs = x->name;
     209    const char *ys = y->name;
     210    switch (x->length)
     211      {
     212        case 8:
     213            result = *(int32_t*)(xs + 4) - *(int32_t*)(ys + 4);
     214            if (result)
     215              return result;
     216            return *(int32_t*)xs - *(int32_t*)ys;
     217        case 7:
     218            result = xs[6] - ys[6];
     219            if (result)
     220                return result;
     221        case 6:
     222            result = *(int32_t*)xs - *(int32_t*)ys;
     223            if (result)
     224                return result;
     225            return *(int16_t*)(xs + 4) - *(int16_t*)(ys + 4);
     226        case 5:
     227            result = xs[4] - ys[4];
     228            if (result)
     229                return result;
     230        case 4:
     231            return *(int32_t*)xs - *(int32_t*)ys;
     232        case 3:
     233            result = xs[2] - ys[2];
     234            if (result)
     235                return result;
     236        case 2:
     237            return *(int16_t*)xs - *(int16_t*)ys;
     238        case 1:
     239            return *xs - *ys;
     240        case 0:
     241            return 0;
     242      }
     243  }
     244#endif /* KMK */
     245#ifdef VARIABLE_HASH_STRICT
     246  if (x->hash1 != variable_hash_a (x->name, x->length))
     247    __asm__("int3");
     248  if (x->hash2 && x->hash2 != variable_hash_b (x->name, x->length))
     249    __asm__("int3");
     250  if (y->hash1 != variable_hash_a (y->name, y->length))
     251    __asm__("int3");
     252  if (y->hash2 && y->hash2 != variable_hash_b (y->name, y->length))
     253    __asm__("int3");
     254#endif
     255#ifdef VARIABLE_HASH
     256
     257  /* hash 1 */
     258  result = (int)x->hash1 - (int)y->hash1;
     259  if (result)
     260    return result;
     261
     262  /* hash 2 */
     263  if (x->hash2 && y->hash2)
     264    {
     265      result = (int)x->hash2 - (int)y->hash2;
     266      if (result)
     267        return result;
     268    }
     269#endif
     270#ifdef KMK
     271  return memcmp (x->name, y->name, x->length);
     272#else
    127273  return_STRING_N_COMPARE (x->name, y->name, x->length);
     274#endif
    128275}
    129276
     
    151298  hash_init (&global_variable_set.table,
    152299#ifdef KMK
    153              8192,
     300             8191,
    154301#else
    155302             VARIABLE_BUCKETS,
     
    180327  var_key.name = (char *) name;
    181328  var_key.length = length;
     329#ifdef VARIABLE_HASH
     330  var_key.hash1 = variable_hash_a (name, length);
     331  var_key.hash2 = 0;
     332#endif
    182333  var_slot = (struct variable **) hash_find_slot (&set->table, &var_key);
    183334
     
    216367  v->name = savestring (name, length);
    217368  v->length = length;
     369#ifdef VARIABLE_HASH
     370  v->hash1 = variable_hash_a (name, length);
     371  v->hash2 = 0;
     372#endif
    218373  hash_insert_at (&set->table, v, var_slot);
    219374  v->value = xstrdup (value);
     
    353508  var_key.name = (char *) name;
    354509  var_key.length = length;
     510#ifdef VARIABLE_HASH
     511  var_key.hash1 = variable_hash_a (name, length);
     512  var_key.hash2 = 0;
     513#endif
    355514
    356515  for (setlist = current_variable_set_list;
     
    438597  var_key.name = (char *) name;
    439598  var_key.length = length;
     599#ifdef VARIABLE_HASH
     600  var_key.hash1 = variable_hash_a (name, length);
     601  var_key.hash2 = 0;
     602#endif
    440603
    441604  return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
     
    9141077  makelevel_key.name = MAKELEVEL_NAME;
    9151078  makelevel_key.length = MAKELEVEL_LENGTH;
     1079#ifdef VARIABLE_HASH
     1080  makelevel_key.hash1 = variable_hash_a (MAKELEVEL_NAME, MAKELEVEL_LENGTH);
     1081  makelevel_key.hash2 = 0;
     1082#endif
    9161083  hash_delete (&table, &makelevel_key);
    9171084
  • trunk/src/gmake/variable.h

    r281 r430  
    5454    char *name;                 /* Variable name.  */
    5555    int length;                 /* strlen (name) */
     56#ifdef VARIABLE_HASH
     57    long hash1;                 /* the primary hash */
     58    long hash2;                 /* the secondary hash */
     59#endif
    5660    char *value;                /* Variable value.  */
    5761    struct floc fileinfo;       /* Where the variable was defined.  */
Note: See TracChangeset for help on using the changeset viewer.