pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: stralloc.c,v 1.200 2005/05/17 22:27:42 nilsson Exp $ + || $Id: stralloc.c,v 1.201 2005/11/03 16:19:50 grubba Exp $   */      #include "global.h"   #include "stralloc.h"   #include "pike_macros.h"   #include "dynamic_buffer.h"   #include "pike_macros.h"   #include "pike_memory.h"   #include "pike_error.h"   #include "gc.h"
pike.git/src/stralloc.c:198:    Pike_fatal("string zero termination foul!\n");   #endif    switch(s->size_shift)    {    case 0: STR0(s)[pos]=value; break;    case 1: STR1(s)[pos]=value; break;    case 2: STR2(s)[pos]=value; break;    default:    Pike_fatal("Illegal shift size!\n");    } +  s->flags |= STRING_NOT_HASHED;   }      #ifdef PIKE_DEBUG   PMOD_EXPORT struct pike_string *debug_check_size_shift(struct pike_string *a,    int shift)   {    if(a->size_shift != shift)    Pike_fatal("Wrong STRX macro used!\n");    return a;   }
pike.git/src/stralloc.c:539:    for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h);   #endif   }      /* Allocation of strings */      /* Allocate some fixed string sizes with BLOCK_ALLOC. */      /* Use the BLOCK_ALLOC() stuff for short strings */    + #undef INIT_BLOCK + #define INIT_BLOCK(NEW_STR) do { \ +  (NEW_STR)->refs = 1; \ +  (NEW_STR)->flags = \ +  STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \ +  } while(0) +    #define SHORT_STRING_BLOCK 256   #define SHORT_STRING_THRESHOLD 15 /* % 4 === -1 */      struct short_pike_string0 {    PIKE_STRING_CONTENTS;    p_wchar0 str[SHORT_STRING_THRESHOLD+1];   };      struct short_pike_string1 {    PIKE_STRING_CONTENTS;
pike.git/src/stralloc.c:561:      struct short_pike_string2 {    PIKE_STRING_CONTENTS;    p_wchar2 str[SHORT_STRING_THRESHOLD+1];   };      BLOCK_ALLOC(short_pike_string0, SHORT_STRING_BLOCK)   BLOCK_ALLOC(short_pike_string1, SHORT_STRING_BLOCK)   BLOCK_ALLOC(short_pike_string2, SHORT_STRING_BLOCK)    + #undef INIT_BLOCK + #define INIT_BLOCK(x) +    #define really_free_short_pike_string(s) do { \    if (!s->size_shift) { \    really_free_short_pike_string0((struct short_pike_string0 *)s); \    } else if (s->size_shift == 1) { \    really_free_short_pike_string1((struct short_pike_string1 *)s); \    DO_IF_DEBUG( \    } else if (s->size_shift != 2) { \    Pike_fatal("Unsupported string shift: %d\n", s->size_shift); \    ) \    } else { \
pike.git/src/stralloc.c:598: Inside #if defined(PIKE_DEBUG)
   struct pike_string *t;   #ifdef PIKE_DEBUG    extern int d_flag;    if(d_flag>10)    verify_shared_strings_tables();   #endif    if (len <= SHORT_STRING_THRESHOLD) {    t=(struct pike_string *)alloc_short_pike_string0();    } else {    t=(struct pike_string *)xalloc(len + sizeof(struct pike_string)); +  t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED;    } -  +  t->refs = 1;    t->str[len]=0;    t->len=len;    t->size_shift=0;    return t;   }      static void link_pike_string(struct pike_string *s, size_t hval)   {    size_t h; -  +  + #ifdef PIKE_DEBUG +  if (!(s->flags & STRING_NOT_SHARED)) { +  debug_dump_pike_string(s, 70); +  Pike_fatal("String already linked.\n"); +  } + #endif +     LOCK_BUCKET(hval);    h=HMODULO(hval); -  s->refs = 0; +     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 > MAX_AVG_LINK_LENGTH * htable_size)    stralloc_rehash();      #ifndef HASH_PREFIX    /* These heuristics might require tuning! /Hubbe */    if(need_more_hash_prefix_depth > MAX_AVG_LINK_LENGTH * 4)    {
pike.git/src/stralloc.c:703: Inside #if defined(PIKE_DEBUG)
   t = (struct pike_string *)alloc_short_pike_string1();   #ifdef PIKE_DEBUG    } else if (shift != 2) {    Pike_fatal("Unsupported string shift: %d\n", shift);   #endif /* PIKE_DEBUG */    } else {    t = (struct pike_string *)alloc_short_pike_string2();    }    } else {    t=(struct pike_string *)xalloc((len<<shift) + sizeof(struct pike_string)); +  t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED;    } -  +  t->refs = 1;    t->len=len;    t->size_shift=shift;    low_set_index(t,len,0);    return t;   }    -  + PMOD_EXPORT void hash_string(struct pike_string *s) + { +  if (!(s->flags & STRING_NOT_HASHED)) return; +  s->hval=do_hash(s); +  s->flags &= ~STRING_NOT_HASHED; + } +    /*    * This function assumes that the shift size is already the minimum it    * can be.    */   PMOD_EXPORT struct pike_string *low_end_shared_string(struct pike_string *s)   {    ptrdiff_t len;    size_t h;    struct pike_string *s2;       len = s->len; -  h = do_hash(s); +  if (s->flags & STRING_NOT_HASHED) { +  h = s->hval = do_hash(s); +  s->flags &= ~STRING_NOT_HASHED; +  }    s2 = internal_findstring(s->str, len, s->size_shift, h);   #ifdef PIKE_DEBUG    if(s2==s)    Pike_fatal("end_shared_string called twice! (or something like that)\n");   #endif       if(s2)    { -  really_free_pike_string(s); +  free_string(s);    s = s2; -  +  add_ref(s);    }else{    link_pike_string(s, h);    } -  add_ref(s); +        return s;      }      /*    * This function checks if the shift size can be decreased before    * entering the string in the shared string table    */   PMOD_EXPORT struct pike_string *end_shared_string(struct pike_string *s)
pike.git/src/stralloc.c:760:    {    default:    Pike_fatal("ARGHEL! size_shift:%d\n", s->size_shift);       case 2:    switch(find_magnitude2(STR2(s),s->len))    {    case 0:    s2=begin_shared_string(s->len);    convert_2_to_0(STR0(s2),STR2(s),s->len); -  really_free_pike_string(s); +  free_string(s);    s=s2;    break;       case 1:    s2=begin_wide_shared_string(s->len,1);    convert_2_to_1(STR1(s2),STR2(s),s->len); -  really_free_pike_string(s); +  free_string(s);    s=s2;    /* Fall though */    }    break;       case 1:    if(!find_magnitude1(STR1(s),s->len))    {    s2=begin_shared_string(s->len);    convert_1_to_0(STR0(s2),STR1(s),s->len); -  really_free_pike_string(s); +  free_string(s);    s=s2;    }    break;       case 0: break;    }       return low_end_shared_string(s);   }   
pike.git/src/stralloc.c:805:   #endif    if( str->len <= SHORT_STRING_THRESHOLD ?    (len <= SHORT_STRING_THRESHOLD) :    (len > SHORT_STRING_THRESHOLD) && str->len > len/2 )    {    str->len=len;    str->str[len]=0;    return end_shared_string(str);    }    tmp = make_shared_binary_pcharp(MKPCHARP_STR(str),len); -  really_free_pike_string(str); +  free_string(str);    return tmp;   }         PMOD_EXPORT struct pike_string * debug_make_shared_binary_string(const char *str,size_t len)   {    struct pike_string *s;    ptrdiff_t h = StrHash(str, len);       s = internal_findstring(str,len,0,h);
pike.git/src/stralloc.c:961: Inside #if defined(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_really_free_string(struct pike_string *s)   {
pike.git/src/stralloc.c:1004: Inside #if defined(PIKE_DEBUG)
   Pike_fatal("Freeing shared string again!\n");       if(((ptrdiff_t)s->next) & 1)    Pike_fatal("Freeing shared string again, memory corrupt or other bug!\n");    }    if ((s->size_shift < 0) || (s->size_shift > 2)) {    Pike_fatal("Freeing string with bad shift (0x%08x); could it be a type?\n",    s->size_shift);    }   #endif +  if (!(s->flags & STRING_NOT_SHARED))    unlink_pike_string(s);    really_free_pike_string(s);    GC_FREE_SIMPLE_BLOCK(s);   }      PMOD_EXPORT void debug_free_string(struct pike_string *s)   {    if(!sub_ref(s))    really_free_string(s);   }
pike.git/src/stralloc.c:1480:    }       if(!r)    {    r=begin_wide_shared_string(size, a->size_shift);    if (a->len <= size) {    MEMCPY(r->str, a->str, a->len<<a->size_shift);    } else {    MEMCPY(r->str, a->str, size<<a->size_shift);    } -  really_free_pike_string(a); +  free_string(a);    }       r->len=size;    low_set_index(r,size,0);    return r;   }      /* Returns an unlinked string ready for end_shared_string */   PMOD_EXPORT struct pike_string *realloc_shared_string(struct pike_string *a,    ptrdiff_t size)
pike.git/src/stralloc.c:1653: Inside #if defined(PIKE_DEBUG)
   struct pike_string *old;   #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. */ -  really_free_pike_string(a); +  free_string(a);    add_ref(a = old);    } else {    link_pike_string(a, a->hval);    add_ref(a);    }    }else{    a = end_shared_string(a);    }    return a;    }else{
pike.git/src/stralloc.c:1698:      PMOD_EXPORT struct pike_string *add_and_free_shared_strings(struct pike_string *a,    struct pike_string *b)   {    ptrdiff_t alen = a->len;    if(a->size_shift == b->size_shift)    {    a = realloc_shared_string(a,alen + b->len);    MEMCPY(a->str+(alen<<a->size_shift),b->str,b->len<<b->size_shift);    free_string(b); +  a->flags |= STRING_NOT_HASHED;    return end_shared_string(a);    }else{    struct pike_string *ret=add_shared_strings(a,b);    free_string(a);    free_string(b);    return ret;    }   }      
pike.git/src/stralloc.c:2093:   /* Doesn't touch or sanity check s->known_shift. */   {    if(mag > s->s->size_shift)    {    struct pike_string *n;    ptrdiff_t l = s->s->len + chars + s->malloced;    n=begin_wide_shared_string(l,mag);    pike_string_cpy(MKPCHARP_STR(n),s->s);    n->len=s->s->len;    s->s->len = s->malloced; /* Restore the real length */ -  really_free_pike_string(s->s); +  free_string(s->s);    s->malloced=l;    s->s=n;    }    else if(s->s->len+chars > s->malloced)    {    ptrdiff_t newlen = MAXIMUM(s->malloced*2,    s->s->len + chars);    ptrdiff_t oldlen = s->s->len;       s->s->len = s->malloced; /* Restore the real length */
pike.git/src/stralloc.c:2771:   {    s->known_shift=0;    s->s->len=0;    /* Ensure NUL-termination */    s->s->str[0] = 0;   }      PMOD_EXPORT void free_string_builder(struct string_builder *s)   {    s->s->len = s->malloced; -  really_free_pike_string(s->s); +  free_string(s->s);   }      PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s)   {    /* Ensure NUL-termination */    low_set_index(s->s,s->s->len,0);    if (s->s->len <= SHORT_STRING_THRESHOLD) {    ptrdiff_t len = s->s->len;    s->s->len = s->malloced;    s->s = realloc_unlinked_string(s->s, len);