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