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"
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
2a782d2008-06-02Martin Stjernholm #ifndef VALGRIND_MAKE_MEM_NOACCESS #define VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_NOACCESS #define VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_WRITABLE #define VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_READABLE
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 { \
f7d1822017-06-25Martin Nilsson  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 { \
f7d1822017-06-25Martin Nilsson  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 { \
f7d1822017-06-25Martin Nilsson  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 { \
f7d1822017-06-25Martin Nilsson  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
3036092013-10-09Arne Goedeke # define PIKE_MEMPOOL_CREATE(a) VALGRIND_CREATE_MEMPOOL(a, 0, 0) # define PIKE_MEMPOOL_ALLOC(a, p, l) VALGRIND_MEMPOOL_ALLOC(a, p, l) # define PIKE_MEMPOOL_FREE(a, p, l) VALGRIND_MEMPOOL_FREE(a, p) # define PIKE_MEMPOOL_DESTROY(a) VALGRIND_DESTROY_MEMPOOL(a)
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]; };
34a7972018-01-18Martin Nilsson PMOD_EXPORT void secure_zero(void *p, size_t n);
9b1f032000-10-09Fredrik Hübinette (Hubbe) 
92456f2017-07-20Marcus Comstedt #ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
8e936c2015-08-06Per Hedbor /* it is faster to just do the unaligned operation. */
30f5b22016-04-09Martin Nilsson static inline UINT64 ATTRIBUTE((unused)) get_unaligned64(const void *ptr) { return *(UINT64*)ptr;
8e936c2015-08-06Per Hedbor }
01b9212016-01-12Per Hedbor static inline unsigned INT32 ATTRIBUTE((unused)) get_unaligned32(const void *ptr) {
8e936c2015-08-06Per Hedbor  return *(unsigned INT32*)ptr; }
01b9212016-01-12Per Hedbor static inline unsigned INT16 ATTRIBUTE((unused)) get_unaligned16(const void *ptr) {
8e936c2015-08-06Per Hedbor  return *(unsigned INT16*)ptr; }
01b9212016-01-12Per Hedbor static inline void ATTRIBUTE((unused)) set_unaligned16(void *ptr,unsigned INT16 val) {
8e936c2015-08-06Per Hedbor  *(unsigned INT16*)ptr = val; }
01b9212016-01-12Per Hedbor static inline void ATTRIBUTE((unused)) set_unaligned32(void *ptr,unsigned INT32 val) {
8e936c2015-08-06Per Hedbor  *(unsigned INT32*)ptr = val; }
30f5b22016-04-09Martin Nilsson static inline void ATTRIBUTE((unused)) set_unaligned64(void *ptr,UINT64 val) { *(UINT64*)ptr = val;
8e936c2015-08-06Per Hedbor } #else
30f5b22016-04-09Martin Nilsson static inline UINT64 ATTRIBUTE((unused)) get_unaligned64(const void * ptr) { UINT64 v;
e744702014-01-11Tobias S. Josefowitz  memcpy(&v, ptr, 8); return v; }
30f5b22016-04-09Martin Nilsson static inline void ATTRIBUTE((unused)) set_unaligned64(void * ptr, UINT64 v) {
e744702014-01-11Tobias S. Josefowitz  memcpy(ptr, &v, 8); }
42c2522017-07-17Martin Nilsson static inline unsigned INT32 ATTRIBUTE((unused)) get_unaligned32(const void * ptr) {
e744702014-01-11Tobias S. Josefowitz  unsigned INT32 v; memcpy(&v, ptr, 4); return v; }
01b9212016-01-12Per Hedbor static inline void ATTRIBUTE((unused)) set_unaligned32(void * ptr, unsigned INT32 v) {
e744702014-01-11Tobias S. Josefowitz  memcpy(ptr, &v, 4); }
01b9212016-01-12Per Hedbor 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; }
01b9212016-01-12Per Hedbor static inline void ATTRIBUTE((unused)) set_unaligned16(void * ptr, unsigned INT16 v) {
e744702014-01-11Tobias S. Josefowitz  memcpy(ptr, &v, 2); }
8e936c2015-08-06Per Hedbor #endif
e744702014-01-11Tobias S. Josefowitz 
13ee8f2006-08-09Martin Stjernholm extern int page_size;
d0e2311999-10-24Henrik Grubbström (Grubba) /* Note to self: Prototypes must be updated manually /Hubbe */
644ea52018-02-01Martin Nilsson PMOD_EXPORT long pcharp_strlen(const PCHARP a) ATTRIBUTE((pure));
66d9282011-05-01Per Hedbor 
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));
7366d02018-02-01Stephen R. van den Berg void reorder(char *memory, INT32 nitems, INT32 size, const INT32 *order);
34ffc02011-05-15Per Hedbor 
e3b3a22016-06-28Henrik Grubbström (Grubba) size_t hashmem_siphash24( const void *s, size_t len );
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));
479c112018-01-18Martin Nilsson 
377d052015-05-26Henrik Grubbström (Grubba) #define MALLOC_FUNCTION ATTRIBUTE((malloc)) PIKE_WARN_UNUSED_RESULT_ATTRIBUTE
0ce2f72011-05-10Per Hedbor  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
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 */
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