pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:33: Inside #if (SIZEOF_LONG == 4) && defined(_LP64)
  #if (SIZEOF_LONG == 4) && defined(_LP64)   /* Kludge for gcc and the system header files not using the same model... */   #undef LONG_MIN   #undef LONG_MAX   #undef ULONG_MAX   #define LONG_MIN INT_MIN   #define LONG_MAX INT_MAX   #define ULONG_MAX UINT_MAX   #endif    - #if PIKE_RUN_UNLOCKED - /* Make this bigger when we get lightweight threads */ - #define BUCKET_LOCKS 2048 - static PIKE_MUTEX_T *bucket_locks; -  - #define BUCKETLOCK(HVAL) \ -  (bucket_locks + (HMODULO(hval__) & (BUCKET_LOCKS-1))) -  - #define LOCK_BUCKET(HVAL) do { \ -  size_t hval__=(HVAL); \ -  PIKE_MUTEX_T *bucket_lock; \ -  while(1) \ -  { \ -  bucket_lock=BUCKETLOCK(hval__); \ -  mt_lock(bucket_lock); \ -  if(bucket_lock == BUCKETLOCK(hval__)) \ -  break; \ -  mt_unlock(bucket_lock); \ -  } \ - }while(0) -  - #define UNLOCK_BUCKET(HVAL) do { \ -  size_t hval__=(HVAL); \ -  mt_unlock(BUCKETLOCK(hval__)); \ - }while(0) -  - #else - #define LOCK_BUCKET(HVAL) - #define UNLOCK_BUCKET(HVAL) - #endif /* PIKE_RUN_UNLOCKED */ -  +    #define BEGIN_HASH_SIZE 1024      static unsigned int hash_prefix_len=64;   static unsigned int need_more_hash_prefix_depth=0;      static unsigned int need_new_hashkey_depth=0;   static size_t hashkey = 0;      static unsigned INT32 htable_size=0;   static unsigned int hashprimes_entry=0;
pike.git/src/stralloc.c:407:      static void locate_problem(int (*isproblem)(const struct pike_string *))   {    unsigned INT32 e;    struct pike_string *s;    DM(struct memhdr *yes=alloc_memhdr());    DM(struct memhdr *no=alloc_memhdr());       for(e=0;e<htable_size;e++)    { -  LOCK_BUCKET(e); +     for(s=base_table[e];s;s=s->next)    {    if(isproblem(s))    {    fprintf(stderr,"***Guilty string:\n");    debug_dump_pike_string(s, 70);    DM(add_marks_to_memhdr(yes,s));    }else{    DM(add_marks_to_memhdr(no,s));    }    } -  UNLOCK_BUCKET(e); +     }       DM(fprintf(stderr,"Plausible problem location(s):\n"));    DM(dump_memhdr_locations(yes,0,0));       DM(fprintf(stderr,"More Plausible problem location(s):\n"));    DM(dump_memhdr_locations(yes,no,0));   }      static int bad_pointer(const struct pike_string *s)
pike.git/src/stralloc.c:464:    ptrdiff_t len,    int size_shift,    size_t hval)   {    struct pike_string *curr;   //,**prev, **base;    unsigned int depth=0;    unsigned int prefix_depth=0;       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_fatal("String with no references.\n");    }
pike.git/src/stralloc.c:487:       if ( len == curr->len &&    size_shift == curr->size_shift &&    hval == curr->hval &&    ( 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++;    if (curr->len > (ptrdiff_t)hash_prefix_len)    prefix_depth++;    }    if (depth > need_new_hashkey_depth) {    /* Keep track of whether the hashtable is getting unbalanced. */    need_new_hashkey_depth = depth;    }
pike.git/src/stralloc.c:510: Inside #if 0
   {   #if 0    fprintf(stderr,    "prefix_depth=%d num_strings=%d need_more_hash_prefix_depth=%d\n"    " hash_prefix_len=%d\n",    prefix_depth, num_strings, need_more_hash_prefix_depth,    hash_prefix_len);   #endif /* 0 */    need_more_hash_prefix_depth = prefix_depth;    } -  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 *binary_findstring_pcharp(PCHARP foo, ptrdiff_t l)   {
pike.git/src/stralloc.c:626:   }      static void stralloc_rehash(void)   {    int h,old;    struct pike_string **old_base;       old=htable_size;    old_base=base_table;    - #ifdef PIKE_RUN_UNLOCKED -  mt_lock(bucket_locks); -  if(old != htable_size) -  { -  /* Someone got here before us */ -  mt_lock(bucket_locks); -  return; -  } -  -  /* Now that we have bucket zero, the hash table -  * cannot change, go ahead and lock ALL buckets. -  * NOTE: bucket zero is already locked -  */ -  for(h=1;h<BUCKET_LOCKS;h++) mt_lock(bucket_locks+h); - #endif -  +     SET_HSIZE( ++hashprimes_entry );       base_table=xcalloc(sizeof(struct pike_string *), htable_size);       need_more_hash_prefix_depth = 0;       for(h=0;h<old;h++)    rehash_string_backwards(old_base[h]);       if(old_base)    free(old_base); -  - #ifdef PIKE_RUN_UNLOCKED -  for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h); - #endif +    }      /* Allocation of strings */      /* Without the str at the end, to get the size of the header. */   struct pike_string_hdr {    PIKE_STRING_CONTENTS;   };      /* Allocate some fixed string sizes with BLOCK_ALLOC. */
pike.git/src/stralloc.c:734: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if (!(s->flags & STRING_NOT_SHARED)) {    debug_dump_pike_string(s, 70);    Pike_fatal("String already linked.\n");    }       if (PIKE_MEM_NOT_DEF_RANGE (s->str, (s->len + 1) << s->size_shift))    Pike_fatal ("Got undefined contents in pike string %p.\n", s);   #endif    -  LOCK_BUCKET(hval); +     h=HMODULO(hval);    s->next = base_table[h];    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();    }       /* These heuristics might require tuning! /Hubbe */    if((need_more_hash_prefix_depth > 4) ||    (need_new_hashkey_depth > 128))    {    /* Changed heuristic 2005-01-17:
pike.git/src/stralloc.c:777:    /* This could in theory have a pretty ugly complexity    * /Hubbe    */       if (need_new_hashkey_depth > 128) {    /* A simple mixing function. */    hashkey ^= (hashkey << 5) ^ (current_time.tv_sec ^ current_time.tv_usec);    need_new_hashkey_depth = 0;    }    - #ifdef PIKE_RUN_UNLOCKED -  mt_lock(bucket_locks); -  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 -  +     if (need_more_hash_prefix_depth > 4) -  { +     hash_prefix_len=hash_prefix_len*2; - #if 0 -  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_more_hash_prefix_depth=0;       for(h=0;h<htable_size;h++)    {    struct pike_string *tmp=base_table[h];    base_table[h]=0;    while(tmp)
pike.git/src/stralloc.c:818:    struct pike_string *tmp2=tmp; /* First unlink */    tmp=tmp2->next;       tmp2->hval=do_hash(tmp2); /* compute new hash value */    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 +     }   }      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();
pike.git/src/stralloc.c:1129:    INT32 len;    for(len=0;str[len];len++);    return debug_make_shared_binary_string2(str,len);   }      /*** Free strings ***/      static void unlink_pike_string(struct pike_string *s)   {    size_t h; -  LOCK_BUCKET(s->hval); +     h= HMODULO(s->hval);    propagate_shared_string(s,h);   #ifdef PIKE_DEBUG    if (base_table[h] != s) {    Pike_fatal("propagate_shared_string() failed. Probably got bogus pike_string.\n");    }   #endif /* PIKE_DEBUG */    base_table[h]=s->next;   #ifdef PIKE_DEBUG    s->next=(struct pike_string *)(ptrdiff_t)-1;   #endif    num_strings--; -  UNLOCK_BUCKET(s->hval); +     s->flags |= STRING_NOT_SHARED;   }      PMOD_EXPORT void do_free_string(struct pike_string *s)   {    if (s)    free_string(s);   }      PMOD_EXPORT void do_free_unlinked_pike_string(struct pike_string *s)
pike.git/src/stralloc.c:1221:    {    long alloced_strings[8] = {0,0,0,0,0,0,0,0};    long alloced_bytes[8] = {0,0,0,0,0,0,0,0};    long num_distinct_strings[8] = {0,0,0,0,0,0,0,0};    long bytes_distinct_strings[8] = {0,0,0,0,0,0,0,0};    long overhead_bytes[8] = {0,0,0,0,0,0,0,0};    unsigned INT32 e;    struct pike_string *p;    for(e=0;e<htable_size;e++)    { -  LOCK_BUCKET(e); +     for(p=base_table[e];p;p=p->next)    {    int is_short = (p->len <= SHORT_STRING_THRESHOLD);    int key = (is_short?0:4) | p->size_shift;    num_distinct_strings[key]++;    if (is_short) {    bytes_distinct_strings[key] +=    DO_ALIGN(SHORT_STRING_THRESHOLD << p->size_shift, sizeof(void *));    } else {    bytes_distinct_strings[key] +=    DO_ALIGN(p->len << p->size_shift, sizeof(void *));    }    alloced_strings[key] += p->refs;    alloced_bytes[key] +=    p->refs*DO_ALIGN((p->len+3) << p->size_shift,sizeof(void *));    } -  UNLOCK_BUCKET(e); +     }    string_builder_sprintf(&s,    "\nShared string hash table:\n"    "-------------------------\n"    "\n"    "Type Count Distinct Bytes Actual Overhead %%\n"    "------------------------------------------------------------\n");    for(e = 0; e < 8; e++) {    int shift = e & 3;    ptrdiff_t overhead;
pike.git/src/stralloc.c:1380: Inside #if defined(PIKE_DEBUG)
  PMOD_EXPORT void verify_shared_strings_tables(void)   {    unsigned INT32 e, h, num=0;    struct pike_string *s;       last_stralloc_verify=current_do_debug_cycle;       for(e=0;e<htable_size;e++)    {    h=0; -  LOCK_BUCKET(e); +     for(s=base_table[e];s;s=s->next)    {    num++;    h++;       if (bad_pointer(s)) {    Pike_fatal("Odd string pointer in string table!\n");    }       if(s->len < 0)
pike.git/src/stralloc.c:1426: Inside #if defined(PIKE_DEBUG)
      if(h>10000)    {    struct pike_string *s2;    for(s2=s;s2;s2=s2->next)    if(s2 == s)    Pike_fatal("Shared string table is cyclic.\n");    h=0;    }    } -  UNLOCK_BUCKET(e); +     }    if(num != num_strings)    Pike_fatal("Num strings is wrong %d!=%d\n",num,num_strings);   }      int safe_debug_findstring(struct pike_string *foo)   {    unsigned INT32 e;    if(!base_table) return 0;    for(e=0;e<htable_size;e++)    {    struct pike_string *p; -  LOCK_BUCKET(e); +     for(p=base_table[e];p;p=p->next)    {    if(p==foo)    { -  UNLOCK_BUCKET(e); +     return 1;    }    } -  UNLOCK_BUCKET(e); +     }    return 0;   }      struct pike_string *debug_findstring(const struct pike_string *foo)   {    struct pike_string *tmp;    tmp=propagate_shared_string(foo, HMODULO(foo->hval));      #if 0    if(!tmp)    {    unsigned INT32 e;    struct pike_string *tmp2;    fprintf(stderr,"String %p %ld %ld %s\n",    foo,    (long)foo->hval,    (long)foo->len,    foo->str);    -  LOCK_BUCKET(foo->hval); +     fprintf(stderr,"------ %p %ld\n",    base_table[HMODULO(foo->hval)],    foo->hval);    for(tmp2=base_table[HMODULO(foo->hval)];tmp2;tmp2=tmp2->next)    {    if(tmp2 == tmp)    fprintf(stderr,"!!%p!!->",tmp2);    else    fprintf(stderr,"%p->",tmp2);    }    fprintf(stderr,"0\n"); -  UNLOCK_BUCKET(foo->hval); +        for(e=0;e<htable_size;e++)    { -  LOCK_BUCKET(e); +     for(tmp2=base_table[e];tmp2;tmp2=tmp2->next)    {    if(tmp2 == tmp)    fprintf(stderr,"String found in hashbin %ld (not %ld)\n",    (long)e,    (long)HMODULO(foo->hval));    } -  UNLOCK_BUCKET(e); +     }    }   #endif /* 0 */    return tmp;   }      PMOD_EXPORT void debug_dump_pike_string(struct pike_string *s, INT32 max)   {    INT32 e;    fprintf(stderr,"0x%p: %ld refs, len=%ld, size_shift=%d, hval=%lux (%lx)\n",
pike.git/src/stralloc.c:1544: Inside #if defined(PIKE_DEBUG)
   else    fprintf(stderr,"\"\n");   }      void dump_stralloc_strings(void)   {    unsigned INT32 e;    struct pike_string *p;    for(e=0;e<htable_size;e++)    { -  LOCK_BUCKET(e); +     for(p=base_table[e];p;p=p->next) {    debug_dump_pike_string(p, 70);   #ifdef DEBUG_MALLOC    debug_malloc_dump_references (p, 2, 1, 0);   #endif    } -  UNLOCK_BUCKET(e); +     }   }      #endif /* PIKE_DEBUG */         /*** String compare functions ***/      /* does not take locale into account */   int low_quick_binary_strcmp(const char *a, ptrdiff_t alen,
pike.git/src/stralloc.c:2254:    return end_shared_string(ret);   }      /*** init/exit memory ***/   void init_shared_string_table(void)   {    for(hashprimes_entry=0;hashprimes[hashprimes_entry]<BEGIN_HASH_SIZE;hashprimes_entry++);    SET_HSIZE(hashprimes_entry);    base_table=xcalloc(sizeof(struct pike_string *), htable_size);    - #ifdef PIKE_RUN_UNLOCKED -  { -  int h; -  bucket_locks=xalloc(sizeof(PIKE_MUTEX_T)*BUCKET_LOCKS); -  for(h=0;h<BUCKET_LOCKS;h++) mt_init(bucket_locks + h); -  } - #endif +     empty_pike_string = make_shared_string("");    empty_pike_string->flags |= STRING_CONTENT_CHECKED | STRING_IS_LOWERCASE | STRING_IS_UPPERCASE;    empty_pike_string->min = empty_pike_string->max = 0;   }      #ifdef DO_PIKE_CLEANUP   PMOD_EXPORT struct shared_string_location *all_shared_string_locations;   #endif      
pike.git/src/stralloc.c:2307: Inside #if defined(DO_PIKE_CLEANUP) and #if defined(PIKE_DEBUG)
   "(%"PRINTSIZET"d bytes) (zapped)\n",num,size);   #ifdef PIKE_DEBUG    dump_stralloc_strings();   #endif    }    }   #endif       for(e=0;e<htable_size;e++)    { -  LOCK_BUCKET(e); +     for(s=base_table[e];s;s=next)    {    next=s->next; - #ifdef REALLY_FREE -  free_unlinked_pike_string(s); - #else +     s->next=0; - #endif +     }    base_table[e]=0; -  UNLOCK_BUCKET(e); +     }    free(base_table);    base_table=0;    num_strings=0;      #ifdef DO_PIKE_CLEANUP    ba_destroy(&string_allocator);   #endif /* DO_PIKE_CLEANUP */   }   
pike.git/src/stralloc.c:2355:    size_t num_=0, size_=0;    if(!base_table)    {    *num=*size=0;    return;    }    size_+=htable_size * sizeof(struct pike_string *);    for(e=0;e<htable_size;e++)    {    struct pike_string *p; -  LOCK_BUCKET(e); +     for(p=base_table[e];p;p=p->next)    {    num_++;    size_ += memory_in_string (p);    } -  UNLOCK_BUCKET(e); +     }   #ifdef PIKE_DEBUG    if(num_strings != num_)    Pike_fatal("Num strings is wrong! %d!=%d.\n",num_strings, num_);   #endif    num[0]=num_;    size[0]=size_;   }      PMOD_EXPORT void visit_string (struct pike_string *s, int action)
pike.git/src/stralloc.c:2420:   }   #endif      struct pike_string *next_pike_string (struct pike_string *s)   {    struct pike_string *next = s->next;    if (!next) {    size_t h = s->hval;    do {    h++; -  LOCK_BUCKET(h); +     h = HMODULO(h);    next = base_table[h]; -  UNLOCK_BUCKET(h); +     } while (!next);    }    return next;   }      PMOD_EXPORT void init_string_builder_alloc(struct string_builder *s, ptrdiff_t length, int mag)   {    s->s=begin_wide_shared_string(length,mag);    s->malloced=length;    s->known_shift=0;
pike.git/src/stralloc.c:3778:       return num * sign;       overflow:    /* Return an overflow error. */    errno = ERANGE;    return HUGE_VAL * sign;       underflow:    /* Return an underflow error. */ - #if 0 -  if (endptr != NULL) -  *endptr = nptr; - #endif +     errno = ERANGE;    return 0.0;       noconv:    /* There was no number. */    if (endptr != NULL)    *endptr = nptr;    return 0.0;   }