1*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2*58b9f456SAndroid Build Coastguard Worker //
3*58b9f456SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*58b9f456SAndroid Build Coastguard Worker //
5*58b9f456SAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*58b9f456SAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*58b9f456SAndroid Build Coastguard Worker //
8*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*58b9f456SAndroid Build Coastguard Worker
10*58b9f456SAndroid Build Coastguard Worker #ifndef COUNT_NEW_HPP
11*58b9f456SAndroid Build Coastguard Worker #define COUNT_NEW_HPP
12*58b9f456SAndroid Build Coastguard Worker
13*58b9f456SAndroid Build Coastguard Worker # include <cstdlib>
14*58b9f456SAndroid Build Coastguard Worker # include <cassert>
15*58b9f456SAndroid Build Coastguard Worker # include <new>
16*58b9f456SAndroid Build Coastguard Worker
17*58b9f456SAndroid Build Coastguard Worker #include "test_macros.h"
18*58b9f456SAndroid Build Coastguard Worker
19*58b9f456SAndroid Build Coastguard Worker #if defined(TEST_HAS_SANITIZERS)
20*58b9f456SAndroid Build Coastguard Worker #define DISABLE_NEW_COUNT
21*58b9f456SAndroid Build Coastguard Worker #endif
22*58b9f456SAndroid Build Coastguard Worker
23*58b9f456SAndroid Build Coastguard Worker namespace detail
24*58b9f456SAndroid Build Coastguard Worker {
25*58b9f456SAndroid Build Coastguard Worker TEST_NORETURN
throw_bad_alloc_helper()26*58b9f456SAndroid Build Coastguard Worker inline void throw_bad_alloc_helper() {
27*58b9f456SAndroid Build Coastguard Worker #ifndef TEST_HAS_NO_EXCEPTIONS
28*58b9f456SAndroid Build Coastguard Worker throw std::bad_alloc();
29*58b9f456SAndroid Build Coastguard Worker #else
30*58b9f456SAndroid Build Coastguard Worker std::abort();
31*58b9f456SAndroid Build Coastguard Worker #endif
32*58b9f456SAndroid Build Coastguard Worker }
33*58b9f456SAndroid Build Coastguard Worker }
34*58b9f456SAndroid Build Coastguard Worker
35*58b9f456SAndroid Build Coastguard Worker class MemCounter
36*58b9f456SAndroid Build Coastguard Worker {
37*58b9f456SAndroid Build Coastguard Worker public:
38*58b9f456SAndroid Build Coastguard Worker // Make MemCounter super hard to accidentally construct or copy.
39*58b9f456SAndroid Build Coastguard Worker class MemCounterCtorArg_ {};
MemCounter(MemCounterCtorArg_)40*58b9f456SAndroid Build Coastguard Worker explicit MemCounter(MemCounterCtorArg_) { reset(); }
41*58b9f456SAndroid Build Coastguard Worker
42*58b9f456SAndroid Build Coastguard Worker private:
43*58b9f456SAndroid Build Coastguard Worker MemCounter(MemCounter const &);
44*58b9f456SAndroid Build Coastguard Worker MemCounter & operator=(MemCounter const &);
45*58b9f456SAndroid Build Coastguard Worker
46*58b9f456SAndroid Build Coastguard Worker public:
47*58b9f456SAndroid Build Coastguard Worker // All checks return true when disable_checking is enabled.
48*58b9f456SAndroid Build Coastguard Worker static const bool disable_checking;
49*58b9f456SAndroid Build Coastguard Worker
50*58b9f456SAndroid Build Coastguard Worker // Disallow any allocations from occurring. Useful for testing that
51*58b9f456SAndroid Build Coastguard Worker // code doesn't perform any allocations.
52*58b9f456SAndroid Build Coastguard Worker bool disable_allocations;
53*58b9f456SAndroid Build Coastguard Worker
54*58b9f456SAndroid Build Coastguard Worker // number of allocations to throw after. Default (unsigned)-1. If
55*58b9f456SAndroid Build Coastguard Worker // throw_after has the default value it will never be decremented.
56*58b9f456SAndroid Build Coastguard Worker static const unsigned never_throw_value = static_cast<unsigned>(-1);
57*58b9f456SAndroid Build Coastguard Worker unsigned throw_after;
58*58b9f456SAndroid Build Coastguard Worker
59*58b9f456SAndroid Build Coastguard Worker int outstanding_new;
60*58b9f456SAndroid Build Coastguard Worker int new_called;
61*58b9f456SAndroid Build Coastguard Worker int delete_called;
62*58b9f456SAndroid Build Coastguard Worker int aligned_new_called;
63*58b9f456SAndroid Build Coastguard Worker int aligned_delete_called;
64*58b9f456SAndroid Build Coastguard Worker std::size_t last_new_size;
65*58b9f456SAndroid Build Coastguard Worker std::size_t last_new_align;
66*58b9f456SAndroid Build Coastguard Worker std::size_t last_delete_align;
67*58b9f456SAndroid Build Coastguard Worker
68*58b9f456SAndroid Build Coastguard Worker int outstanding_array_new;
69*58b9f456SAndroid Build Coastguard Worker int new_array_called;
70*58b9f456SAndroid Build Coastguard Worker int delete_array_called;
71*58b9f456SAndroid Build Coastguard Worker int aligned_new_array_called;
72*58b9f456SAndroid Build Coastguard Worker int aligned_delete_array_called;
73*58b9f456SAndroid Build Coastguard Worker std::size_t last_new_array_size;
74*58b9f456SAndroid Build Coastguard Worker std::size_t last_new_array_align;
75*58b9f456SAndroid Build Coastguard Worker std::size_t last_delete_array_align;
76*58b9f456SAndroid Build Coastguard Worker
77*58b9f456SAndroid Build Coastguard Worker public:
newCalled(std::size_t s)78*58b9f456SAndroid Build Coastguard Worker void newCalled(std::size_t s)
79*58b9f456SAndroid Build Coastguard Worker {
80*58b9f456SAndroid Build Coastguard Worker assert(disable_allocations == false);
81*58b9f456SAndroid Build Coastguard Worker assert(s);
82*58b9f456SAndroid Build Coastguard Worker if (throw_after == 0) {
83*58b9f456SAndroid Build Coastguard Worker throw_after = never_throw_value;
84*58b9f456SAndroid Build Coastguard Worker detail::throw_bad_alloc_helper();
85*58b9f456SAndroid Build Coastguard Worker } else if (throw_after != never_throw_value) {
86*58b9f456SAndroid Build Coastguard Worker --throw_after;
87*58b9f456SAndroid Build Coastguard Worker }
88*58b9f456SAndroid Build Coastguard Worker ++new_called;
89*58b9f456SAndroid Build Coastguard Worker ++outstanding_new;
90*58b9f456SAndroid Build Coastguard Worker last_new_size = s;
91*58b9f456SAndroid Build Coastguard Worker }
92*58b9f456SAndroid Build Coastguard Worker
alignedNewCalled(std::size_t s,std::size_t a)93*58b9f456SAndroid Build Coastguard Worker void alignedNewCalled(std::size_t s, std::size_t a) {
94*58b9f456SAndroid Build Coastguard Worker newCalled(s);
95*58b9f456SAndroid Build Coastguard Worker ++aligned_new_called;
96*58b9f456SAndroid Build Coastguard Worker last_new_align = a;
97*58b9f456SAndroid Build Coastguard Worker }
98*58b9f456SAndroid Build Coastguard Worker
deleteCalled(void * p)99*58b9f456SAndroid Build Coastguard Worker void deleteCalled(void * p)
100*58b9f456SAndroid Build Coastguard Worker {
101*58b9f456SAndroid Build Coastguard Worker assert(p);
102*58b9f456SAndroid Build Coastguard Worker --outstanding_new;
103*58b9f456SAndroid Build Coastguard Worker ++delete_called;
104*58b9f456SAndroid Build Coastguard Worker }
105*58b9f456SAndroid Build Coastguard Worker
alignedDeleteCalled(void * p,std::size_t a)106*58b9f456SAndroid Build Coastguard Worker void alignedDeleteCalled(void *p, std::size_t a) {
107*58b9f456SAndroid Build Coastguard Worker deleteCalled(p);
108*58b9f456SAndroid Build Coastguard Worker ++aligned_delete_called;
109*58b9f456SAndroid Build Coastguard Worker last_delete_align = a;
110*58b9f456SAndroid Build Coastguard Worker }
111*58b9f456SAndroid Build Coastguard Worker
newArrayCalled(std::size_t s)112*58b9f456SAndroid Build Coastguard Worker void newArrayCalled(std::size_t s)
113*58b9f456SAndroid Build Coastguard Worker {
114*58b9f456SAndroid Build Coastguard Worker assert(disable_allocations == false);
115*58b9f456SAndroid Build Coastguard Worker assert(s);
116*58b9f456SAndroid Build Coastguard Worker if (throw_after == 0) {
117*58b9f456SAndroid Build Coastguard Worker throw_after = never_throw_value;
118*58b9f456SAndroid Build Coastguard Worker detail::throw_bad_alloc_helper();
119*58b9f456SAndroid Build Coastguard Worker } else {
120*58b9f456SAndroid Build Coastguard Worker // don't decrement throw_after here. newCalled will end up doing that.
121*58b9f456SAndroid Build Coastguard Worker }
122*58b9f456SAndroid Build Coastguard Worker ++outstanding_array_new;
123*58b9f456SAndroid Build Coastguard Worker ++new_array_called;
124*58b9f456SAndroid Build Coastguard Worker last_new_array_size = s;
125*58b9f456SAndroid Build Coastguard Worker }
126*58b9f456SAndroid Build Coastguard Worker
alignedNewArrayCalled(std::size_t s,std::size_t a)127*58b9f456SAndroid Build Coastguard Worker void alignedNewArrayCalled(std::size_t s, std::size_t a) {
128*58b9f456SAndroid Build Coastguard Worker newArrayCalled(s);
129*58b9f456SAndroid Build Coastguard Worker ++aligned_new_array_called;
130*58b9f456SAndroid Build Coastguard Worker last_new_array_align = a;
131*58b9f456SAndroid Build Coastguard Worker }
132*58b9f456SAndroid Build Coastguard Worker
deleteArrayCalled(void * p)133*58b9f456SAndroid Build Coastguard Worker void deleteArrayCalled(void * p)
134*58b9f456SAndroid Build Coastguard Worker {
135*58b9f456SAndroid Build Coastguard Worker assert(p);
136*58b9f456SAndroid Build Coastguard Worker --outstanding_array_new;
137*58b9f456SAndroid Build Coastguard Worker ++delete_array_called;
138*58b9f456SAndroid Build Coastguard Worker }
139*58b9f456SAndroid Build Coastguard Worker
alignedDeleteArrayCalled(void * p,std::size_t a)140*58b9f456SAndroid Build Coastguard Worker void alignedDeleteArrayCalled(void * p, std::size_t a) {
141*58b9f456SAndroid Build Coastguard Worker deleteArrayCalled(p);
142*58b9f456SAndroid Build Coastguard Worker ++aligned_delete_array_called;
143*58b9f456SAndroid Build Coastguard Worker last_delete_array_align = a;
144*58b9f456SAndroid Build Coastguard Worker }
145*58b9f456SAndroid Build Coastguard Worker
disableAllocations()146*58b9f456SAndroid Build Coastguard Worker void disableAllocations()
147*58b9f456SAndroid Build Coastguard Worker {
148*58b9f456SAndroid Build Coastguard Worker disable_allocations = true;
149*58b9f456SAndroid Build Coastguard Worker }
150*58b9f456SAndroid Build Coastguard Worker
enableAllocations()151*58b9f456SAndroid Build Coastguard Worker void enableAllocations()
152*58b9f456SAndroid Build Coastguard Worker {
153*58b9f456SAndroid Build Coastguard Worker disable_allocations = false;
154*58b9f456SAndroid Build Coastguard Worker }
155*58b9f456SAndroid Build Coastguard Worker
reset()156*58b9f456SAndroid Build Coastguard Worker void reset()
157*58b9f456SAndroid Build Coastguard Worker {
158*58b9f456SAndroid Build Coastguard Worker disable_allocations = false;
159*58b9f456SAndroid Build Coastguard Worker throw_after = never_throw_value;
160*58b9f456SAndroid Build Coastguard Worker
161*58b9f456SAndroid Build Coastguard Worker outstanding_new = 0;
162*58b9f456SAndroid Build Coastguard Worker new_called = 0;
163*58b9f456SAndroid Build Coastguard Worker delete_called = 0;
164*58b9f456SAndroid Build Coastguard Worker aligned_new_called = 0;
165*58b9f456SAndroid Build Coastguard Worker aligned_delete_called = 0;
166*58b9f456SAndroid Build Coastguard Worker last_new_size = 0;
167*58b9f456SAndroid Build Coastguard Worker last_new_align = 0;
168*58b9f456SAndroid Build Coastguard Worker
169*58b9f456SAndroid Build Coastguard Worker outstanding_array_new = 0;
170*58b9f456SAndroid Build Coastguard Worker new_array_called = 0;
171*58b9f456SAndroid Build Coastguard Worker delete_array_called = 0;
172*58b9f456SAndroid Build Coastguard Worker aligned_new_array_called = 0;
173*58b9f456SAndroid Build Coastguard Worker aligned_delete_array_called = 0;
174*58b9f456SAndroid Build Coastguard Worker last_new_array_size = 0;
175*58b9f456SAndroid Build Coastguard Worker last_new_array_align = 0;
176*58b9f456SAndroid Build Coastguard Worker }
177*58b9f456SAndroid Build Coastguard Worker
178*58b9f456SAndroid Build Coastguard Worker public:
checkOutstandingNewEq(int n) const179*58b9f456SAndroid Build Coastguard Worker bool checkOutstandingNewEq(int n) const
180*58b9f456SAndroid Build Coastguard Worker {
181*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == outstanding_new;
182*58b9f456SAndroid Build Coastguard Worker }
183*58b9f456SAndroid Build Coastguard Worker
checkOutstandingNewNotEq(int n) const184*58b9f456SAndroid Build Coastguard Worker bool checkOutstandingNewNotEq(int n) const
185*58b9f456SAndroid Build Coastguard Worker {
186*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != outstanding_new;
187*58b9f456SAndroid Build Coastguard Worker }
188*58b9f456SAndroid Build Coastguard Worker
checkNewCalledEq(int n) const189*58b9f456SAndroid Build Coastguard Worker bool checkNewCalledEq(int n) const
190*58b9f456SAndroid Build Coastguard Worker {
191*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == new_called;
192*58b9f456SAndroid Build Coastguard Worker }
193*58b9f456SAndroid Build Coastguard Worker
checkNewCalledNotEq(int n) const194*58b9f456SAndroid Build Coastguard Worker bool checkNewCalledNotEq(int n) const
195*58b9f456SAndroid Build Coastguard Worker {
196*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != new_called;
197*58b9f456SAndroid Build Coastguard Worker }
198*58b9f456SAndroid Build Coastguard Worker
checkNewCalledGreaterThan(int n) const199*58b9f456SAndroid Build Coastguard Worker bool checkNewCalledGreaterThan(int n) const
200*58b9f456SAndroid Build Coastguard Worker {
201*58b9f456SAndroid Build Coastguard Worker return disable_checking || new_called > n;
202*58b9f456SAndroid Build Coastguard Worker }
203*58b9f456SAndroid Build Coastguard Worker
checkDeleteCalledEq(int n) const204*58b9f456SAndroid Build Coastguard Worker bool checkDeleteCalledEq(int n) const
205*58b9f456SAndroid Build Coastguard Worker {
206*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == delete_called;
207*58b9f456SAndroid Build Coastguard Worker }
208*58b9f456SAndroid Build Coastguard Worker
checkDeleteCalledNotEq(int n) const209*58b9f456SAndroid Build Coastguard Worker bool checkDeleteCalledNotEq(int n) const
210*58b9f456SAndroid Build Coastguard Worker {
211*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != delete_called;
212*58b9f456SAndroid Build Coastguard Worker }
213*58b9f456SAndroid Build Coastguard Worker
checkAlignedNewCalledEq(int n) const214*58b9f456SAndroid Build Coastguard Worker bool checkAlignedNewCalledEq(int n) const
215*58b9f456SAndroid Build Coastguard Worker {
216*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == aligned_new_called;
217*58b9f456SAndroid Build Coastguard Worker }
218*58b9f456SAndroid Build Coastguard Worker
checkAlignedNewCalledNotEq(int n) const219*58b9f456SAndroid Build Coastguard Worker bool checkAlignedNewCalledNotEq(int n) const
220*58b9f456SAndroid Build Coastguard Worker {
221*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != aligned_new_called;
222*58b9f456SAndroid Build Coastguard Worker }
223*58b9f456SAndroid Build Coastguard Worker
checkAlignedNewCalledGreaterThan(int n) const224*58b9f456SAndroid Build Coastguard Worker bool checkAlignedNewCalledGreaterThan(int n) const
225*58b9f456SAndroid Build Coastguard Worker {
226*58b9f456SAndroid Build Coastguard Worker return disable_checking || aligned_new_called > n;
227*58b9f456SAndroid Build Coastguard Worker }
228*58b9f456SAndroid Build Coastguard Worker
checkAlignedDeleteCalledEq(int n) const229*58b9f456SAndroid Build Coastguard Worker bool checkAlignedDeleteCalledEq(int n) const
230*58b9f456SAndroid Build Coastguard Worker {
231*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == aligned_delete_called;
232*58b9f456SAndroid Build Coastguard Worker }
233*58b9f456SAndroid Build Coastguard Worker
checkAlignedDeleteCalledNotEq(int n) const234*58b9f456SAndroid Build Coastguard Worker bool checkAlignedDeleteCalledNotEq(int n) const
235*58b9f456SAndroid Build Coastguard Worker {
236*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != aligned_delete_called;
237*58b9f456SAndroid Build Coastguard Worker }
238*58b9f456SAndroid Build Coastguard Worker
checkLastNewSizeEq(std::size_t n) const239*58b9f456SAndroid Build Coastguard Worker bool checkLastNewSizeEq(std::size_t n) const
240*58b9f456SAndroid Build Coastguard Worker {
241*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == last_new_size;
242*58b9f456SAndroid Build Coastguard Worker }
243*58b9f456SAndroid Build Coastguard Worker
checkLastNewSizeNotEq(std::size_t n) const244*58b9f456SAndroid Build Coastguard Worker bool checkLastNewSizeNotEq(std::size_t n) const
245*58b9f456SAndroid Build Coastguard Worker {
246*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != last_new_size;
247*58b9f456SAndroid Build Coastguard Worker }
248*58b9f456SAndroid Build Coastguard Worker
checkLastNewAlignEq(std::size_t n) const249*58b9f456SAndroid Build Coastguard Worker bool checkLastNewAlignEq(std::size_t n) const
250*58b9f456SAndroid Build Coastguard Worker {
251*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == last_new_align;
252*58b9f456SAndroid Build Coastguard Worker }
253*58b9f456SAndroid Build Coastguard Worker
checkLastNewAlignNotEq(std::size_t n) const254*58b9f456SAndroid Build Coastguard Worker bool checkLastNewAlignNotEq(std::size_t n) const
255*58b9f456SAndroid Build Coastguard Worker {
256*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != last_new_align;
257*58b9f456SAndroid Build Coastguard Worker }
258*58b9f456SAndroid Build Coastguard Worker
checkLastDeleteAlignEq(std::size_t n) const259*58b9f456SAndroid Build Coastguard Worker bool checkLastDeleteAlignEq(std::size_t n) const
260*58b9f456SAndroid Build Coastguard Worker {
261*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == last_delete_align;
262*58b9f456SAndroid Build Coastguard Worker }
263*58b9f456SAndroid Build Coastguard Worker
checkLastDeleteAlignNotEq(std::size_t n) const264*58b9f456SAndroid Build Coastguard Worker bool checkLastDeleteAlignNotEq(std::size_t n) const
265*58b9f456SAndroid Build Coastguard Worker {
266*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != last_delete_align;
267*58b9f456SAndroid Build Coastguard Worker }
268*58b9f456SAndroid Build Coastguard Worker
checkOutstandingArrayNewEq(int n) const269*58b9f456SAndroid Build Coastguard Worker bool checkOutstandingArrayNewEq(int n) const
270*58b9f456SAndroid Build Coastguard Worker {
271*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == outstanding_array_new;
272*58b9f456SAndroid Build Coastguard Worker }
273*58b9f456SAndroid Build Coastguard Worker
checkOutstandingArrayNewNotEq(int n) const274*58b9f456SAndroid Build Coastguard Worker bool checkOutstandingArrayNewNotEq(int n) const
275*58b9f456SAndroid Build Coastguard Worker {
276*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != outstanding_array_new;
277*58b9f456SAndroid Build Coastguard Worker }
278*58b9f456SAndroid Build Coastguard Worker
checkNewArrayCalledEq(int n) const279*58b9f456SAndroid Build Coastguard Worker bool checkNewArrayCalledEq(int n) const
280*58b9f456SAndroid Build Coastguard Worker {
281*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == new_array_called;
282*58b9f456SAndroid Build Coastguard Worker }
283*58b9f456SAndroid Build Coastguard Worker
checkNewArrayCalledNotEq(int n) const284*58b9f456SAndroid Build Coastguard Worker bool checkNewArrayCalledNotEq(int n) const
285*58b9f456SAndroid Build Coastguard Worker {
286*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != new_array_called;
287*58b9f456SAndroid Build Coastguard Worker }
288*58b9f456SAndroid Build Coastguard Worker
checkDeleteArrayCalledEq(int n) const289*58b9f456SAndroid Build Coastguard Worker bool checkDeleteArrayCalledEq(int n) const
290*58b9f456SAndroid Build Coastguard Worker {
291*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == delete_array_called;
292*58b9f456SAndroid Build Coastguard Worker }
293*58b9f456SAndroid Build Coastguard Worker
checkDeleteArrayCalledNotEq(int n) const294*58b9f456SAndroid Build Coastguard Worker bool checkDeleteArrayCalledNotEq(int n) const
295*58b9f456SAndroid Build Coastguard Worker {
296*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != delete_array_called;
297*58b9f456SAndroid Build Coastguard Worker }
298*58b9f456SAndroid Build Coastguard Worker
checkAlignedNewArrayCalledEq(int n) const299*58b9f456SAndroid Build Coastguard Worker bool checkAlignedNewArrayCalledEq(int n) const
300*58b9f456SAndroid Build Coastguard Worker {
301*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == aligned_new_array_called;
302*58b9f456SAndroid Build Coastguard Worker }
303*58b9f456SAndroid Build Coastguard Worker
checkAlignedNewArrayCalledNotEq(int n) const304*58b9f456SAndroid Build Coastguard Worker bool checkAlignedNewArrayCalledNotEq(int n) const
305*58b9f456SAndroid Build Coastguard Worker {
306*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != aligned_new_array_called;
307*58b9f456SAndroid Build Coastguard Worker }
308*58b9f456SAndroid Build Coastguard Worker
checkAlignedNewArrayCalledGreaterThan(int n) const309*58b9f456SAndroid Build Coastguard Worker bool checkAlignedNewArrayCalledGreaterThan(int n) const
310*58b9f456SAndroid Build Coastguard Worker {
311*58b9f456SAndroid Build Coastguard Worker return disable_checking || aligned_new_array_called > n;
312*58b9f456SAndroid Build Coastguard Worker }
313*58b9f456SAndroid Build Coastguard Worker
checkAlignedDeleteArrayCalledEq(int n) const314*58b9f456SAndroid Build Coastguard Worker bool checkAlignedDeleteArrayCalledEq(int n) const
315*58b9f456SAndroid Build Coastguard Worker {
316*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == aligned_delete_array_called;
317*58b9f456SAndroid Build Coastguard Worker }
318*58b9f456SAndroid Build Coastguard Worker
checkAlignedDeleteArrayCalledNotEq(int n) const319*58b9f456SAndroid Build Coastguard Worker bool checkAlignedDeleteArrayCalledNotEq(int n) const
320*58b9f456SAndroid Build Coastguard Worker {
321*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != aligned_delete_array_called;
322*58b9f456SAndroid Build Coastguard Worker }
323*58b9f456SAndroid Build Coastguard Worker
checkLastNewArraySizeEq(std::size_t n) const324*58b9f456SAndroid Build Coastguard Worker bool checkLastNewArraySizeEq(std::size_t n) const
325*58b9f456SAndroid Build Coastguard Worker {
326*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == last_new_array_size;
327*58b9f456SAndroid Build Coastguard Worker }
328*58b9f456SAndroid Build Coastguard Worker
checkLastNewArraySizeNotEq(std::size_t n) const329*58b9f456SAndroid Build Coastguard Worker bool checkLastNewArraySizeNotEq(std::size_t n) const
330*58b9f456SAndroid Build Coastguard Worker {
331*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != last_new_array_size;
332*58b9f456SAndroid Build Coastguard Worker }
333*58b9f456SAndroid Build Coastguard Worker
checkLastNewArrayAlignEq(std::size_t n) const334*58b9f456SAndroid Build Coastguard Worker bool checkLastNewArrayAlignEq(std::size_t n) const
335*58b9f456SAndroid Build Coastguard Worker {
336*58b9f456SAndroid Build Coastguard Worker return disable_checking || n == last_new_array_align;
337*58b9f456SAndroid Build Coastguard Worker }
338*58b9f456SAndroid Build Coastguard Worker
checkLastNewArrayAlignNotEq(std::size_t n) const339*58b9f456SAndroid Build Coastguard Worker bool checkLastNewArrayAlignNotEq(std::size_t n) const
340*58b9f456SAndroid Build Coastguard Worker {
341*58b9f456SAndroid Build Coastguard Worker return disable_checking || n != last_new_array_align;
342*58b9f456SAndroid Build Coastguard Worker }
343*58b9f456SAndroid Build Coastguard Worker };
344*58b9f456SAndroid Build Coastguard Worker
345*58b9f456SAndroid Build Coastguard Worker #ifdef DISABLE_NEW_COUNT
346*58b9f456SAndroid Build Coastguard Worker const bool MemCounter::disable_checking = true;
347*58b9f456SAndroid Build Coastguard Worker #else
348*58b9f456SAndroid Build Coastguard Worker const bool MemCounter::disable_checking = false;
349*58b9f456SAndroid Build Coastguard Worker #endif
350*58b9f456SAndroid Build Coastguard Worker
getGlobalMemCounter()351*58b9f456SAndroid Build Coastguard Worker inline MemCounter* getGlobalMemCounter() {
352*58b9f456SAndroid Build Coastguard Worker static MemCounter counter((MemCounter::MemCounterCtorArg_()));
353*58b9f456SAndroid Build Coastguard Worker return &counter;
354*58b9f456SAndroid Build Coastguard Worker }
355*58b9f456SAndroid Build Coastguard Worker
356*58b9f456SAndroid Build Coastguard Worker MemCounter &globalMemCounter = *getGlobalMemCounter();
357*58b9f456SAndroid Build Coastguard Worker
358*58b9f456SAndroid Build Coastguard Worker #ifndef DISABLE_NEW_COUNT
operator new(std::size_t s)359*58b9f456SAndroid Build Coastguard Worker void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
360*58b9f456SAndroid Build Coastguard Worker {
361*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->newCalled(s);
362*58b9f456SAndroid Build Coastguard Worker void* ret = std::malloc(s);
363*58b9f456SAndroid Build Coastguard Worker if (ret == nullptr)
364*58b9f456SAndroid Build Coastguard Worker detail::throw_bad_alloc_helper();
365*58b9f456SAndroid Build Coastguard Worker return ret;
366*58b9f456SAndroid Build Coastguard Worker }
367*58b9f456SAndroid Build Coastguard Worker
operator delete(void * p)368*58b9f456SAndroid Build Coastguard Worker void operator delete(void* p) TEST_NOEXCEPT
369*58b9f456SAndroid Build Coastguard Worker {
370*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->deleteCalled(p);
371*58b9f456SAndroid Build Coastguard Worker std::free(p);
372*58b9f456SAndroid Build Coastguard Worker }
373*58b9f456SAndroid Build Coastguard Worker
operator new[](std::size_t s)374*58b9f456SAndroid Build Coastguard Worker void* operator new[](std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
375*58b9f456SAndroid Build Coastguard Worker {
376*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->newArrayCalled(s);
377*58b9f456SAndroid Build Coastguard Worker return operator new(s);
378*58b9f456SAndroid Build Coastguard Worker }
379*58b9f456SAndroid Build Coastguard Worker
operator delete[](void * p)380*58b9f456SAndroid Build Coastguard Worker void operator delete[](void* p) TEST_NOEXCEPT
381*58b9f456SAndroid Build Coastguard Worker {
382*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->deleteArrayCalled(p);
383*58b9f456SAndroid Build Coastguard Worker operator delete(p);
384*58b9f456SAndroid Build Coastguard Worker }
385*58b9f456SAndroid Build Coastguard Worker
386*58b9f456SAndroid Build Coastguard Worker #ifndef TEST_HAS_NO_ALIGNED_ALLOCATION
387*58b9f456SAndroid Build Coastguard Worker #if defined(_LIBCPP_MSVCRT_LIKE) || \
388*58b9f456SAndroid Build Coastguard Worker (!defined(_LIBCPP_VERSION) && defined(_WIN32))
389*58b9f456SAndroid Build Coastguard Worker #define USE_ALIGNED_ALLOC
390*58b9f456SAndroid Build Coastguard Worker #endif
391*58b9f456SAndroid Build Coastguard Worker
operator new(std::size_t s,std::align_val_t av)392*58b9f456SAndroid Build Coastguard Worker void* operator new(std::size_t s, std::align_val_t av) TEST_THROW_SPEC(std::bad_alloc) {
393*58b9f456SAndroid Build Coastguard Worker const std::size_t a = static_cast<std::size_t>(av);
394*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->alignedNewCalled(s, a);
395*58b9f456SAndroid Build Coastguard Worker void *ret;
396*58b9f456SAndroid Build Coastguard Worker #ifdef USE_ALIGNED_ALLOC
397*58b9f456SAndroid Build Coastguard Worker ret = _aligned_malloc(s, a);
398*58b9f456SAndroid Build Coastguard Worker #else
399*58b9f456SAndroid Build Coastguard Worker posix_memalign(&ret, a, s);
400*58b9f456SAndroid Build Coastguard Worker #endif
401*58b9f456SAndroid Build Coastguard Worker if (ret == nullptr)
402*58b9f456SAndroid Build Coastguard Worker detail::throw_bad_alloc_helper();
403*58b9f456SAndroid Build Coastguard Worker return ret;
404*58b9f456SAndroid Build Coastguard Worker }
405*58b9f456SAndroid Build Coastguard Worker
operator delete(void * p,std::align_val_t av)406*58b9f456SAndroid Build Coastguard Worker void operator delete(void *p, std::align_val_t av) TEST_NOEXCEPT {
407*58b9f456SAndroid Build Coastguard Worker const std::size_t a = static_cast<std::size_t>(av);
408*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->alignedDeleteCalled(p, a);
409*58b9f456SAndroid Build Coastguard Worker if (p) {
410*58b9f456SAndroid Build Coastguard Worker #ifdef USE_ALIGNED_ALLOC
411*58b9f456SAndroid Build Coastguard Worker ::_aligned_free(p);
412*58b9f456SAndroid Build Coastguard Worker #else
413*58b9f456SAndroid Build Coastguard Worker ::free(p);
414*58b9f456SAndroid Build Coastguard Worker #endif
415*58b9f456SAndroid Build Coastguard Worker }
416*58b9f456SAndroid Build Coastguard Worker }
417*58b9f456SAndroid Build Coastguard Worker
operator new[](std::size_t s,std::align_val_t av)418*58b9f456SAndroid Build Coastguard Worker void* operator new[](std::size_t s, std::align_val_t av) TEST_THROW_SPEC(std::bad_alloc) {
419*58b9f456SAndroid Build Coastguard Worker const std::size_t a = static_cast<std::size_t>(av);
420*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->alignedNewArrayCalled(s, a);
421*58b9f456SAndroid Build Coastguard Worker return operator new(s, av);
422*58b9f456SAndroid Build Coastguard Worker }
423*58b9f456SAndroid Build Coastguard Worker
operator delete[](void * p,std::align_val_t av)424*58b9f456SAndroid Build Coastguard Worker void operator delete[](void *p, std::align_val_t av) TEST_NOEXCEPT {
425*58b9f456SAndroid Build Coastguard Worker const std::size_t a = static_cast<std::size_t>(av);
426*58b9f456SAndroid Build Coastguard Worker getGlobalMemCounter()->alignedDeleteArrayCalled(p, a);
427*58b9f456SAndroid Build Coastguard Worker return operator delete(p, av);
428*58b9f456SAndroid Build Coastguard Worker }
429*58b9f456SAndroid Build Coastguard Worker
430*58b9f456SAndroid Build Coastguard Worker #endif // TEST_HAS_NO_ALIGNED_ALLOCATION
431*58b9f456SAndroid Build Coastguard Worker
432*58b9f456SAndroid Build Coastguard Worker #endif // DISABLE_NEW_COUNT
433*58b9f456SAndroid Build Coastguard Worker
434*58b9f456SAndroid Build Coastguard Worker struct DisableAllocationGuard {
DisableAllocationGuardDisableAllocationGuard435*58b9f456SAndroid Build Coastguard Worker explicit DisableAllocationGuard(bool disable = true) : m_disabled(disable)
436*58b9f456SAndroid Build Coastguard Worker {
437*58b9f456SAndroid Build Coastguard Worker // Don't re-disable if already disabled.
438*58b9f456SAndroid Build Coastguard Worker if (globalMemCounter.disable_allocations == true) m_disabled = false;
439*58b9f456SAndroid Build Coastguard Worker if (m_disabled) globalMemCounter.disableAllocations();
440*58b9f456SAndroid Build Coastguard Worker }
441*58b9f456SAndroid Build Coastguard Worker
releaseDisableAllocationGuard442*58b9f456SAndroid Build Coastguard Worker void release() {
443*58b9f456SAndroid Build Coastguard Worker if (m_disabled) globalMemCounter.enableAllocations();
444*58b9f456SAndroid Build Coastguard Worker m_disabled = false;
445*58b9f456SAndroid Build Coastguard Worker }
446*58b9f456SAndroid Build Coastguard Worker
~DisableAllocationGuardDisableAllocationGuard447*58b9f456SAndroid Build Coastguard Worker ~DisableAllocationGuard() {
448*58b9f456SAndroid Build Coastguard Worker release();
449*58b9f456SAndroid Build Coastguard Worker }
450*58b9f456SAndroid Build Coastguard Worker
451*58b9f456SAndroid Build Coastguard Worker private:
452*58b9f456SAndroid Build Coastguard Worker bool m_disabled;
453*58b9f456SAndroid Build Coastguard Worker
454*58b9f456SAndroid Build Coastguard Worker DisableAllocationGuard(DisableAllocationGuard const&);
455*58b9f456SAndroid Build Coastguard Worker DisableAllocationGuard& operator=(DisableAllocationGuard const&);
456*58b9f456SAndroid Build Coastguard Worker };
457*58b9f456SAndroid Build Coastguard Worker
458*58b9f456SAndroid Build Coastguard Worker struct RequireAllocationGuard {
RequireAllocationGuardRequireAllocationGuard459*58b9f456SAndroid Build Coastguard Worker explicit RequireAllocationGuard(std::size_t RequireAtLeast = 1)
460*58b9f456SAndroid Build Coastguard Worker : m_req_alloc(RequireAtLeast),
461*58b9f456SAndroid Build Coastguard Worker m_new_count_on_init(globalMemCounter.new_called),
462*58b9f456SAndroid Build Coastguard Worker m_outstanding_new_on_init(globalMemCounter.outstanding_new),
463*58b9f456SAndroid Build Coastguard Worker m_exactly(false)
464*58b9f456SAndroid Build Coastguard Worker {
465*58b9f456SAndroid Build Coastguard Worker }
466*58b9f456SAndroid Build Coastguard Worker
requireAtLeastRequireAllocationGuard467*58b9f456SAndroid Build Coastguard Worker void requireAtLeast(std::size_t N) { m_req_alloc = N; m_exactly = false; }
requireExactlyRequireAllocationGuard468*58b9f456SAndroid Build Coastguard Worker void requireExactly(std::size_t N) { m_req_alloc = N; m_exactly = true; }
469*58b9f456SAndroid Build Coastguard Worker
~RequireAllocationGuardRequireAllocationGuard470*58b9f456SAndroid Build Coastguard Worker ~RequireAllocationGuard() {
471*58b9f456SAndroid Build Coastguard Worker assert(globalMemCounter.checkOutstandingNewEq(static_cast<int>(m_outstanding_new_on_init)));
472*58b9f456SAndroid Build Coastguard Worker std::size_t Expect = m_new_count_on_init + m_req_alloc;
473*58b9f456SAndroid Build Coastguard Worker assert(globalMemCounter.checkNewCalledEq(static_cast<int>(Expect)) ||
474*58b9f456SAndroid Build Coastguard Worker (!m_exactly && globalMemCounter.checkNewCalledGreaterThan(static_cast<int>(Expect))));
475*58b9f456SAndroid Build Coastguard Worker }
476*58b9f456SAndroid Build Coastguard Worker
477*58b9f456SAndroid Build Coastguard Worker private:
478*58b9f456SAndroid Build Coastguard Worker std::size_t m_req_alloc;
479*58b9f456SAndroid Build Coastguard Worker const std::size_t m_new_count_on_init;
480*58b9f456SAndroid Build Coastguard Worker const std::size_t m_outstanding_new_on_init;
481*58b9f456SAndroid Build Coastguard Worker bool m_exactly;
482*58b9f456SAndroid Build Coastguard Worker RequireAllocationGuard(RequireAllocationGuard const&);
483*58b9f456SAndroid Build Coastguard Worker RequireAllocationGuard& operator=(RequireAllocationGuard const&);
484*58b9f456SAndroid Build Coastguard Worker };
485*58b9f456SAndroid Build Coastguard Worker
486*58b9f456SAndroid Build Coastguard Worker #endif /* COUNT_NEW_HPP */
487