pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:8:   #include "stralloc.h"   #include "pike_macros.h"   #include "dynamic_buffer.h"   #include "pike_macros.h"   #include "pike_memory.h"   #include "error.h"   #include "gc.h"   #include "stuff.h"   #include "bignum.h"   #include "interpret.h" + #include "block_alloc.h"      #include <errno.h>   #include <float.h>   #include <ctype.h>   #include <math.h>      #ifndef HUGE   #define HUGE HUGE_VAL   #endif /*!HUGE*/    - RCSID("$Id: stralloc.c,v 1.106 2000/10/20 10:06:50 grubba Exp $"); + RCSID("$Id: stralloc.c,v 1.107 2000/11/25 17:00:17 grubba Exp $");      #define BEGIN_HASH_SIZE 997   #define MAX_AVG_LINK_LENGTH 3      /* Experimental dynamic hash length */   #ifndef HASH_PREFIX   static unsigned int HASH_PREFIX=64;   static unsigned int need_more_hash_prefix=0;   #endif   
pike.git/src/stralloc.c:407:    for(h=0;h<old;h++)    rehash_string_backwards(old_base[h]);       if(old_base)    free((char *)old_base);   }         /*** Make new strings ***/    + /* Use the BLOCK_ALLOC() stuff for short strings */ +  + #define SHORT_STRING_BLOCK 256 + #define SHORT_STRING_THRESHOLD 16 +  + struct short_pike_string0 { +  struct pike_string str; +  p_wchar0 data[SHORT_STRING_THRESHOLD]; + }; +  + struct short_pike_string1 { +  struct pike_string str; +  p_wchar1 data[SHORT_STRING_THRESHOLD]; + }; +  + struct short_pike_string2 { +  struct pike_string str; +  p_wchar2 data[SHORT_STRING_THRESHOLD]; + }; +  + #undef BLOCK_ALLOC_NEXT + #define BLOCK_ALLOC_NEXT str.next +  + 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 BLOCK_ALLOC_NEXT + #define BLOCK_ALLOC_NEXT next +  + #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) { \ +  fatal("Unsupported string shift: %d\n", s->size_shift); \ +  ) \ +  } else { \ +  really_free_short_pike_string2((struct short_pike_string2 *)s); \ +  } \ +  } while(0) +  + #define really_free_pike_string(s) do { \ +  if (s->len <= SHORT_STRING_THRESHOLD) { \ +  really_free_short_pike_string(s); \ +  } else { \ +  debug_free((char *)s, DMALLOC_LOCATION(), 1); \ +  } \ +  } while(0) +    /* note that begin_shared_string expects the _exact_ size of the string,    * not the maximum size    */   PMOD_EXPORT struct pike_string *debug_begin_shared_string(size_t len)   {    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->str[len]=0;    t->len=len;    t->size_shift=0;    return t;   }      static void link_pike_string(struct pike_string *s, size_t h)   {    s->refs = 0;    s->next = base_table[h];
pike.git/src/stralloc.c:478:   }      PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int shift)   {    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) { +  if (!shift) { +  t = (struct pike_string *)alloc_short_pike_string0(); +  } else if (shift == 1) { +  t = (struct pike_string *)alloc_short_pike_string1(); + #ifdef PIKE_DEBUG +  } else if (shift != 2) { +  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->len=len;    t->size_shift=shift;    low_set_index(t,len,0);    return t;   }      /*    * This function assumes that the shift size is already the minimum it    * can be.    */
pike.git/src/stralloc.c:505:    len = s->len;    h = do_hash(s);    s2 = internal_findstring(s->str, len, s->size_shift, h);   #ifdef PIKE_DEBUG    if(s2==s)    fatal("end_shared_string called twice! (or something like that)\n");   #endif       if(s2)    { -  free((char *)s); +  really_free_pike_string(s);    s = s2;    }else{    link_pike_string(s, h);    }    add_ref(s);       return s;      }   
pike.git/src/stralloc.c:535:    {    default:    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); -  free((char *)s); +  really_free_pike_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); -  free((char *)s); +  really_free_pike_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); -  free((char *)s); +  really_free_pike_string(s);    s=s2;    }    break;       case 0: break;    }       return low_end_shared_string(s);   }   
pike.git/src/stralloc.c:735: Inside #if defined(PIKE_DEBUG)
   {    if(s->next == (struct pike_string *)(ptrdiff_t)-1)    fatal("Freeing shared string again!\n");       if(((ptrdiff_t)s->next) & 1)    fatal("Freeing shared string again, memory corrupt or other bug!\n");    }    }   #endif    unlink_pike_string(s); -  debug_free((char *)s,DMALLOC_LOCATION(),1); +  really_free_pike_string(s);    GC_FREE_SIMPLE_BLOCK(s);   }      PMOD_EXPORT void debug_free_string(struct pike_string *s)   {    if(--s->refs<=0)    really_free_string(s);   }      
pike.git/src/stralloc.c:1122:    if(ac-bc) return ac-bc;    }    return a->len - b->len;    }    }   }      PMOD_EXPORT struct pike_string *realloc_unlinked_string(struct pike_string *a,    ptrdiff_t size)   { -  struct pike_string *r; +  struct pike_string *r = NULL; +  +  if (a->len <= SHORT_STRING_THRESHOLD) { +  if (size <= SHORT_STRING_THRESHOLD) { +  /* There's already place enough. */ +  a->len = size; +  low_set_index(a, size, 0); +  return a; +  } +  } else if (size > SHORT_STRING_THRESHOLD) {    r=(struct pike_string *)realloc((char *)a,    sizeof(struct pike_string)+    ((size+1)<<a->size_shift)); /* FIXME !! */ -  +  }       if(!r)    { -  r=begin_shared_string(size); +  r=begin_wide_shared_string(size, a->size_shift); +  if (a->len <= size) {    MEMCPY(r->str, a->str, a->len<<a->size_shift); -  free((char *)a); +  } else { +  MEMCPY(r->str, a->str, size<<a->size_shift);    } -  +  really_free_pike_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:1565: Inside #if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC)
   dump_stralloc_strings();    }    }   #endif    for(e=0;e<htable_size;e++)    {    for(s=base_table[e];s;s=next)    {    next=s->next;   #ifdef REALLY_FREE -  free((char *)s); +  really_free_pike_string(s);   #else    s->next=0;   #endif    }    base_table[e]=0;    }    free((char *)base_table);    base_table=0;    num_strings=0;   }
pike.git/src/stralloc.c:1647:   static void string_build_mkspace(struct string_builder *s,    ptrdiff_t chars, int mag)   {    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);    s->malloced=l; -  free((char *)s->s); +     s->s=n;    }    else if(((size_t)s->s->len+chars) > ((size_t)s->malloced))    {    size_t newlen = MAXIMUM((size_t)(s->malloced*2),    (size_t)(s->s->len + chars)); -  +  ptrdiff_t oldlen = s->s->len;    -  s->s=(struct pike_string *)realloc((char *)s->s, -  sizeof(struct pike_string)+ -  ((newlen+1)<<s->s->size_shift)); -  if(!s->s) -  fatal("Out of memory.\n"); -  s->malloced=newlen; +  s->s = realloc_unlinked_string(s->s, newlen); +  s->s->len = oldlen; +  s->malloced = newlen;    }   }      PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, ptrdiff_t chars, int mag)   {    void *ret;    string_build_mkspace(s, chars, mag);    if(chars<0) s->known_shift=0;    ret = s->s->str + (s->s->len<<s->s->size_shift);    s->s->len += chars;    return ret;   }      PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch)   {    ptrdiff_t i; -  + #if 1 +  if ((min_magnitude(ch) > s->s->size_shift) || +  (((size_t)s->s->len) >= ((size_t)s->malloced))) {    string_build_mkspace(s,1,min_magnitude(ch)); -  +  } + #else +  string_build_mkspace(s,1,min_magnitude(ch)); + #endif /* 0 */    s->known_shift=MAXIMUM((size_t)min_magnitude(ch),s->known_shift);    i = s->s->len++;    low_set_index(s->s,i,ch);   }         PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s, char *str, ptrdiff_t len)   {    string_build_mkspace(s,len,0);    switch(s->s->size_shift)
pike.git/src/stralloc.c:1704:    fatal("Illegal magnitude!\n");    }    s->s->len+=len;   }         PMOD_EXPORT void string_builder_append(struct string_builder *s,    PCHARP from,    ptrdiff_t len)   { -  string_build_mkspace(s,len,from.shift); +  int shift; +  if ((shift = from.shift) > s->s->size_shift) { +  if (shift == 1) { +  shift = find_magnitude1((p_wchar1 *)from.ptr, len); +  } else { +  shift = find_magnitude2((p_wchar2 *)from.ptr, len); +  } +  } +  string_build_mkspace(s, len, shift);    generic_memcpy(MKPCHARP_STR_OFF(s->s,s->s->len), from, len);    s->s->len+=len;   }      PMOD_EXPORT void string_builder_fill(struct string_builder *s,    ptrdiff_t howmany,    PCHARP from,    ptrdiff_t len,    ptrdiff_t offset)   {    ptrdiff_t tmp; -  +  int shift;      #ifdef PIKE_DEBUG    if(len<=0)    fatal("Cannot fill with zero length strings!\n");   #endif    if(howmany<=0) return;       if(!s->s->size_shift &&    len == 1 &&    (!from.shift || !min_magnitude(EXTRACT_PCHARP(from))))    {    MEMSET(string_builder_allocate(s,howmany,0),    EXTRACT_PCHARP(from),    howmany);    return;    }    -  string_build_mkspace(s,howmany,from.shift); +  if ((shift = from.shift) > s->s->size_shift) { +  /* Check if we really need the extra magnitude. */ +  /* FIXME: What about offset? */ +  if (shift == 1) { +  shift = find_magnitude1((p_wchar1 *)from.ptr, len); +  } else { +  shift = find_magnitude2((p_wchar2 *)from.ptr, len); +  } +  } +  +  string_build_mkspace(s, howmany, shift);    tmp = MINIMUM(howmany, len - offset);       generic_memcpy(MKPCHARP_STR_OFF(s->s,s->s->len),    ADD_PCHARP(from,offset),    tmp);    s->s->len+=tmp;    howmany-=tmp;    if(howmany > 0)    {    void *new_from;
pike.git/src/stralloc.c:1787:         PMOD_EXPORT void reset_string_builder(struct string_builder *s)   {    s->known_shift=0;    s->s->len=0;   }      PMOD_EXPORT void free_string_builder(struct string_builder *s)   { -  free((char *)s->s); +  s->s->len = s->malloced; +  really_free_pike_string(s->s);   }      PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s)   {    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); +  }    if(s->known_shift == (size_t)s->s->size_shift)    return low_end_shared_string(s->s);    return end_shared_string(s->s);   }      PMOD_EXPORT PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, ptrdiff_t len)   {    switch(ptr.shift)    {    case 0: return MKPCHARP(MEMCHR0(ptr.ptr,chr,len),0);