xref: /llvm-project/compiler-rt/lib/memprof/memprof_new_delete.cpp (revision 3d4bba302d2460b9ac6463ef920c301f1f40fb41)
1*3d4bba30STeresa Johnson //===-- memprof_interceptors.cpp -----------------------------------------===//
2*3d4bba30STeresa Johnson //
3*3d4bba30STeresa Johnson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*3d4bba30STeresa Johnson // See https://llvm.org/LICENSE.txt for license information.
5*3d4bba30STeresa Johnson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*3d4bba30STeresa Johnson //
7*3d4bba30STeresa Johnson //===----------------------------------------------------------------------===//
8*3d4bba30STeresa Johnson //
9*3d4bba30STeresa Johnson // This file is a part of MemProfiler, a memory profiler.
10*3d4bba30STeresa Johnson //
11*3d4bba30STeresa Johnson // Interceptors for operators new and delete.
12*3d4bba30STeresa Johnson //===----------------------------------------------------------------------===//
13*3d4bba30STeresa Johnson 
14*3d4bba30STeresa Johnson #include "memprof_allocator.h"
15*3d4bba30STeresa Johnson #include "memprof_internal.h"
16*3d4bba30STeresa Johnson #include "memprof_stack.h"
17*3d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_allocator_report.h"
18*3d4bba30STeresa Johnson 
19*3d4bba30STeresa Johnson #include "interception/interception.h"
20*3d4bba30STeresa Johnson 
21*3d4bba30STeresa Johnson #include <stddef.h>
22*3d4bba30STeresa Johnson 
23*3d4bba30STeresa Johnson #define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
24*3d4bba30STeresa Johnson 
25*3d4bba30STeresa Johnson using namespace __memprof;
26*3d4bba30STeresa Johnson 
27*3d4bba30STeresa Johnson // Fake std::nothrow_t and std::align_val_t to avoid including <new>.
28*3d4bba30STeresa Johnson namespace std {
29*3d4bba30STeresa Johnson struct nothrow_t {};
30*3d4bba30STeresa Johnson enum class align_val_t : size_t {};
31*3d4bba30STeresa Johnson } // namespace std
32*3d4bba30STeresa Johnson 
33*3d4bba30STeresa Johnson #define OPERATOR_NEW_BODY(type, nothrow)                                       \
34*3d4bba30STeresa Johnson   GET_STACK_TRACE_MALLOC;                                                      \
35*3d4bba30STeresa Johnson   void *res = memprof_memalign(0, size, &stack, type);                         \
36*3d4bba30STeresa Johnson   if (!nothrow && UNLIKELY(!res))                                              \
37*3d4bba30STeresa Johnson     ReportOutOfMemory(size, &stack);                                           \
38*3d4bba30STeresa Johnson   return res;
39*3d4bba30STeresa Johnson #define OPERATOR_NEW_BODY_ALIGN(type, nothrow)                                 \
40*3d4bba30STeresa Johnson   GET_STACK_TRACE_MALLOC;                                                      \
41*3d4bba30STeresa Johnson   void *res = memprof_memalign((uptr)align, size, &stack, type);               \
42*3d4bba30STeresa Johnson   if (!nothrow && UNLIKELY(!res))                                              \
43*3d4bba30STeresa Johnson     ReportOutOfMemory(size, &stack);                                           \
44*3d4bba30STeresa Johnson   return res;
45*3d4bba30STeresa Johnson 
46*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new(size_t size)47*3d4bba30STeresa Johnson void *operator new(size_t size) {
48*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);
49*3d4bba30STeresa Johnson }
50*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new[](size_t size)51*3d4bba30STeresa Johnson void *operator new[](size_t size) {
52*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);
53*3d4bba30STeresa Johnson }
54*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new(size_t size,std::nothrow_t const &)55*3d4bba30STeresa Johnson void *operator new(size_t size, std::nothrow_t const &) {
56*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);
57*3d4bba30STeresa Johnson }
58*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new[](size_t size,std::nothrow_t const &)59*3d4bba30STeresa Johnson void *operator new[](size_t size, std::nothrow_t const &) {
60*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);
61*3d4bba30STeresa Johnson }
62*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new(size_t size,std::align_val_t align)63*3d4bba30STeresa Johnson void *operator new(size_t size, std::align_val_t align) {
64*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/);
65*3d4bba30STeresa Johnson }
66*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new[](size_t size,std::align_val_t align)67*3d4bba30STeresa Johnson void *operator new[](size_t size, std::align_val_t align) {
68*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/);
69*3d4bba30STeresa Johnson }
70*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new(size_t size,std::align_val_t align,std::nothrow_t const &)71*3d4bba30STeresa Johnson void *operator new(size_t size, std::align_val_t align,
72*3d4bba30STeresa Johnson                    std::nothrow_t const &) {
73*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/);
74*3d4bba30STeresa Johnson }
75*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator new[](size_t size,std::align_val_t align,std::nothrow_t const &)76*3d4bba30STeresa Johnson void *operator new[](size_t size, std::align_val_t align,
77*3d4bba30STeresa Johnson                      std::nothrow_t const &) {
78*3d4bba30STeresa Johnson   OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/);
79*3d4bba30STeresa Johnson }
80*3d4bba30STeresa Johnson 
81*3d4bba30STeresa Johnson #define OPERATOR_DELETE_BODY(type)                                             \
82*3d4bba30STeresa Johnson   GET_STACK_TRACE_FREE;                                                        \
83*3d4bba30STeresa Johnson   memprof_delete(ptr, 0, 0, &stack, type);
84*3d4bba30STeresa Johnson 
85*3d4bba30STeresa Johnson #define OPERATOR_DELETE_BODY_SIZE(type)                                        \
86*3d4bba30STeresa Johnson   GET_STACK_TRACE_FREE;                                                        \
87*3d4bba30STeresa Johnson   memprof_delete(ptr, size, 0, &stack, type);
88*3d4bba30STeresa Johnson 
89*3d4bba30STeresa Johnson #define OPERATOR_DELETE_BODY_ALIGN(type)                                       \
90*3d4bba30STeresa Johnson   GET_STACK_TRACE_FREE;                                                        \
91*3d4bba30STeresa Johnson   memprof_delete(ptr, 0, static_cast<uptr>(align), &stack, type);
92*3d4bba30STeresa Johnson 
93*3d4bba30STeresa Johnson #define OPERATOR_DELETE_BODY_SIZE_ALIGN(type)                                  \
94*3d4bba30STeresa Johnson   GET_STACK_TRACE_FREE;                                                        \
95*3d4bba30STeresa Johnson   memprof_delete(ptr, size, static_cast<uptr>(align), &stack, type);
96*3d4bba30STeresa Johnson 
97*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete(void * ptr)98*3d4bba30STeresa Johnson void operator delete(void *ptr)NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW); }
99*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete[](void * ptr)100*3d4bba30STeresa Johnson void operator delete[](void *ptr) NOEXCEPT {
101*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY(FROM_NEW_BR);
102*3d4bba30STeresa Johnson }
103*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete(void * ptr,std::nothrow_t const &)104*3d4bba30STeresa Johnson void operator delete(void *ptr, std::nothrow_t const &) {
105*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY(FROM_NEW);
106*3d4bba30STeresa Johnson }
107*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete[](void * ptr,std::nothrow_t const &)108*3d4bba30STeresa Johnson void operator delete[](void *ptr, std::nothrow_t const &) {
109*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY(FROM_NEW_BR);
110*3d4bba30STeresa Johnson }
111*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete(void * ptr,size_t size)112*3d4bba30STeresa Johnson void operator delete(void *ptr, size_t size)NOEXCEPT {
113*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_SIZE(FROM_NEW);
114*3d4bba30STeresa Johnson }
115*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete[](void * ptr,size_t size)116*3d4bba30STeresa Johnson void operator delete[](void *ptr, size_t size) NOEXCEPT {
117*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR);
118*3d4bba30STeresa Johnson }
119*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete(void * ptr,std::align_val_t align)120*3d4bba30STeresa Johnson void operator delete(void *ptr, std::align_val_t align)NOEXCEPT {
121*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_ALIGN(FROM_NEW);
122*3d4bba30STeresa Johnson }
123*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete[](void * ptr,std::align_val_t align)124*3d4bba30STeresa Johnson void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {
125*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR);
126*3d4bba30STeresa Johnson }
127*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete(void * ptr,std::align_val_t align,std::nothrow_t const &)128*3d4bba30STeresa Johnson void operator delete(void *ptr, std::align_val_t align,
129*3d4bba30STeresa Johnson                      std::nothrow_t const &) {
130*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_ALIGN(FROM_NEW);
131*3d4bba30STeresa Johnson }
132*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete[](void * ptr,std::align_val_t align,std::nothrow_t const &)133*3d4bba30STeresa Johnson void operator delete[](void *ptr, std::align_val_t align,
134*3d4bba30STeresa Johnson                        std::nothrow_t const &) {
135*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR);
136*3d4bba30STeresa Johnson }
137*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete(void * ptr,size_t size,std::align_val_t align)138*3d4bba30STeresa Johnson void operator delete(void *ptr, size_t size, std::align_val_t align)NOEXCEPT {
139*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW);
140*3d4bba30STeresa Johnson }
141*3d4bba30STeresa Johnson CXX_OPERATOR_ATTRIBUTE
operator delete[](void * ptr,size_t size,std::align_val_t align)142*3d4bba30STeresa Johnson void operator delete[](void *ptr, size_t size,
143*3d4bba30STeresa Johnson                        std::align_val_t align) NOEXCEPT {
144*3d4bba30STeresa Johnson   OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR);
145*3d4bba30STeresa Johnson }
146