Blender V4.3
MEM_guardedalloc.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
34#ifndef __MEM_GUARDEDALLOC_H__
35#define __MEM_GUARDEDALLOC_H__
36
37/* Needed for uintptr_t and attributes, exception, don't use BLI anywhere else in `MEM_*` */
40
41#include <string.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
52extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
53
59void MEM_freeN(void *vmemh);
60
61#if 0 /* UNUSED */
65extern short (*MEM_testN)(void *vmemh);
66#endif
67
72extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
73
79extern void *(*MEM_reallocN_id)(void *vmemh,
80 size_t len,
81 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
83
87extern void *(*MEM_recallocN_id)(void *vmemh,
88 size_t len,
89 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
91
92#define MEM_reallocN(vmemh, len) MEM_reallocN_id(vmemh, len, __func__)
93#define MEM_recallocN(vmemh, len) MEM_recallocN_id(vmemh, len, __func__)
94
100extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
102
108extern void *(*MEM_calloc_arrayN)(size_t len,
109 size_t size,
110 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
112
117extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
119
125extern void *(*MEM_malloc_arrayN)(size_t len,
126 size_t size,
127 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
129
134void *MEM_mallocN_aligned(size_t len,
135 size_t alignment,
136 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
138
142extern void *(*MEM_calloc_arrayN_aligned)(
143 size_t len,
144 size_t size,
145 size_t alignment,
146 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1, 2)
148
153extern void (*MEM_printmemlist_pydict)(void);
154
158extern void (*MEM_printmemlist)(void);
159
161extern void (*MEM_callbackmemlist)(void (*func)(void *));
162
164extern void (*MEM_printmemlist_stats)(void);
165
167extern void (*MEM_set_error_callback)(void (*func)(const char *));
168
174extern bool (*MEM_consistency_check)(void);
175
177extern void (*MEM_set_memory_debug)(void);
178
180extern size_t (*MEM_get_memory_in_use)(void);
182extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
183
185extern void (*MEM_reset_peak_memory)(void);
186
188extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
189
190#ifdef __cplusplus
191# define MEM_SAFE_FREE(v) \
192 do { \
193 static_assert(std::is_pointer_v<std::decay_t<decltype(v)>>); \
194 void **_v = (void **)&(v); \
195 if (*_v) { \
196 MEM_freeN(*_v); \
197 *_v = NULL; \
198 } \
199 } while (0)
200#else
201# define MEM_SAFE_FREE(v) \
202 do { \
203 void **_v = (void **)&(v); \
204 if (*_v) { \
205 MEM_freeN(*_v); \
206 *_v = NULL; \
207 } \
208 } while (0)
209#endif
210
212#define MEM_SIZE_OVERHEAD sizeof(size_t)
213#define MEM_SIZE_OPTIMAL(size) ((size)-MEM_SIZE_OVERHEAD)
214
215#ifndef NDEBUG
216extern const char *(*MEM_name_ptr)(void *vmemh);
225extern void (*MEM_name_ptr_set)(void *vmemh, const char *str) ATTR_NONNULL();
226#endif
227
233
238void MEM_use_memleak_detection(bool enabled);
239
246
257
268
269#ifdef __cplusplus
270}
271#endif /* __cplusplus */
272
273#ifdef __cplusplus
274
275# include <any>
276# include <memory>
277# include <new>
278# include <type_traits>
279# include <utility>
280
282
288# define MEM_MIN_CPP_ALIGNMENT \
289 (__STDCPP_DEFAULT_NEW_ALIGNMENT__ < alignof(void *) ? __STDCPP_DEFAULT_NEW_ALIGNMENT__ : \
290 alignof(void *))
291
302template<typename T, typename... Args>
303inline T *MEM_new(const char *allocation_name, Args &&...args)
304{
306 sizeof(T), alignof(T), allocation_name, mem_guarded::internal::AllocationType::NEW_DELETE);
307 return new (buffer) T(std::forward<Args>(args)...);
308}
309
319template<typename T> inline void MEM_delete(const T *ptr)
320{
321 static_assert(
322 !std::is_void_v<T>,
323 "MEM_delete on a void pointer is not possible, `static_cast` it to the correct type");
324 if (ptr == nullptr) {
325 return;
326 }
327 /* C++ allows destruction of `const` objects, so the pointer is allowed to be `const`. */
328 ptr->~T();
331}
332
340template<typename T> inline T *MEM_cnew(const char *allocation_name)
341{
342 static_assert(std::is_trivial_v<T>, "For non-trivial types, MEM_new must be used.");
343 return static_cast<T *>(MEM_calloc_arrayN_aligned(1, sizeof(T), alignof(T), allocation_name));
344}
345
349template<typename T> inline T *MEM_cnew_array(const size_t length, const char *allocation_name)
350{
351 static_assert(std::is_trivial_v<T>, "For non-trivial types, MEM_new must be used.");
352 return static_cast<T *>(
353 MEM_calloc_arrayN_aligned(length, sizeof(T), alignof(T), allocation_name));
354}
355
366template<typename T> inline T *MEM_cnew(const char *allocation_name, const T &other)
367{
368 static_assert(std::is_trivial_v<T>, "For non-trivial types, MEM_new must be used.");
369 T *new_object = static_cast<T *>(MEM_mallocN_aligned(sizeof(T), alignof(T), allocation_name));
370 if (new_object) {
371 memcpy(new_object, &other, sizeof(T));
372 }
373 return new_object;
374}
375
377# define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
378 public: \
379 void *operator new(size_t num_bytes) \
380 { \
381 return mem_guarded::internal::mem_mallocN_aligned_ex( \
382 num_bytes, \
383 __STDCPP_DEFAULT_NEW_ALIGNMENT__, \
384 _id, \
385 mem_guarded::internal::AllocationType::NEW_DELETE); \
386 } \
387 void *operator new(size_t num_bytes, std::align_val_t alignment) \
388 { \
389 return mem_guarded::internal::mem_mallocN_aligned_ex( \
390 num_bytes, size_t(alignment), _id, mem_guarded::internal::AllocationType::NEW_DELETE); \
391 } \
392 void operator delete(void *mem) \
393 { \
394 if (mem) { \
395 mem_guarded::internal::mem_freeN_ex(mem, \
396 mem_guarded::internal::AllocationType::NEW_DELETE); \
397 } \
398 } \
399 void *operator new[](size_t num_bytes) \
400 { \
401 return mem_guarded::internal::mem_mallocN_aligned_ex( \
402 num_bytes, \
403 __STDCPP_DEFAULT_NEW_ALIGNMENT__, \
404 _id "[]", \
405 mem_guarded::internal::AllocationType::NEW_DELETE); \
406 } \
407 void *operator new[](size_t num_bytes, std::align_val_t alignment) \
408 { \
409 return mem_guarded::internal::mem_mallocN_aligned_ex( \
410 num_bytes, \
411 size_t(alignment), \
412 _id "[]", \
413 mem_guarded::internal::AllocationType::NEW_DELETE); \
414 } \
415 void operator delete[](void *mem) \
416 { \
417 if (mem) { \
418 mem_guarded::internal::mem_freeN_ex(mem, \
419 mem_guarded::internal::AllocationType::NEW_DELETE); \
420 } \
421 } \
422 void *operator new(size_t /*count*/, void *ptr) \
423 { \
424 return ptr; \
425 } \
426
430 \
431 void operator delete(void * /*ptr_to_free*/, void * /*ptr*/) {}
432
442template<typename T, typename... Args> T &MEM_construct_leak_detection_data(Args &&...args)
443{
444 std::shared_ptr<T> data = std::make_shared<T>(std::forward<Args>(args)...);
445 std::any any_data = std::make_any<std::shared_ptr<T>>(data);
447 return *data;
448}
449
450#endif /* __cplusplus */
451
452#endif /* __MEM_GUARDEDALLOC_H__ */
#define ATTR_WARN_UNUSED_RESULT
#define ATTR_ALLOC_SIZE(...)
#define ATTR_NONNULL(...)
void *(* MEM_mallocN)(size_t len, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
Definition mallocn.cc:44
void MEM_use_guarded_allocator(void)
Definition mallocn.cc:170
void MEM_use_memleak_detection(bool enabled)
void(* MEM_reset_peak_memory)(void)
Definition mallocn.cc:64
void MEM_enable_fail_on_memleak(void)
size_t(* MEM_get_memory_in_use)(void)
Definition mallocn.cc:62
void(* MEM_printmemlist_stats)(void)
Definition mallocn.cc:58
void(* MEM_set_memory_debug)(void)
Definition mallocn.cc:61
size_t(* MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT
Definition mallocn.cc:65
void *(* MEM_calloc_arrayN_aligned)(size_t len, size_t size, size_t alignment, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
Definition mallocn.cc:51
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
Definition mallocn.cc:45
void MEM_init_memleak_detection(void)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3)
Definition mallocn.cc:110
void(* MEM_set_error_callback)(void(*func)(const char *))
Definition mallocn.cc:59
size_t(* MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT
Definition mallocn.cc:36
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
Definition mallocn.cc:43
void MEM_use_lockfree_allocator(void)
Definition mallocn.cc:130
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
bool(* MEM_consistency_check)(void)
Definition mallocn.cc:60
unsigned int(* MEM_get_memory_blocks_in_use)(void)
Definition mallocn.cc:63
void(* MEM_name_ptr_set)(void *vmemh, const char *str) ATTR_NONNULL()
Definition mallocn.cc:71
void(* MEM_printmemlist_pydict)(void)
Definition mallocn.cc:55
void(* MEM_callbackmemlist)(void(*func)(void *))
Definition mallocn.cc:57
void(* MEM_printmemlist)(void)
Definition mallocn.cc:56
int len
#define str(s)
#define T
void add_memleak_data(std::any data)
void(* mem_freeN_ex)(void *vmemh, AllocationType allocation_type)
Definition mallocn.cc:37
void *(* mem_mallocN_aligned_ex)(size_t len, size_t alignment, const char *str, AllocationType allocation_type)
Definition mallocn.cc:46
PointerRNA * ptr
Definition wm_files.cc:4126