1 | /******************************************************************************/ |
2 | #ifdef JEMALLOC_H_TYPES |
3 | |
4 | #ifdef JEMALLOC_VALGRIND |
5 | #include <valgrind/valgrind.h> |
6 | |
7 | /* |
8 | * The size that is reported to Valgrind must be consistent through a chain of |
9 | * malloc..realloc..realloc calls. Request size isn't recorded anywhere in |
10 | * jemalloc, so it is critical that all callers of these macros provide usize |
11 | * rather than request size. As a result, buffer overflow detection is |
12 | * technically weakened for the standard API, though it is generally accepted |
13 | * practice to consider any extra bytes reported by malloc_usable_size() as |
14 | * usable space. |
15 | */ |
16 | #define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do { \ |
17 | if (unlikely(in_valgrind)) \ |
18 | valgrind_make_mem_noaccess(ptr, usize); \ |
19 | } while (0) |
20 | #define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do { \ |
21 | if (unlikely(in_valgrind)) \ |
22 | valgrind_make_mem_undefined(ptr, usize); \ |
23 | } while (0) |
24 | #define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do { \ |
25 | if (unlikely(in_valgrind)) \ |
26 | valgrind_make_mem_defined(ptr, usize); \ |
27 | } while (0) |
28 | /* |
29 | * The VALGRIND_MALLOCLIKE_BLOCK() and VALGRIND_RESIZEINPLACE_BLOCK() macro |
30 | * calls must be embedded in macros rather than in functions so that when |
31 | * Valgrind reports errors, there are no extra stack frames in the backtraces. |
32 | */ |
33 | #define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do { \ |
34 | if (unlikely(in_valgrind && cond)) { \ |
35 | VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, p2rz(tsdn, ptr), \ |
36 | zero); \ |
37 | } \ |
38 | } while (0) |
39 | #define JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize, \ |
40 | ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ |
41 | zero) do { \ |
42 | if (unlikely(in_valgrind)) { \ |
43 | size_t rzsize = p2rz(tsdn, ptr); \ |
44 | \ |
45 | if (!maybe_moved || ptr == old_ptr) { \ |
46 | VALGRIND_RESIZEINPLACE_BLOCK(ptr, old_usize, \ |
47 | usize, rzsize); \ |
48 | if (zero && old_usize < usize) { \ |
49 | valgrind_make_mem_defined( \ |
50 | (void *)((uintptr_t)ptr + \ |
51 | old_usize), usize - old_usize); \ |
52 | } \ |
53 | } else { \ |
54 | if (!old_ptr_maybe_null || old_ptr != NULL) { \ |
55 | valgrind_freelike_block(old_ptr, \ |
56 | old_rzsize); \ |
57 | } \ |
58 | if (!ptr_maybe_null || ptr != NULL) { \ |
59 | size_t copy_size = (old_usize < usize) \ |
60 | ? old_usize : usize; \ |
61 | size_t tail_size = usize - copy_size; \ |
62 | VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, \ |
63 | rzsize, false); \ |
64 | if (copy_size > 0) { \ |
65 | valgrind_make_mem_defined(ptr, \ |
66 | copy_size); \ |
67 | } \ |
68 | if (zero && tail_size > 0) { \ |
69 | valgrind_make_mem_defined( \ |
70 | (void *)((uintptr_t)ptr + \ |
71 | copy_size), tail_size); \ |
72 | } \ |
73 | } \ |
74 | } \ |
75 | } \ |
76 | } while (0) |
77 | #define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do { \ |
78 | if (unlikely(in_valgrind)) \ |
79 | valgrind_freelike_block(ptr, rzsize); \ |
80 | } while (0) |
81 | #else |
82 | #define RUNNING_ON_VALGRIND ((unsigned)0) |
83 | #define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {} while (0) |
84 | #define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {} while (0) |
85 | #define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {} while (0) |
86 | #define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do {} while (0) |
87 | #define JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize, \ |
88 | ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ |
89 | zero) do {} while (0) |
90 | #define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do {} while (0) |
91 | #endif |
92 | |
93 | #endif /* JEMALLOC_H_TYPES */ |
94 | /******************************************************************************/ |
95 | #ifdef JEMALLOC_H_STRUCTS |
96 | |
97 | #endif /* JEMALLOC_H_STRUCTS */ |
98 | /******************************************************************************/ |
99 | #ifdef JEMALLOC_H_EXTERNS |
100 | |
101 | #ifdef JEMALLOC_VALGRIND |
102 | void valgrind_make_mem_noaccess(void *ptr, size_t usize); |
103 | void valgrind_make_mem_undefined(void *ptr, size_t usize); |
104 | void valgrind_make_mem_defined(void *ptr, size_t usize); |
105 | void valgrind_freelike_block(void *ptr, size_t usize); |
106 | #endif |
107 | |
108 | #endif /* JEMALLOC_H_EXTERNS */ |
109 | /******************************************************************************/ |
110 | #ifdef JEMALLOC_H_INLINES |
111 | |
112 | #endif /* JEMALLOC_H_INLINES */ |
113 | /******************************************************************************/ |
114 | |
115 | |