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. */
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
b408242006-07-02Martin Stjernholm #define HAVE_VALGRIND_MACROS /* Assume that any of the following header files have the macros we * need. Haven't checked if it's true or not. */
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>
b408242006-07-02Martin Stjernholm #else #undef HAVE_VALGRIND_MACROS
b8c5132003-05-13Martin Stjernholm #endif
9b1f032000-10-09Fredrik Hübinette (Hubbe) 
b408242006-07-02Martin Stjernholm #endif /* USE_VALGRIND */ #ifdef HAVE_VALGRIND_MACROS
6cef102008-01-29Per Hedbor #endif
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 { \
2a782d2008-06-02Martin Stjernholm  VALGRIND_DISCARD(VALGRIND_MAKE_MEM_NOACCESS(addr, bytes)); \
7ca8592002-11-23Martin Stjernholm  } 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 { \
2a782d2008-06-02Martin Stjernholm  VALGRIND_DISCARD(VALGRIND_MAKE_MEM_UNDEFINED(addr, bytes)); \
7ca8592002-11-23Martin Stjernholm  } 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 { \
2a782d2008-06-02Martin Stjernholm  VALGRIND_DISCARD(VALGRIND_MAKE_MEM_DEFINED(addr, bytes)); \
7ca8592002-11-23Martin Stjernholm  } 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 { \
2a782d2008-06-02Martin Stjernholm  VALGRIND_DISCARD(VALGRIND_MAKE_MEM_DEFINED(addr, bytes)); \
7ca8592002-11-23Martin Stjernholm  } 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
2a782d2008-06-02Martin Stjernholm /* Return true if a memchecker reports the memory to not be * addressable (might also print debug messages etc). */ #define PIKE_MEM_NOT_ADDR(lvalue) \ PIKE_MEM_NOT_ADDR_RANGE(&(lvalue), sizeof (lvalue)) #define PIKE_MEM_NOT_ADDR_RANGE(addr, bytes) \ VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, bytes) /* Return true if a memchecker reports the memory to not be defined * (might also print debug messages etc). */ #define PIKE_MEM_NOT_DEF(lvalue) \ PIKE_MEM_NOT_DEF_RANGE(&(lvalue), sizeof (lvalue)) #define PIKE_MEM_NOT_DEF_RANGE(addr, bytes) \ VALGRIND_CHECK_MEM_IS_DEFINED(addr, bytes)
411bb52013-08-02Arne Goedeke #ifdef VALGRIND_CREATE_MEMPOOL
411bb52013-08-02Arne Goedeke #else /* somewhat functional alternatives to mempool macros */
8e90372014-09-05Arne Goedeke # define PIKE_MEMPOOL_CREATE(a) do {} while (0)
411bb52013-08-02Arne Goedeke # define PIKE_MEMPOOL_ALLOC(a, p, l) PIKE_MEM_WO_RANGE(p, l)
3036092013-10-09Arne Goedeke # define PIKE_MEMPOOL_FREE(a, p, l) PIKE_MEM_NA_RANGE(p, l)
8e90372014-09-05Arne Goedeke # define PIKE_MEMPOOL_DESTROY(a) do {} while (0)
411bb52013-08-02Arne Goedeke #endif
8e90372014-09-05Arne Goedeke #define VALGRINDUSED(x) x
b408242006-07-02Martin Stjernholm #else /* !HAVE_VALGRIND_MACROS */
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
2a782d2008-06-02Martin Stjernholm #define PIKE_MEM_NOT_ADDR(lvalue) 0 #define PIKE_MEM_NOT_ADDR_RANGE(addr, bytes) 0 #define PIKE_MEM_NOT_DEF(lvalue) 0 #define PIKE_MEM_NOT_DEF_RANGE(addr, bytes) 0
8e90372014-09-05Arne Goedeke #define PIKE_MEMPOOL_CREATE(a) do {} while (0) #define PIKE_MEMPOOL_ALLOC(a, p, l) do {} while (0) #define PIKE_MEMPOOL_FREE(a, p, l) do {} while (0) #define PIKE_MEMPOOL_DESTROY(a) do {} while (0) #define VALGRINDUSED(x) UNUSED(x)
7ca8592002-11-23Martin Stjernholm 
b408242006-07-02Martin Stjernholm #endif /* !HAVE_VALGRIND_MACROS */
4281d22002-11-20Henrik Grubbström (Grubba) 
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]; };
0a146b2013-03-12Arne Goedeke /* * The purpose of this function is to avoid dead store elimination in cases when * sensitive data has to be cleared from memory. */
356d232014-10-30Henrik Grubbström (Grubba) static INLINE void ATTRIBUTE((unused)) * guaranteed_memset(void * p, int c, size_t n) {
dc57c82013-04-19Per Hedbor  volatile char * _p = (char *)p;
0a146b2013-03-12Arne Goedeke  while (n--) *_p++ = c;
dc57c82013-04-19Per Hedbor  return (void *)p;
0a146b2013-03-12Arne Goedeke }
9b1f032000-10-09Fredrik Hübinette (Hubbe) 
356d232014-10-30Henrik Grubbström (Grubba) static INLINE unsigned INT64 ATTRIBUTE((unused)) get_unaligned64(const void * ptr) {
e744702014-01-11Tobias S. Josefowitz  unsigned INT64 v; memcpy(&v, ptr, 8); return v; }
356d232014-10-30Henrik Grubbström (Grubba) static INLINE void ATTRIBUTE((unused)) set_unaligned64(void * ptr, unsigned INT64 v) {
e744702014-01-11Tobias S. Josefowitz  memcpy(ptr, &v, 8); }
356d232014-10-30Henrik Grubbström (Grubba) static INLINE unsigned INT64 ATTRIBUTE((unused)) get_unaligned32(const void * ptr) {
e744702014-01-11Tobias S. Josefowitz  unsigned INT32 v; memcpy(&v, ptr, 4); return v; }
356d232014-10-30Henrik Grubbström (Grubba) static INLINE void ATTRIBUTE((unused)) set_unaligned32(void * ptr, unsigned INT32 v) {
e744702014-01-11Tobias S. Josefowitz  memcpy(ptr, &v, 4); }
356d232014-10-30Henrik Grubbström (Grubba) static INLINE unsigned INT16 ATTRIBUTE((unused)) get_unaligned16(const void * ptr) {
e744702014-01-11Tobias S. Josefowitz  unsigned INT16 v; memcpy(&v, ptr, 2); return v; }
356d232014-10-30Henrik Grubbström (Grubba) static INLINE void ATTRIBUTE((unused)) set_unaligned16(void * ptr, unsigned INT16 v) {
e744702014-01-11Tobias S. Josefowitz  memcpy(ptr, &v, 2); }
9b1f032000-10-09Fredrik Hübinette (Hubbe) #include "pike_search.h"
4218011999-01-31Fredrik Hübinette (Hubbe) #include "block_alloc_h.h"
13ee8f2006-08-09Martin Stjernholm extern int page_size;
d0e2311999-10-24Henrik Grubbström (Grubba) /* Note to self: Prototypes must be updated manually /Hubbe */
66d9282011-05-01Per Hedbor PMOD_EXPORT ptrdiff_t pcharp_memcmp(PCHARP a, PCHARP b, int sz) ATTRIBUTE((pure)); PMOD_EXPORT long pcharp_strlen(PCHARP a) ATTRIBUTE((pure));
98c0302014-09-03Martin Nilsson #define MEMCHR0 memchr
66d9282011-05-01Per Hedbor p_wchar1 *MEMCHR1(p_wchar1 *p, p_wchar2 c, ptrdiff_t e) ATTRIBUTE((pure)); p_wchar2 *MEMCHR2(p_wchar2 *p, p_wchar2 c, ptrdiff_t e) ATTRIBUTE((pure)); /* PMOD_EXPORT void swap(char *a, char *b, size_t size); */
84f8952000-08-16Henrik Grubbström (Grubba) 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);
34ffc02011-05-15Per Hedbor  #if (defined(__i386__) || defined(__amd64__)) && defined(__GNUC__)
b7e55a2013-05-17Per Hedbor extern PMOD_EXPORT
34ffc02011-05-15Per Hedbor #ifdef __i386__
356d232014-10-30Henrik Grubbström (Grubba) ATTRIBUTE((fastcall))
34ffc02011-05-15Per Hedbor #endif
b7e55a2013-05-17Per Hedbor size_t (*low_hashmem)(const void *, size_t, size_t, size_t);
34ffc02011-05-15Per Hedbor #else
0169c62011-12-30Henrik Grubbström (Grubba) PMOD_EXPORT size_t low_hashmem(const void *, size_t len, size_t mlen, size_t key) ATTRIBUTE((pure));
34ffc02011-05-15Per Hedbor #endif
0169c62011-12-30Henrik Grubbström (Grubba) PMOD_EXPORT size_t hashmem(const void *, size_t len, size_t mlen) ATTRIBUTE((pure));
66d9282011-05-01Per Hedbor /*
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);
66d9282011-05-01Per Hedbor */
0ce2f72011-05-10Per Hedbor #define MALLOC_FUNCTION ATTRIBUTE((malloc)) ATTRIBUTE((warn_unused_result)) PMOD_EXPORT void *debug_xalloc(size_t size) MALLOC_FUNCTION; PMOD_EXPORT void *debug_xmalloc(size_t s) MALLOC_FUNCTION;
f1792d2000-12-13Fredrik Hübinette (Hubbe) PMOD_EXPORT void debug_xfree(void *mem);
0ce2f72011-05-10Per Hedbor PMOD_EXPORT void *debug_xrealloc(void *m, size_t s) MALLOC_FUNCTION; PMOD_EXPORT void *debug_xcalloc(size_t n, size_t s) MALLOC_FUNCTION;
cab1f32014-11-13Arne Goedeke PMOD_EXPORT void *xalloc_aligned(size_t size, size_t alignment) MALLOC_FUNCTION;
aa432a2013-08-01Arne Goedeke  #define PIKE_ALIGNTO(x, a) (((x) + (a)-1) & ~((a)-1))
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) 
0ce2f72011-05-10Per Hedbor PMOD_EXPORT void *mexec_alloc(size_t sz) MALLOC_FUNCTION; PMOD_EXPORT void *mexec_realloc(void *ptr, size_t sz) MALLOC_FUNCTION; PMOD_EXPORT void mexec_free(void *ptr);
13ee8f2006-08-09Martin Stjernholm void init_pike_memory (void);
0929032006-08-09Martin Stjernholm void exit_pike_memory (void);
53fde72005-05-25Henrik Grubbström (Grubba) 
0e26b62013-07-01Arne Goedeke #ifdef DEBUG_MALLOC PMOD_EXPORT void * system_malloc(size_t) MALLOC_FUNCTION; PMOD_EXPORT void system_free(void *); #endif
db4a401998-10-09Fredrik Hübinette (Hubbe) #undef BLOCK_ALLOC
0929032006-08-09Martin Stjernholm /* Determine if we should use our own heap manager for executable * memory. */ #if defined(MEXEC_USES_MMAP) || defined (_WIN32) #define USE_MY_MEXEC_ALLOC #endif
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #endif