Main Page | Class List | Directories | File List | Class Members | File Members

pike_memory.h

Go to the documentation of this file.
00001 /*
00002 || This file is part of Pike. For copyright information see COPYRIGHT.
00003 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
00004 || for more information.
00005 || $Id: pike_memory.h,v 1.51 2005/05/25 16:59:39 grubba Exp $
00006 */
00007 
00008 #ifndef MEMORY_H
00009 #define MEMORY_H
00010 
00011 #include "global.h"
00012 #include "stralloc.h"
00013 
00014 #ifdef USE_VALGRIND
00015 
00016 #ifdef HAVE_MEMCHECK_H
00017 #include <memcheck.h>
00018 #elif defined(HAVE_VALGRIND_MEMCHECK_H)
00019 #include <valgrind/memcheck.h>
00020 #elif defined(HAVE_VALGRIND_H)
00021 #include <valgrind.h>
00022 #endif
00023 
00024 /* No Access */
00025 #define PIKE_MEM_NA(lvalue) do {                                        \
00026     PIKE_MEM_NA_RANGE(&(lvalue), sizeof (lvalue));                      \
00027   } while (0)
00028 #define PIKE_MEM_NA_RANGE(addr, bytes) do {                             \
00029     VALGRIND_DISCARD(VALGRIND_MAKE_NOACCESS(addr, bytes));              \
00030   } while (0)
00031 
00032 /* Write Only -- Will become RW when having been written to */
00033 #define PIKE_MEM_WO(lvalue) do {                                        \
00034     PIKE_MEM_WO_RANGE(&(lvalue), sizeof (lvalue));                      \
00035   } while (0)
00036 #define PIKE_MEM_WO_RANGE(addr, bytes) do {                             \
00037     VALGRIND_DISCARD(VALGRIND_MAKE_WRITABLE(addr, bytes));              \
00038   } while (0)
00039 
00040 /* Read/Write */
00041 #define PIKE_MEM_RW(lvalue) do {                                        \
00042     PIKE_MEM_RW_RANGE(&(lvalue), sizeof (lvalue));                      \
00043   } while (0)
00044 #define PIKE_MEM_RW_RANGE(addr, bytes) do {                             \
00045     VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(addr, bytes));              \
00046   } while (0)
00047 
00048 /* Read Only -- Not currently supported by valgrind */
00049 #define PIKE_MEM_RO(lvalue) do {                                        \
00050     PIKE_MEM_RO_RANGE(&(lvalue), sizeof (lvalue));                      \
00051   } while (0)
00052 #define PIKE_MEM_RO_RANGE(addr, bytes) do {                             \
00053     VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(addr, bytes));              \
00054   } while (0)
00055 
00056 /* Return true if a memchecker is in use. */
00057 #define PIKE_MEM_CHECKER() RUNNING_ON_VALGRIND
00058 
00059 #else
00060 
00061 #define PIKE_MEM_NA(lvalue)             do {} while (0)
00062 #define PIKE_MEM_NA_RANGE(addr, bytes)  do {} while (0)
00063 #define PIKE_MEM_WO(lvalue)             do {} while (0)
00064 #define PIKE_MEM_WO_RANGE(addr, bytes)  do {} while (0)
00065 #define PIKE_MEM_RW(lvalue)             do {} while (0)
00066 #define PIKE_MEM_RW_RANGE(addr, bytes)  do {} while (0)
00067 #define PIKE_MEM_RO(lvalue)             do {} while (0)
00068 #define PIKE_MEM_RO_RANGE(addr, bytes)  do {} while (0)
00069 #define PIKE_MEM_CHECKER()              0
00070 
00071 #endif /* USE_VALGRIND */
00072 
00073 
00074 #define MEMSEARCH_LINKS 512
00075 
00076 struct link
00077 {
00078   struct link *next;
00079   INT32 key;
00080   ptrdiff_t offset;
00081 };
00082 
00083 enum methods {
00084   no_search,
00085   use_memchr,
00086   memchr_and_memcmp,
00087   hubbe_search,
00088   boyer_moore
00089 };
00090 
00091 struct mem_searcher
00092 {
00093   enum methods method;
00094   char *needle;
00095   size_t needlelen;
00096   size_t hsize, max;
00097   struct link links[MEMSEARCH_LINKS];
00098   struct link *set[MEMSEARCH_LINKS];
00099 };
00100 
00101 
00102 #include "pike_search.h"
00103 
00104 #include "block_alloc_h.h"
00105 #define MEMCHR0 MEMCHR
00106 
00107 /* Note to self: Prototypes must be updated manually /Hubbe */
00108 PMOD_EXPORT ptrdiff_t pcharp_memcmp(PCHARP a, PCHARP b, int sz);
00109 PMOD_EXPORT long pcharp_strlen(PCHARP a);
00110 PMOD_EXPORT p_wchar1 *MEMCHR1(p_wchar1 *p, p_wchar2 c, ptrdiff_t e);
00111 PMOD_EXPORT p_wchar2 *MEMCHR2(p_wchar2 *p, p_wchar2 c, ptrdiff_t e);
00112 PMOD_EXPORT void swap(char *a, char *b, size_t size);
00113 PMOD_EXPORT void reverse(char *memory, size_t nitems, size_t size);
00114 PMOD_EXPORT void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order);
00115 PMOD_EXPORT size_t hashmem(const unsigned char *a, size_t len, size_t mlen);
00116 PMOD_EXPORT size_t hashstr(const unsigned char *str, ptrdiff_t maxn);
00117 PMOD_EXPORT size_t simple_hashmem(const unsigned char *str, ptrdiff_t len, ptrdiff_t maxn);
00118 PMOD_EXPORT size_t simple_hashmem1(const p_wchar1 *str, ptrdiff_t len, ptrdiff_t maxn);
00119 PMOD_EXPORT size_t simple_hashmem2(const p_wchar2 *str, ptrdiff_t len, ptrdiff_t maxn);
00120 PMOD_EXPORT void memfill(char *to,
00121              INT32 tolen,
00122              char *from,
00123              INT32 fromlen,
00124              INT32 offset);
00125 PMOD_EXPORT void *debug_xalloc(size_t size);
00126 PMOD_EXPORT void *debug_xmalloc(size_t s);
00127 PMOD_EXPORT void debug_xfree(void *mem);
00128 PMOD_EXPORT void *debug_xrealloc(void *m, size_t s);
00129 PMOD_EXPORT void *debug_xcalloc(size_t n, size_t s);
00130 
00131 void *mexec_alloc(size_t sz);
00132 void *mexec_realloc(void *ptr, size_t sz);
00133 void mexec_free(void *ptr);
00134 
00135 #undef BLOCK_ALLOC
00136 
00137 #ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
00138 #define DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS(IF, ELSE)    IF
00139 #else /* !HANDLES_UNALIGNED_MEMORY_ACCESS */
00140 #define DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS(IF, ELSE)    ELSE
00141 #endif /* HANDLES_UNALIGNED_MEMORY_ACCESS */
00142 
00143 #if SIZEOF_CHAR_P == 4
00144 #define DIVIDE_BY_2_CHAR_P(X)   (X >>= 3)
00145 #else /* sizeof(char *) != 4 */
00146 #if SIZEOF_CHAR_P == 8
00147 #define DIVIDE_BY_2_CHAR_P(X)   (X >>= 4)
00148 #else /* sizeof(char *) != 8 */
00149 #define DIVIDE_BY_2_CHAR_P(X)   (X /= 2*sizeof(size_t))
00150 #endif /* sizeof(char *) == 8 */
00151 #endif /* sizeof(char *) == 4 */
00152 
00153 /* NB: RET should be an lvalue of type size_t. */
00154 #define DO_HASHMEM(RET, A, LEN, MLEN)                   \
00155   do {                                                  \
00156     const unsigned char *a = A;                         \
00157     size_t len = LEN;                                   \
00158     size_t mlen = MLEN;                                 \
00159     size_t ret;                                         \
00160                                                         \
00161     ret = 9248339*len;                                  \
00162     if(len<mlen)                                        \
00163       mlen=len;                                         \
00164     else                                                \
00165     {                                                   \
00166       switch(len-mlen)                                  \
00167       {                                                 \
00168         default: ret^=(ret<<6) + a[len-7];              \
00169         case 7:                                         \
00170         case 6: ret^=(ret<<7) + a[len-5];               \
00171         case 5:                                         \
00172         case 4: ret^=(ret<<4) + a[len-4];               \
00173         case 3: ret^=(ret<<3) + a[len-3];               \
00174         case 2: ret^=(ret<<3) + a[len-2];               \
00175         case 1: ret^=(ret<<3) + a[len-1];               \
00176       }                                                 \
00177     }                                                   \
00178     a += mlen & 7;                                      \
00179     switch(mlen&7)                                      \
00180     {                                                   \
00181       case 7: ret^=a[-7];                               \
00182       case 6: ret^=(ret<<4)+a[-6];                      \
00183       case 5: ret^=(ret<<7)+a[-5];                      \
00184       case 4: ret^=(ret<<6)+a[-4];                      \
00185       case 3: ret^=(ret<<3)+a[-3];                      \
00186       case 2: ret^=(ret<<7)+a[-2];                      \
00187       case 1: ret^=(ret<<5)+a[-1];                      \
00188     }                                                   \
00189                                                         \
00190     DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS(                 \
00191       {                                                 \
00192         size_t *b;                                      \
00193         b=(size_t *)a;                                  \
00194                                                         \
00195         for(DIVIDE_BY_2_CHAR_P(mlen);mlen--;)           \
00196         {                                               \
00197           ret^=(ret<<7)+*(b++);                         \
00198           ret^=(ret>>6)+*(b++);                         \
00199         }                                               \
00200       }                                                 \
00201     ,                                                   \
00202       for(mlen >>= 3; mlen--;)                          \
00203       {                                                 \
00204         register size_t t1;                             \
00205         register size_t t2;                             \
00206         t1= a[0];                                       \
00207         t2= a[1];                                       \
00208         t1=(t1<<5) + a[2];                              \
00209         t2=(t2<<4) + a[3];                              \
00210         t1=(t1<<7) + a[4];                              \
00211         t2=(t2<<5) + a[5];                              \
00212         t1=(t1<<3) + a[6];                              \
00213         t2=(t2<<4) + a[7];                              \
00214         a += 8;                                         \
00215         ret^=(ret<<7) + (ret>>6) + t1 + (t2<<6);        \
00216       }                                                 \
00217     )                                                   \
00218                                                         \
00219     RET = ret;                                          \
00220   } while(0)
00221 
00222 #ifdef DEBUG_MALLOC
00223 void initialize_dmalloc(void);
00224 #else
00225 #define initialize_dmalloc()
00226 #endif
00227 
00228 #endif

Generated on Fri Jul 22 23:44:26 2005 for Pike by  doxygen 1.3.9.1