1 //===-- memprof_interceptors.cpp -----------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of MemProfiler, a memory profiler.
11 // Interceptors for operators new and delete.
12 //===----------------------------------------------------------------------===//
14 #include "memprof_allocator.h"
15 #include "memprof_internal.h"
16 #include "memprof_stack.h"
17 #include "sanitizer_common/sanitizer_allocator_report.h"
19 #include "interception/interception.h"
23 #define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
25 using namespace __memprof
;
27 // Fake std::nothrow_t and std::align_val_t to avoid including <new>.
30 enum class align_val_t
: size_t {};
33 #define OPERATOR_NEW_BODY(type, nothrow) \
34 GET_STACK_TRACE_MALLOC; \
35 void *res = memprof_memalign(0, size, &stack, type); \
36 if (!nothrow && UNLIKELY(!res)) \
37 ReportOutOfMemory(size, &stack); \
39 #define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
40 GET_STACK_TRACE_MALLOC; \
41 void *res = memprof_memalign((uptr)align, size, &stack, type); \
42 if (!nothrow && UNLIKELY(!res)) \
43 ReportOutOfMemory(size, &stack); \
46 CXX_OPERATOR_ATTRIBUTE
47 void *operator new(size_t size
) {
48 OPERATOR_NEW_BODY(FROM_NEW
, false /*nothrow*/);
50 CXX_OPERATOR_ATTRIBUTE
51 void *operator new[](size_t size
) {
52 OPERATOR_NEW_BODY(FROM_NEW_BR
, false /*nothrow*/);
54 CXX_OPERATOR_ATTRIBUTE
55 void *operator new(size_t size
, std::nothrow_t
const &) {
56 OPERATOR_NEW_BODY(FROM_NEW
, true /*nothrow*/);
58 CXX_OPERATOR_ATTRIBUTE
59 void *operator new[](size_t size
, std::nothrow_t
const &) {
60 OPERATOR_NEW_BODY(FROM_NEW_BR
, true /*nothrow*/);
62 CXX_OPERATOR_ATTRIBUTE
63 void *operator new(size_t size
, std::align_val_t align
) {
64 OPERATOR_NEW_BODY_ALIGN(FROM_NEW
, false /*nothrow*/);
66 CXX_OPERATOR_ATTRIBUTE
67 void *operator new[](size_t size
, std::align_val_t align
) {
68 OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR
, false /*nothrow*/);
70 CXX_OPERATOR_ATTRIBUTE
71 void *operator new(size_t size
, std::align_val_t align
,
72 std::nothrow_t
const &) {
73 OPERATOR_NEW_BODY_ALIGN(FROM_NEW
, true /*nothrow*/);
75 CXX_OPERATOR_ATTRIBUTE
76 void *operator new[](size_t size
, std::align_val_t align
,
77 std::nothrow_t
const &) {
78 OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR
, true /*nothrow*/);
81 #define OPERATOR_DELETE_BODY(type) \
82 GET_STACK_TRACE_FREE; \
83 memprof_delete(ptr, 0, 0, &stack, type);
85 #define OPERATOR_DELETE_BODY_SIZE(type) \
86 GET_STACK_TRACE_FREE; \
87 memprof_delete(ptr, size, 0, &stack, type);
89 #define OPERATOR_DELETE_BODY_ALIGN(type) \
90 GET_STACK_TRACE_FREE; \
91 memprof_delete(ptr, 0, static_cast<uptr>(align), &stack, type);
93 #define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \
94 GET_STACK_TRACE_FREE; \
95 memprof_delete(ptr, size, static_cast<uptr>(align), &stack, type);
97 CXX_OPERATOR_ATTRIBUTE
98 void operator delete(void *ptr
)NOEXCEPT
{ OPERATOR_DELETE_BODY(FROM_NEW
); }
99 CXX_OPERATOR_ATTRIBUTE
100 void operator delete[](void *ptr
) NOEXCEPT
{
101 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
103 CXX_OPERATOR_ATTRIBUTE
104 void operator delete(void *ptr
, std::nothrow_t
const &) {
105 OPERATOR_DELETE_BODY(FROM_NEW
);
107 CXX_OPERATOR_ATTRIBUTE
108 void operator delete[](void *ptr
, std::nothrow_t
const &) {
109 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
111 CXX_OPERATOR_ATTRIBUTE
112 void operator delete(void *ptr
, size_t size
)NOEXCEPT
{
113 OPERATOR_DELETE_BODY_SIZE(FROM_NEW
);
115 CXX_OPERATOR_ATTRIBUTE
116 void operator delete[](void *ptr
, size_t size
) NOEXCEPT
{
117 OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR
);
119 CXX_OPERATOR_ATTRIBUTE
120 void operator delete(void *ptr
, std::align_val_t align
)NOEXCEPT
{
121 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW
);
123 CXX_OPERATOR_ATTRIBUTE
124 void operator delete[](void *ptr
, std::align_val_t align
) NOEXCEPT
{
125 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR
);
127 CXX_OPERATOR_ATTRIBUTE
128 void operator delete(void *ptr
, std::align_val_t align
,
129 std::nothrow_t
const &) {
130 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW
);
132 CXX_OPERATOR_ATTRIBUTE
133 void operator delete[](void *ptr
, std::align_val_t align
,
134 std::nothrow_t
const &) {
135 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR
);
137 CXX_OPERATOR_ATTRIBUTE
138 void operator delete(void *ptr
, size_t size
, std::align_val_t align
)NOEXCEPT
{
139 OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW
);
141 CXX_OPERATOR_ATTRIBUTE
142 void operator delete[](void *ptr
, size_t size
,
143 std::align_val_t align
) NOEXCEPT
{
144 OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR
);