00001
00002
00003
00004
00005
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
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
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
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
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
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
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
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
00140 #define DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS(IF, ELSE) ELSE
00141 #endif
00142
00143 #if SIZEOF_CHAR_P == 4
00144 #define DIVIDE_BY_2_CHAR_P(X) (X >>= 3)
00145 #else
00146 #if SIZEOF_CHAR_P == 8
00147 #define DIVIDE_BY_2_CHAR_P(X) (X >>= 4)
00148 #else
00149 #define DIVIDE_BY_2_CHAR_P(X) (X /= 2*sizeof(size_t))
00150 #endif
00151 #endif
00152
00153
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