xref: /freebsd/contrib/llvm-project/libcxx/src/new.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===--------------------------- new.cpp ----------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include <stdlib.h>
10*0b57cec5SDimitry Andric 
11*0b57cec5SDimitry Andric #include "new"
12*0b57cec5SDimitry Andric #include "include/atomic_support.h"
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #if defined(_LIBCPP_ABI_MICROSOFT)
15*0b57cec5SDimitry Andric #   if !defined(_LIBCPP_ABI_VCRUNTIME)
16*0b57cec5SDimitry Andric #       include "support/runtime/new_handler_fallback.ipp"
17*0b57cec5SDimitry Andric #   endif
18*0b57cec5SDimitry Andric #elif defined(LIBCXX_BUILDING_LIBCXXABI)
19*0b57cec5SDimitry Andric #   include <cxxabi.h>
20*0b57cec5SDimitry Andric #elif defined(LIBCXXRT)
21*0b57cec5SDimitry Andric #   include <cxxabi.h>
22*0b57cec5SDimitry Andric #   include "support/runtime/new_handler_fallback.ipp"
23*0b57cec5SDimitry Andric #elif defined(__GLIBCXX__)
24*0b57cec5SDimitry Andric     // nothing to do
25*0b57cec5SDimitry Andric #else
26*0b57cec5SDimitry Andric #   include "support/runtime/new_handler_fallback.ipp"
27*0b57cec5SDimitry Andric #endif
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric namespace std
30*0b57cec5SDimitry Andric {
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric #ifndef __GLIBCXX__
33*0b57cec5SDimitry Andric const nothrow_t nothrow{};
34*0b57cec5SDimitry Andric #endif
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric #ifndef LIBSTDCXX
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric void
39*0b57cec5SDimitry Andric __throw_bad_alloc()
40*0b57cec5SDimitry Andric {
41*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
42*0b57cec5SDimitry Andric     throw bad_alloc();
43*0b57cec5SDimitry Andric #else
44*0b57cec5SDimitry Andric     _VSTD::abort();
45*0b57cec5SDimitry Andric #endif
46*0b57cec5SDimitry Andric }
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric #endif // !LIBSTDCXX
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric }  // std
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric #if !defined(__GLIBCXX__) &&                                                   \
53*0b57cec5SDimitry Andric     !defined(_LIBCPP_ABI_VCRUNTIME) &&      \
54*0b57cec5SDimitry Andric     !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
55*0b57cec5SDimitry Andric 
56*0b57cec5SDimitry Andric // Implement all new and delete operators as weak definitions
57*0b57cec5SDimitry Andric // in this shared library, so that they can be overridden by programs
58*0b57cec5SDimitry Andric // that define non-weak copies of the functions.
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric _LIBCPP_WEAK
61*0b57cec5SDimitry Andric void *
62*0b57cec5SDimitry Andric operator new(std::size_t size) _THROW_BAD_ALLOC
63*0b57cec5SDimitry Andric {
64*0b57cec5SDimitry Andric     if (size == 0)
65*0b57cec5SDimitry Andric         size = 1;
66*0b57cec5SDimitry Andric     void* p;
67*0b57cec5SDimitry Andric     while ((p = ::malloc(size)) == 0)
68*0b57cec5SDimitry Andric     {
69*0b57cec5SDimitry Andric         // If malloc fails and there is a new_handler,
70*0b57cec5SDimitry Andric         // call it to try free up memory.
71*0b57cec5SDimitry Andric         std::new_handler nh = std::get_new_handler();
72*0b57cec5SDimitry Andric         if (nh)
73*0b57cec5SDimitry Andric             nh();
74*0b57cec5SDimitry Andric         else
75*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
76*0b57cec5SDimitry Andric             throw std::bad_alloc();
77*0b57cec5SDimitry Andric #else
78*0b57cec5SDimitry Andric             break;
79*0b57cec5SDimitry Andric #endif
80*0b57cec5SDimitry Andric     }
81*0b57cec5SDimitry Andric     return p;
82*0b57cec5SDimitry Andric }
83*0b57cec5SDimitry Andric 
84*0b57cec5SDimitry Andric _LIBCPP_WEAK
85*0b57cec5SDimitry Andric void*
86*0b57cec5SDimitry Andric operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
87*0b57cec5SDimitry Andric {
88*0b57cec5SDimitry Andric     void* p = 0;
89*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
90*0b57cec5SDimitry Andric     try
91*0b57cec5SDimitry Andric     {
92*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
93*0b57cec5SDimitry Andric         p = ::operator new(size);
94*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
95*0b57cec5SDimitry Andric     }
96*0b57cec5SDimitry Andric     catch (...)
97*0b57cec5SDimitry Andric     {
98*0b57cec5SDimitry Andric     }
99*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
100*0b57cec5SDimitry Andric     return p;
101*0b57cec5SDimitry Andric }
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric _LIBCPP_WEAK
104*0b57cec5SDimitry Andric void*
105*0b57cec5SDimitry Andric operator new[](size_t size) _THROW_BAD_ALLOC
106*0b57cec5SDimitry Andric {
107*0b57cec5SDimitry Andric     return ::operator new(size);
108*0b57cec5SDimitry Andric }
109*0b57cec5SDimitry Andric 
110*0b57cec5SDimitry Andric _LIBCPP_WEAK
111*0b57cec5SDimitry Andric void*
112*0b57cec5SDimitry Andric operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
113*0b57cec5SDimitry Andric {
114*0b57cec5SDimitry Andric     void* p = 0;
115*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
116*0b57cec5SDimitry Andric     try
117*0b57cec5SDimitry Andric     {
118*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
119*0b57cec5SDimitry Andric         p = ::operator new[](size);
120*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
121*0b57cec5SDimitry Andric     }
122*0b57cec5SDimitry Andric     catch (...)
123*0b57cec5SDimitry Andric     {
124*0b57cec5SDimitry Andric     }
125*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
126*0b57cec5SDimitry Andric     return p;
127*0b57cec5SDimitry Andric }
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric _LIBCPP_WEAK
130*0b57cec5SDimitry Andric void
131*0b57cec5SDimitry Andric operator delete(void* ptr) _NOEXCEPT
132*0b57cec5SDimitry Andric {
133*0b57cec5SDimitry Andric     ::free(ptr);
134*0b57cec5SDimitry Andric }
135*0b57cec5SDimitry Andric 
136*0b57cec5SDimitry Andric _LIBCPP_WEAK
137*0b57cec5SDimitry Andric void
138*0b57cec5SDimitry Andric operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
139*0b57cec5SDimitry Andric {
140*0b57cec5SDimitry Andric     ::operator delete(ptr);
141*0b57cec5SDimitry Andric }
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric _LIBCPP_WEAK
144*0b57cec5SDimitry Andric void
145*0b57cec5SDimitry Andric operator delete(void* ptr, size_t) _NOEXCEPT
146*0b57cec5SDimitry Andric {
147*0b57cec5SDimitry Andric     ::operator delete(ptr);
148*0b57cec5SDimitry Andric }
149*0b57cec5SDimitry Andric 
150*0b57cec5SDimitry Andric _LIBCPP_WEAK
151*0b57cec5SDimitry Andric void
152*0b57cec5SDimitry Andric operator delete[] (void* ptr) _NOEXCEPT
153*0b57cec5SDimitry Andric {
154*0b57cec5SDimitry Andric     ::operator delete(ptr);
155*0b57cec5SDimitry Andric }
156*0b57cec5SDimitry Andric 
157*0b57cec5SDimitry Andric _LIBCPP_WEAK
158*0b57cec5SDimitry Andric void
159*0b57cec5SDimitry Andric operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
160*0b57cec5SDimitry Andric {
161*0b57cec5SDimitry Andric     ::operator delete[](ptr);
162*0b57cec5SDimitry Andric }
163*0b57cec5SDimitry Andric 
164*0b57cec5SDimitry Andric _LIBCPP_WEAK
165*0b57cec5SDimitry Andric void
166*0b57cec5SDimitry Andric operator delete[] (void* ptr, size_t) _NOEXCEPT
167*0b57cec5SDimitry Andric {
168*0b57cec5SDimitry Andric     ::operator delete[](ptr);
169*0b57cec5SDimitry Andric }
170*0b57cec5SDimitry Andric 
171*0b57cec5SDimitry Andric #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
172*0b57cec5SDimitry Andric 
173*0b57cec5SDimitry Andric _LIBCPP_WEAK
174*0b57cec5SDimitry Andric void *
175*0b57cec5SDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
176*0b57cec5SDimitry Andric {
177*0b57cec5SDimitry Andric     if (size == 0)
178*0b57cec5SDimitry Andric         size = 1;
179*0b57cec5SDimitry Andric     if (static_cast<size_t>(alignment) < sizeof(void*))
180*0b57cec5SDimitry Andric       alignment = std::align_val_t(sizeof(void*));
181*0b57cec5SDimitry Andric     void* p;
182*0b57cec5SDimitry Andric #if defined(_LIBCPP_MSVCRT_LIKE)
183*0b57cec5SDimitry Andric     while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
184*0b57cec5SDimitry Andric #else
185*0b57cec5SDimitry Andric     while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
186*0b57cec5SDimitry Andric #endif
187*0b57cec5SDimitry Andric     {
188*0b57cec5SDimitry Andric         // If posix_memalign fails and there is a new_handler,
189*0b57cec5SDimitry Andric         // call it to try free up memory.
190*0b57cec5SDimitry Andric         std::new_handler nh = std::get_new_handler();
191*0b57cec5SDimitry Andric         if (nh)
192*0b57cec5SDimitry Andric             nh();
193*0b57cec5SDimitry Andric         else {
194*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
195*0b57cec5SDimitry Andric             throw std::bad_alloc();
196*0b57cec5SDimitry Andric #else
197*0b57cec5SDimitry Andric             p = nullptr; // posix_memalign doesn't initialize 'p' on failure
198*0b57cec5SDimitry Andric             break;
199*0b57cec5SDimitry Andric #endif
200*0b57cec5SDimitry Andric         }
201*0b57cec5SDimitry Andric     }
202*0b57cec5SDimitry Andric     return p;
203*0b57cec5SDimitry Andric }
204*0b57cec5SDimitry Andric 
205*0b57cec5SDimitry Andric _LIBCPP_WEAK
206*0b57cec5SDimitry Andric void*
207*0b57cec5SDimitry Andric operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
208*0b57cec5SDimitry Andric {
209*0b57cec5SDimitry Andric     void* p = 0;
210*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
211*0b57cec5SDimitry Andric     try
212*0b57cec5SDimitry Andric     {
213*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
214*0b57cec5SDimitry Andric         p = ::operator new(size, alignment);
215*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
216*0b57cec5SDimitry Andric     }
217*0b57cec5SDimitry Andric     catch (...)
218*0b57cec5SDimitry Andric     {
219*0b57cec5SDimitry Andric     }
220*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
221*0b57cec5SDimitry Andric     return p;
222*0b57cec5SDimitry Andric }
223*0b57cec5SDimitry Andric 
224*0b57cec5SDimitry Andric _LIBCPP_WEAK
225*0b57cec5SDimitry Andric void*
226*0b57cec5SDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
227*0b57cec5SDimitry Andric {
228*0b57cec5SDimitry Andric     return ::operator new(size, alignment);
229*0b57cec5SDimitry Andric }
230*0b57cec5SDimitry Andric 
231*0b57cec5SDimitry Andric _LIBCPP_WEAK
232*0b57cec5SDimitry Andric void*
233*0b57cec5SDimitry Andric operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
234*0b57cec5SDimitry Andric {
235*0b57cec5SDimitry Andric     void* p = 0;
236*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
237*0b57cec5SDimitry Andric     try
238*0b57cec5SDimitry Andric     {
239*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
240*0b57cec5SDimitry Andric         p = ::operator new[](size, alignment);
241*0b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
242*0b57cec5SDimitry Andric     }
243*0b57cec5SDimitry Andric     catch (...)
244*0b57cec5SDimitry Andric     {
245*0b57cec5SDimitry Andric     }
246*0b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
247*0b57cec5SDimitry Andric     return p;
248*0b57cec5SDimitry Andric }
249*0b57cec5SDimitry Andric 
250*0b57cec5SDimitry Andric _LIBCPP_WEAK
251*0b57cec5SDimitry Andric void
252*0b57cec5SDimitry Andric operator delete(void* ptr, std::align_val_t) _NOEXCEPT
253*0b57cec5SDimitry Andric {
254*0b57cec5SDimitry Andric #if defined(_LIBCPP_MSVCRT_LIKE)
255*0b57cec5SDimitry Andric     ::_aligned_free(ptr);
256*0b57cec5SDimitry Andric #else
257*0b57cec5SDimitry Andric     ::free(ptr);
258*0b57cec5SDimitry Andric #endif
259*0b57cec5SDimitry Andric }
260*0b57cec5SDimitry Andric 
261*0b57cec5SDimitry Andric _LIBCPP_WEAK
262*0b57cec5SDimitry Andric void
263*0b57cec5SDimitry Andric operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
264*0b57cec5SDimitry Andric {
265*0b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
266*0b57cec5SDimitry Andric }
267*0b57cec5SDimitry Andric 
268*0b57cec5SDimitry Andric _LIBCPP_WEAK
269*0b57cec5SDimitry Andric void
270*0b57cec5SDimitry Andric operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
271*0b57cec5SDimitry Andric {
272*0b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
273*0b57cec5SDimitry Andric }
274*0b57cec5SDimitry Andric 
275*0b57cec5SDimitry Andric _LIBCPP_WEAK
276*0b57cec5SDimitry Andric void
277*0b57cec5SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
278*0b57cec5SDimitry Andric {
279*0b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
280*0b57cec5SDimitry Andric }
281*0b57cec5SDimitry Andric 
282*0b57cec5SDimitry Andric _LIBCPP_WEAK
283*0b57cec5SDimitry Andric void
284*0b57cec5SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
285*0b57cec5SDimitry Andric {
286*0b57cec5SDimitry Andric     ::operator delete[](ptr, alignment);
287*0b57cec5SDimitry Andric }
288*0b57cec5SDimitry Andric 
289*0b57cec5SDimitry Andric _LIBCPP_WEAK
290*0b57cec5SDimitry Andric void
291*0b57cec5SDimitry Andric operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
292*0b57cec5SDimitry Andric {
293*0b57cec5SDimitry Andric     ::operator delete[](ptr, alignment);
294*0b57cec5SDimitry Andric }
295*0b57cec5SDimitry Andric 
296*0b57cec5SDimitry Andric #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
297*0b57cec5SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
298