21#ifdef WITH_MEM_VALGRIND
22# include "valgrind/memcheck.h"
26#include "../../source/blender/blenlib/BLI_strict_flags.h"
36typedef struct MemHead {
40static_assert(MEM_MIN_CPP_ALIGNMENT <=
alignof(MemHead),
"Bad alignment of MemHead");
41static_assert(MEM_MIN_CPP_ALIGNMENT <=
sizeof(MemHead),
"Bad size of MemHead");
43typedef struct MemHeadAligned {
47static_assert(MEM_MIN_CPP_ALIGNMENT <=
alignof(MemHeadAligned),
"Bad alignment of MemHeadAligned");
48static_assert(MEM_MIN_CPP_ALIGNMENT <=
sizeof(MemHeadAligned),
"Bad size of MemHeadAligned");
74#define MEMHEAD_FROM_PTR(ptr) (((MemHead *)ptr) - 1)
75#define PTR_FROM_MEMHEAD(memhead) (memhead + 1)
76#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned *)ptr) - 1)
77#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & size_t(MEMHEAD_FLAG_ALIGN))
78#define MEMHEAD_IS_FROM_CPP_NEW(memhead) ((memhead)->len & size_t(MEMHEAD_FLAG_FROM_CPP_NEW))
79#define MEMHEAD_LEN(memhead) ((memhead)->len & ~size_t(MEMHEAD_FLAG_MASK))
88 vsnprintf(buf,
sizeof(buf), message, str_format_args);
89 buf[
sizeof(buf) - 1] =
'\0';
102 va_list str_format_args;
103 va_start(str_format_args, message);
105 va_end(str_format_args);
114 va_list str_format_args;
116 va_start(str_format_args, message);
118 va_end(str_format_args);
120 if (vmemh ==
nullptr) {
128 const void *address = memh;
129 size_t size =
len +
sizeof(*memh);
164 "Attempt to use C-style MEM_freeN on a pointer created with CPP-style MEM_new or new\n");
170 memset(memh + 1, 255,
len);
183 void *newp =
nullptr;
190 "Attempt to use C-style MEM_dupallocN on a pointer created with "
191 "CPP-style MEM_new or new\n");
202 memcpy(newp, vmemh, prev_size);
209 void *newp =
nullptr;
217 "Attempt to use C-style MEM_reallocN on a pointer created with "
218 "CPP-style MEM_new or new\n");
233 memcpy(newp, vmemh,
len);
237 memcpy(newp, vmemh, old_len);
252 void *newp =
nullptr;
260 "Attempt to use C-style MEM_recallocN on a pointer created with "
261 "CPP-style MEM_new or new\n");
276 memcpy(newp, vmemh,
len);
279 memcpy(newp, vmemh, old_len);
284 memset(((
char *)newp) + old_len, 0,
len - old_len);
304 memh = (MemHead *)calloc(1,
len +
sizeof(MemHead));
324 "Calloc array aborted due to integer overflow: "
341#ifdef WITH_MEM_VALGRIND
342 const size_t len_unaligned =
len;
346 memh = (MemHead *)malloc(
len +
sizeof(MemHead));
352 memset(memh + 1, 255,
len);
354#ifdef WITH_MEM_VALGRIND
356 VALGRIND_MAKE_MEM_UNDEFINED(memh + 1, len_unaligned);
359 VALGRIND_MAKE_MEM_DEFINED((
const char *)(memh + 1) + len_unaligned,
len - len_unaligned);
381 "Malloc array aborted due to integer overflow: "
419#ifdef WITH_MEM_VALGRIND
420 const size_t len_unaligned =
len;
425 len + extra_padding +
sizeof(MemHeadAligned), alignment);
432 memh = (MemHeadAligned *)((
char *)memh + extra_padding);
436 memset(memh + 1, 255,
len);
438#ifdef WITH_MEM_VALGRIND
440 VALGRIND_MAKE_MEM_UNDEFINED(memh + 1, len_unaligned);
443 VALGRIND_MAKE_MEM_DEFINED((
const char *)(memh + 1) + len_unaligned,
len - len_unaligned);
451 memh->alignment = short(alignment);
465 const size_t alignment,
471 "Calloc array aborted due to integer overflow: "
480 if (alignment <= MEM_MIN_CPP_ALIGNMENT) {
489 const size_t alignment,
498 const size_t alignment,
503 if (alignment <= MEM_MIN_CPP_ALIGNMENT) {
512 memset(
ptr, 0, bytes_num);
534 "\nFor more detailed per-block statistics run Blender with memory debugging command line "
537#ifdef HAVE_MALLOC_STATS
538 printf(
"System Statistics:\n");
584 return "unknown block name ptr";
587 return "MEM_lockfree_name_ptr(nullptr)";
void BLI_kdtree_nd_ free(KDTree *tree)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static __attribute__((constructor)) void cpu_check()
#define assert(assertion)
bool leak_detector_has_run
char free_after_leak_detection_message[]
void aligned_free(void *ptr)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
void * aligned_malloc(size_t size, size_t alignment)
static bool malloc_debug_memset
static void(* error_callback)(const char *)
@ MEMHEAD_FLAG_FROM_CPP_NEW
MEM_INLINE bool MEM_size_safe_multiply(size_t a, size_t b, size_t *result)
MEM_INLINE void MEM_trigger_error_on_memory_block(const void *, const size_t)
size_t memory_usage_current(void)
#define MEMHEAD_REAL_PTR(memh)
#define MEMHEAD_ALIGN_PADDING(alignment)
void memory_usage_block_alloc(size_t size)
#define SIZET_ALIGN_4(len)
size_t memory_usage_block_num(void)
void memory_usage_block_free(size_t size)
size_t memory_usage_peak(void)
#define ALIGNED_MALLOC_MINIMUM_ALIGNMENT
void memory_usage_peak_reset(void)
uint MEM_lockfree_get_memory_blocks_in_use()
void * MEM_lockfree_mallocN(size_t len, const char *str)
void MEM_lockfree_printmemlist_pydict()
static void * mem_lockfree_malloc_arrayN_aligned(const size_t len, const size_t size, const size_t alignment, const char *str, size_t &r_bytes_num)
void * MEM_lockfree_dupallocN(const void *vmemh)
void * MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_lockfree_reset_peak_memory()
void MEM_lockfree_set_error_callback(void(*func)(const char *))
void * MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str, const AllocationType allocation_type)
#define PTR_FROM_MEMHEAD(memhead)
void * MEM_lockfree_calloc_arrayN_aligned(const size_t len, const size_t size, const size_t alignment, const char *str)
size_t MEM_lockfree_get_peak_memory()
static void(* error_callback)(const char *)
void * MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str)
void MEM_lockfree_name_ptr_set(void *, const char *)
static void print_error(const char *message, va_list str_format_args)
void * MEM_lockfree_callocN(size_t len, const char *str)
void * MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str)
static void report_error_on_address(const void *vmemh, const char *message,...)
void MEM_lockfree_set_memory_debug()
bool MEM_lockfree_consistency_check()
void MEM_lockfree_printmemlist()
#define MEMHEAD_LEN(memhead)
#define MEMHEAD_IS_ALIGNED(memhead)
void * MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str)
const char * MEM_lockfree_name_ptr(void *vmemh)
void MEM_lockfree_callbackmemlist(void(*func)(void *))
#define MEMHEAD_FROM_PTR(ptr)
size_t MEM_lockfree_get_memory_in_use()
void MEM_lockfree_freeN(void *vmemh, AllocationType allocation_type)
void * MEM_lockfree_malloc_arrayN_aligned(const size_t len, const size_t size, const size_t alignment, const char *str)
#define MEMHEAD_IS_FROM_CPP_NEW(memhead)
#define MEMHEAD_ALIGNED_FROM_PTR(ptr)
void mem_lockfree_clearmemlist()
size_t MEM_lockfree_allocN_len(const void *vmemh)
void MEM_lockfree_printmemlist_stats()
void *(* mem_mallocN)(size_t len, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)