pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:66:    mt_unlock(BUCKETLOCK(hval__)); \   }while(0)      #else   #define LOCK_BUCKET(HVAL)   #define UNLOCK_BUCKET(HVAL)   #endif /* PIKE_RUN_UNLOCKED */      #define BEGIN_HASH_SIZE 1024    - /* Experimental dynamic hash length */ - #ifndef HASH_PREFIX - static unsigned int HASH_PREFIX=64; + static unsigned int hash_prefix_len=64;   static unsigned int need_more_hash_prefix_depth=0; - #endif +       /* Force a new hashkey to be generated early during init. */   static unsigned int need_new_hashkey_depth=0xffff;   static size_t hashkey = 0;      static unsigned INT32 htable_size=0;   static unsigned int hashprimes_entry=0;   static struct pike_string **base_table=0;   static unsigned INT32 num_strings=0;   PMOD_EXPORT struct pike_string *empty_pike_string = 0;      /*** Main string hash function ***/      #define StrHash(s,len) low_do_hash(s,len,0) - #define low_do_hash(STR,LEN,SHIFT) low_hashmem( (STR), (LEN)<<(SHIFT), HASH_PREFIX<<(SHIFT), hashkey ) + #define low_do_hash(STR,LEN,SHIFT) low_hashmem( (STR), (LEN)<<(SHIFT), hash_prefix_len<<(SHIFT), hashkey )   #define do_hash(STR) low_do_hash(STR->str,STR->len,STR->size_shift)      /* Returns true if str could contain n. */   PMOD_EXPORT int string_range_contains( struct pike_string *str, int n )   {    INT32 min, max;    check_string_range( str, 1, &min, &max );    if( n >= min && n <= max )    return 1;    return 0;
pike.git/src/stralloc.c:471:    * This assumes that the string is minimized!!!!    */   static struct pike_string *internal_findstring(const char *s,    ptrdiff_t len,    int size_shift,    size_t hval)   {    struct pike_string *curr;   //,**prev, **base;    unsigned int depth=0; - #ifndef HASH_PREFIX +     unsigned int prefix_depth=0; - #endif +     size_t h;    LOCK_BUCKET(hval);    h=HMODULO(hval);    for(curr = base_table[h]; curr; curr = curr->next)    {   #ifdef PIKE_DEBUG    if(curr->refs<1)    {    debug_dump_pike_string(curr, 70);    locate_problem(has_zero_refs);
pike.git/src/stralloc.c:502:    ( curr->str == s ||    !MEMCMP(curr->str, s,len<<size_shift))) /* found it */    {    /* *prev = curr->next; */    /* curr->next = *base; */    /* *base = curr; */    UNLOCK_BUCKET(hval);    return curr; /* pointer to string */    }    depth++; - #ifndef HASH_PREFIX -  if (curr->len > (ptrdiff_t)HASH_PREFIX) +  if (curr->len > (ptrdiff_t)hash_prefix_len)    prefix_depth++; - #endif +     }    if (depth > need_new_hashkey_depth) {    /* Keep track of whether the hashtable is getting unbalanced. */    need_new_hashkey_depth = depth;    } - #ifndef HASH_PREFIX +     /* These heuruistics might require tuning! /Hubbe */    if (prefix_depth > need_more_hash_prefix_depth)    {   #if 0    fprintf(stderr,    "prefix_depth=%d num_strings=%d need_more_hash_prefix_depth=%d\n" -  " HASH_PREFIX=%d\n", +  " hash_prefix_len=%d\n",    prefix_depth, num_strings, need_more_hash_prefix_depth, -  HASH_PREFIX); +  hash_prefix_len);   #endif /* 0 */    need_more_hash_prefix_depth = prefix_depth;    } - #endif /* !HASH_PREFIX */ +     UNLOCK_BUCKET(hval);    return 0; /* not found */   }      struct pike_string *binary_findstring(const char *foo, ptrdiff_t l)   {    return internal_findstring(foo, l, 0, StrHash(foo,l));   }      struct pike_string *findstring(const char *foo)
pike.git/src/stralloc.c:725:    base_table[h] = s;    s->hval=hval;    s->flags &= ~(STRING_NOT_HASHED|STRING_NOT_SHARED);    num_strings++;    UNLOCK_BUCKET(hval);       if(num_strings > htable_size) {    stralloc_rehash();    }    - #ifndef HASH_PREFIX +     /* These heuristics might require tuning! /Hubbe */    if((need_more_hash_prefix_depth > 4) ||    (need_new_hashkey_depth > 128))    {    /* Changed heuristic 2005-01-17:    * -  * Increase HASH_PREFIX if there's some bucket containing +  * Increase hash_prefix_len if there's some bucket containing    * more than 4 strings that are longer -  * than HASH_PREFIX. +  * than hash_prefix_len.    * /grubba    *    * Changed heuristic 2011-12-30:    *    * Generate a new hash key if there's some bucket containing    * more than 16 strings. This ought to    * suffice to alleviate the #hashdos vulnerability.    *    * /grubba    */
pike.git/src/stralloc.c:762: Inside #if undefined(HASH_PREFIX) and #if defined(PIKE_RUN_UNLOCKED)
   if(need_more_hash_prefix_depth <= 4)    {    /* Someone got here before us */    mt_lock(bucket_locks);    return;    }    for(h=1;h<BUCKET_LOCKS;h++) mt_lock(bucket_locks+h);   #endif       /* A simple mixing function. */ -  hashkey ^= (hashkey << 5) | (current_time.tv_sec ^ current_time.tv_usec); +  hashkey ^= (hashkey << 5) ^ (current_time.tv_sec ^ current_time.tv_usec);    -  if (need_more_hash_prefix_depth > 4) { -  HASH_PREFIX=HASH_PREFIX*2; +  if (need_more_hash_prefix_depth > 4) +  { +  hash_prefix_len=hash_prefix_len*2;   #if 0 -  fprintf(stderr, "Doubling HASH_PREFIX to %d and rehashing\n", -  HASH_PREFIX); +  fprintf(stderr, "Doubling hash_prefix_len to %d and rehashing\n", +  hash_prefix_len);   #endif /* 0 */    }    /* NOTE: No need to update to the correct values, since that will    * be done on demand.    */    need_new_hashkey_depth = 0;    need_more_hash_prefix_depth=0;       for(h=0;h<htable_size;h++)    {
pike.git/src/stralloc.c:798: Inside #if undefined(HASH_PREFIX)
   h2=HMODULO(tmp2->hval);       tmp2->next=base_table[h2]; /* and re-hash */    base_table[h2]=tmp2;    }    }   #ifdef PIKE_RUN_UNLOCKED    for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h);   #endif    } - #endif /* !HASH_PREFIX */ +    }      PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int shift)   {    struct pike_string *t = NULL;   #ifdef PIKE_DEBUG    extern int d_flag;    if(d_flag>10)    verify_shared_strings_tables();   #endif
pike.git/src/stralloc.c:836:    t->len=len;    t->size_shift=shift;    DO_IF_DEBUG(t->next = NULL);    low_set_index(t,len,0);    return t;   }      PMOD_EXPORT void hash_string(struct pike_string *s)   {    if (!(s->flags & STRING_NOT_HASHED)) return; -  /* if( s->len < HASH_PREFIX ) */ +  /* if( s->len < hash_prefix_len ) */    /* check_string_range( s, 0, 0, 0 ); */    s->hval=do_hash(s);    s->flags &= ~STRING_NOT_HASHED;   }      /*    * This function assumes that the shift size is already the minimum it    * can be.    */   struct pike_string *low_end_shared_string(struct pike_string *s)
pike.git/src/stralloc.c:1948:          /* We now know that the string has the right character size */    if(a->refs==1)    {    /* One ref - destructive mode */       unlink_pike_string(a);    low_set_index(a, index, c);    CLEAR_STRING_CHECKED(a); -  if((((unsigned int)index) >= HASH_PREFIX) && (index < a->len-8)) +  if((((unsigned int)index) >= hash_prefix_len) && (index < a->len-8))    {    struct pike_string *old; -  +  /* Doesn't change hash value - sneak it in there */   #ifdef PIKE_DEBUG    if (wrong_hash(a)) {    Pike_fatal("Broken hash optimization.\n");    }   #endif -  /* Doesn't change hash value - sneak it in there */ +     old = internal_findstring(a->str, a->len, a->size_shift, a->hval);    if (old) {    /* The new string is equal to some old string. */    free_string(a);    add_ref(a = old);    } else {    link_pike_string(a, a->hval);    }    }else{    a = end_shared_string(a);