xref: /freebsd/contrib/llvm-project/libcxx/src/new.cpp (revision 02e9120893770924227138ba49df1edb3896112a)
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <__memory/aligned_alloc.h>
10 #include <cstdlib>
11 #include <new>
12 
13 #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)
14 
15 // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp
16 // file. The version in this file is the canonical one.
17 
18 // ------------------ BEGIN COPY ------------------
19 // Implement all new and delete operators as weak definitions
20 // in this shared library, so that they can be overridden by programs
21 // that define non-weak copies of the functions.
22 
23 _LIBCPP_WEAK
24 void *
25 operator new(std::size_t size) _THROW_BAD_ALLOC
26 {
27     if (size == 0)
28         size = 1;
29     void* p;
30     while ((p = std::malloc(size)) == nullptr)
31     {
32         // If malloc fails and there is a new_handler,
33         // call it to try free up memory.
34         std::new_handler nh = std::get_new_handler();
35         if (nh)
36             nh();
37         else
38 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
39             throw std::bad_alloc();
40 #else
41             break;
42 #endif
43     }
44     return p;
45 }
46 
47 _LIBCPP_WEAK
48 void*
49 operator new(size_t size, const std::nothrow_t&) noexcept
50 {
51     void* p = nullptr;
52 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
53     try
54     {
55 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
56         p = ::operator new(size);
57 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
58     }
59     catch (...)
60     {
61     }
62 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
63     return p;
64 }
65 
66 _LIBCPP_WEAK
67 void*
68 operator new[](size_t size) _THROW_BAD_ALLOC
69 {
70     return ::operator new(size);
71 }
72 
73 _LIBCPP_WEAK
74 void*
75 operator new[](size_t size, const std::nothrow_t&) noexcept
76 {
77     void* p = nullptr;
78 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
79     try
80     {
81 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
82         p = ::operator new[](size);
83 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
84     }
85     catch (...)
86     {
87     }
88 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
89     return p;
90 }
91 
92 _LIBCPP_WEAK
93 void
94 operator delete(void* ptr) noexcept
95 {
96     std::free(ptr);
97 }
98 
99 _LIBCPP_WEAK
100 void
101 operator delete(void* ptr, const std::nothrow_t&) noexcept
102 {
103     ::operator delete(ptr);
104 }
105 
106 _LIBCPP_WEAK
107 void
108 operator delete(void* ptr, size_t) noexcept
109 {
110     ::operator delete(ptr);
111 }
112 
113 _LIBCPP_WEAK
114 void
115 operator delete[] (void* ptr) noexcept
116 {
117     ::operator delete(ptr);
118 }
119 
120 _LIBCPP_WEAK
121 void
122 operator delete[] (void* ptr, const std::nothrow_t&) noexcept
123 {
124     ::operator delete[](ptr);
125 }
126 
127 _LIBCPP_WEAK
128 void
129 operator delete[] (void* ptr, size_t) noexcept
130 {
131     ::operator delete[](ptr);
132 }
133 
134 #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
135 
136 _LIBCPP_WEAK
137 void *
138 operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
139 {
140     if (size == 0)
141         size = 1;
142     if (static_cast<size_t>(alignment) < sizeof(void*))
143       alignment = std::align_val_t(sizeof(void*));
144 
145     // Try allocating memory. If allocation fails and there is a new_handler,
146     // call it to try free up memory, and try again until it succeeds, or until
147     // the new_handler decides to terminate.
148     //
149     // If allocation fails and there is no new_handler, we throw bad_alloc
150     // (or return nullptr if exceptions are disabled).
151     void* p;
152     while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
153     {
154         std::new_handler nh = std::get_new_handler();
155         if (nh)
156             nh();
157         else {
158 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
159             throw std::bad_alloc();
160 #else
161             break;
162 #endif
163         }
164     }
165     return p;
166 }
167 
168 _LIBCPP_WEAK
169 void*
170 operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
171 {
172     void* p = nullptr;
173 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
174     try
175     {
176 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
177         p = ::operator new(size, alignment);
178 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
179     }
180     catch (...)
181     {
182     }
183 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
184     return p;
185 }
186 
187 _LIBCPP_WEAK
188 void*
189 operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
190 {
191     return ::operator new(size, alignment);
192 }
193 
194 _LIBCPP_WEAK
195 void*
196 operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
197 {
198     void* p = nullptr;
199 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
200     try
201     {
202 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
203         p = ::operator new[](size, alignment);
204 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
205     }
206     catch (...)
207     {
208     }
209 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
210     return p;
211 }
212 
213 _LIBCPP_WEAK
214 void
215 operator delete(void* ptr, std::align_val_t) noexcept
216 {
217     std::__libcpp_aligned_free(ptr);
218 }
219 
220 _LIBCPP_WEAK
221 void
222 operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
223 {
224     ::operator delete(ptr, alignment);
225 }
226 
227 _LIBCPP_WEAK
228 void
229 operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
230 {
231     ::operator delete(ptr, alignment);
232 }
233 
234 _LIBCPP_WEAK
235 void
236 operator delete[] (void* ptr, std::align_val_t alignment) noexcept
237 {
238     ::operator delete(ptr, alignment);
239 }
240 
241 _LIBCPP_WEAK
242 void
243 operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
244 {
245     ::operator delete[](ptr, alignment);
246 }
247 
248 _LIBCPP_WEAK
249 void
250 operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
251 {
252     ::operator delete[](ptr, alignment);
253 }
254 
255 #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
256 // ------------------ END COPY ------------------
257 
258 #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME
259