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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.