e576bb2002-10-11Martin Nilsson /* || 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.
53fde72005-05-25Henrik Grubbström (Grubba) || $Id: pike_memory.h,v 1.51 2005/05/25 16:59:39 grubba Exp $
e576bb2002-10-11Martin Nilsson */
24ddc71998-03-28Henrik Grubbström (Grubba) 
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #ifndef MEMORY_H #define MEMORY_H #include "global.h"
3e625c1998-10-11Fredrik Hübinette (Hubbe) #include "stralloc.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) 
762f972003-01-26Mirar (Pontus Hagland) #ifdef USE_VALGRIND
a42e082003-04-26Marcus Agehall #ifdef HAVE_MEMCHECK_H #include <memcheck.h>
b8c5132003-05-13Martin Stjernholm #elif defined(HAVE_VALGRIND_MEMCHECK_H) #include <valgrind/memcheck.h> #elif defined(HAVE_VALGRIND_H)
875ab52002-11-19Henrik Grubbström (Grubba) #include <valgrind.h>
b8c5132003-05-13Martin Stjernholm #endif
9b1f032000-10-09Fredrik Hübinette (Hubbe) 
4281d22002-11-20Henrik Grubbström (Grubba) /* No Access */
7ca8592002-11-23Martin Stjernholm #define PIKE_MEM_NA(lvalue) do { \
6546b22002-11-23Martin Stjernholm  PIKE_MEM_NA_RANGE(&(lvalue), sizeof (lvalue)); \
7ca8592002-11-23Martin Stjernholm  } while (0) #define PIKE_MEM_NA_RANGE(addr, bytes) do { \ VALGRIND_DISCARD(VALGRIND_MAKE_NOACCESS(addr, bytes)); \ } while (0) /* Write Only -- Will become RW when having been written to */ #define PIKE_MEM_WO(lvalue) do { \
6546b22002-11-23Martin Stjernholm  PIKE_MEM_WO_RANGE(&(lvalue), sizeof (lvalue)); \
7ca8592002-11-23Martin Stjernholm  } while (0) #define PIKE_MEM_WO_RANGE(addr, bytes) do { \ VALGRIND_DISCARD(VALGRIND_MAKE_WRITABLE(addr, bytes)); \ } while (0)
4281d22002-11-20Henrik Grubbström (Grubba) /* Read/Write */
7ca8592002-11-23Martin Stjernholm #define PIKE_MEM_RW(lvalue) do { \
6546b22002-11-23Martin Stjernholm  PIKE_MEM_RW_RANGE(&(lvalue), sizeof (lvalue)); \
7ca8592002-11-23Martin Stjernholm  } while (0) #define PIKE_MEM_RW_RANGE(addr, bytes) do { \ VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(addr, bytes)); \ } while (0)
4281d22002-11-20Henrik Grubbström (Grubba) /* Read Only -- Not currently supported by valgrind */
7ca8592002-11-23Martin Stjernholm #define PIKE_MEM_RO(lvalue) do { \
6546b22002-11-23Martin Stjernholm  PIKE_MEM_RO_RANGE(&(lvalue), sizeof (lvalue)); \
7ca8592002-11-23Martin Stjernholm  } while (0) #define PIKE_MEM_RO_RANGE(addr, bytes) do { \ VALGRIND_DISCARD(VALGRIND_MAKE_READABLE(addr, bytes)); \ } while (0)
c306092003-02-16Martin Stjernholm /* Return true if a memchecker is in use. */
f09e482002-11-23Martin Stjernholm #define PIKE_MEM_CHECKER() RUNNING_ON_VALGRIND
4281d22002-11-20Henrik Grubbström (Grubba) #else
7ca8592002-11-23Martin Stjernholm  #define PIKE_MEM_NA(lvalue) do {} while (0) #define PIKE_MEM_NA_RANGE(addr, bytes) do {} while (0) #define PIKE_MEM_WO(lvalue) do {} while (0) #define PIKE_MEM_WO_RANGE(addr, bytes) do {} while (0) #define PIKE_MEM_RW(lvalue) do {} while (0) #define PIKE_MEM_RW_RANGE(addr, bytes) do {} while (0) #define PIKE_MEM_RO(lvalue) do {} while (0) #define PIKE_MEM_RO_RANGE(addr, bytes) do {} while (0)
f09e482002-11-23Martin Stjernholm #define PIKE_MEM_CHECKER() 0
7ca8592002-11-23Martin Stjernholm 
4281d22002-11-20Henrik Grubbström (Grubba) #endif /* USE_VALGRIND */
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #define MEMSEARCH_LINKS 512 struct link { struct link *next;
e0755c2000-08-15Henrik Grubbström (Grubba)  INT32 key; ptrdiff_t offset;
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) }; enum methods { no_search, use_memchr, memchr_and_memcmp,
db4a401998-10-09Fredrik Hübinette (Hubbe)  hubbe_search, boyer_moore
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) }; struct mem_searcher { enum methods method; char *needle;
61a8ec2000-08-11Henrik Grubbström (Grubba)  size_t needlelen;
7901142000-08-15Henrik Grubbström (Grubba)  size_t hsize, max;
9aa6fa1997-05-19Fredrik Hübinette (Hubbe)  struct link links[MEMSEARCH_LINKS]; struct link *set[MEMSEARCH_LINKS]; };
9b1f032000-10-09Fredrik Hübinette (Hubbe)  #include "pike_search.h"
4218011999-01-31Fredrik Hübinette (Hubbe) #include "block_alloc_h.h"
db4a401998-10-09Fredrik Hübinette (Hubbe) #define MEMCHR0 MEMCHR
d0e2311999-10-24Henrik Grubbström (Grubba) /* Note to self: Prototypes must be updated manually /Hubbe */
f5757f2000-08-11Henrik Grubbström (Grubba) PMOD_EXPORT ptrdiff_t pcharp_memcmp(PCHARP a, PCHARP b, int sz);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT long pcharp_strlen(PCHARP a);
ffcab42004-03-24Henrik Grubbström (Grubba) PMOD_EXPORT p_wchar1 *MEMCHR1(p_wchar1 *p, p_wchar2 c, ptrdiff_t e); PMOD_EXPORT p_wchar2 *MEMCHR2(p_wchar2 *p, p_wchar2 c, ptrdiff_t e);
84f8952000-08-16Henrik Grubbström (Grubba) PMOD_EXPORT void swap(char *a, char *b, size_t size); PMOD_EXPORT void reverse(char *memory, size_t nitems, size_t size);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order);
51f0e02000-08-10Henrik Grubbström (Grubba) PMOD_EXPORT size_t hashmem(const unsigned char *a, size_t len, size_t mlen); PMOD_EXPORT size_t hashstr(const unsigned char *str, ptrdiff_t maxn); PMOD_EXPORT size_t simple_hashmem(const unsigned char *str, ptrdiff_t len, ptrdiff_t maxn);
5d98c42003-03-02Henrik Grubbström (Grubba) PMOD_EXPORT size_t simple_hashmem1(const p_wchar1 *str, ptrdiff_t len, ptrdiff_t maxn); PMOD_EXPORT size_t simple_hashmem2(const p_wchar2 *str, ptrdiff_t len, ptrdiff_t maxn);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void memfill(char *to,
9aa6fa1997-05-19Fredrik Hübinette (Hubbe)  INT32 tolen, char *from, INT32 fromlen, INT32 offset);
5c37fd2001-10-03Martin Stjernholm PMOD_EXPORT void *debug_xalloc(size_t size);
f1792d2000-12-13Fredrik Hübinette (Hubbe) PMOD_EXPORT void *debug_xmalloc(size_t s); PMOD_EXPORT void debug_xfree(void *mem); PMOD_EXPORT void *debug_xrealloc(void *m, size_t s); PMOD_EXPORT void *debug_xcalloc(size_t n, size_t s);
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) 
53fde72005-05-25Henrik Grubbström (Grubba) void *mexec_alloc(size_t sz); void *mexec_realloc(void *ptr, size_t sz); void mexec_free(void *ptr);
db4a401998-10-09Fredrik Hübinette (Hubbe) #undef BLOCK_ALLOC
52068e2000-12-01Henrik Grubbström (Grubba) #ifdef HANDLES_UNALIGNED_MEMORY_ACCESS #define DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS(IF, ELSE) IF #else /* !HANDLES_UNALIGNED_MEMORY_ACCESS */ #define DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS(IF, ELSE) ELSE #endif /* HANDLES_UNALIGNED_MEMORY_ACCESS */ #if SIZEOF_CHAR_P == 4 #define DIVIDE_BY_2_CHAR_P(X) (X >>= 3) #else /* sizeof(char *) != 4 */ #if SIZEOF_CHAR_P == 8 #define DIVIDE_BY_2_CHAR_P(X) (X >>= 4) #else /* sizeof(char *) != 8 */ #define DIVIDE_BY_2_CHAR_P(X) (X /= 2*sizeof(size_t)) #endif /* sizeof(char *) == 8 */ #endif /* sizeof(char *) == 4 */
d4f7bc2000-12-01Henrik Grubbström (Grubba) /* NB: RET should be an lvalue of type size_t. */ #define DO_HASHMEM(RET, A, LEN, MLEN) \
52068e2000-12-01Henrik Grubbström (Grubba)  do { \ const unsigned char *a = A; \ size_t len = LEN; \ size_t mlen = MLEN; \ size_t ret; \ \ ret = 9248339*len; \ if(len<mlen) \ mlen=len; \ else \ { \ switch(len-mlen) \ { \ default: ret^=(ret<<6) + a[len-7]; \ case 7: \ case 6: ret^=(ret<<7) + a[len-5]; \ case 5: \ case 4: ret^=(ret<<4) + a[len-4]; \ case 3: ret^=(ret<<3) + a[len-3]; \ case 2: ret^=(ret<<3) + a[len-2]; \ case 1: ret^=(ret<<3) + a[len-1]; \ } \ } \ a += mlen & 7; \ switch(mlen&7) \ { \ case 7: ret^=a[-7]; \ case 6: ret^=(ret<<4)+a[-6]; \ case 5: ret^=(ret<<7)+a[-5]; \ case 4: ret^=(ret<<6)+a[-4]; \ case 3: ret^=(ret<<3)+a[-3]; \ case 2: ret^=(ret<<7)+a[-2]; \ case 1: ret^=(ret<<5)+a[-1]; \ } \ \ DO_IF_ELSE_UNALIGNED_MEMORY_ACCESS( \ { \ size_t *b; \ b=(size_t *)a; \ \ for(DIVIDE_BY_2_CHAR_P(mlen);mlen--;) \ { \ ret^=(ret<<7)+*(b++); \ ret^=(ret>>6)+*(b++); \ } \ } \ , \ for(mlen >>= 3; mlen--;) \ { \
d2f2052000-12-01Henrik Grubbström (Grubba)  register size_t t1; \ register size_t t2; \
52068e2000-12-01Henrik Grubbström (Grubba)  t1= a[0]; \ t2= a[1]; \ t1=(t1<<5) + a[2]; \ t2=(t2<<4) + a[3]; \ t1=(t1<<7) + a[4]; \ t2=(t2<<5) + a[5]; \ t1=(t1<<3) + a[6]; \ t2=(t2<<4) + a[7]; \ a += 8; \ ret^=(ret<<7) + (ret>>6) + t1 + (t2<<6); \ } \ ) \ \
d4f7bc2000-12-01Henrik Grubbström (Grubba)  RET = ret; \
52068e2000-12-01Henrik Grubbström (Grubba)  } while(0)
df458c2004-12-30Henrik Grubbström (Grubba) #ifdef DEBUG_MALLOC void initialize_dmalloc(void); #else #define initialize_dmalloc() #endif
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #endif