1*eb8650a7SLouis Dionne //===----------------------------------------------------------------------===//
237812274SEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
637812274SEric Fiselier //
737812274SEric Fiselier //
837812274SEric Fiselier // This file implements the new and delete operators.
937812274SEric Fiselier //===----------------------------------------------------------------------===//
1037812274SEric Fiselier 
1137812274SEric Fiselier #include "__cxxabi_config.h"
1237812274SEric Fiselier #include <new>
1337812274SEric Fiselier #include <cstdlib>
1437812274SEric Fiselier 
155601305fSLouis Dionne #if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK)
165601305fSLouis Dionne #error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \
17b2577e5dSEric Fiselier        already be defined by libc++.
1837812274SEric Fiselier #endif
19b2577e5dSEric Fiselier // Implement all new and delete operators as weak definitions
20b2577e5dSEric Fiselier // in this shared library, so that they can be overridden by programs
21b2577e5dSEric Fiselier // that define non-weak copies of the functions.
2237812274SEric Fiselier 
2337812274SEric Fiselier _LIBCXXABI_WEAK
2437812274SEric Fiselier void *
operator new(std::size_t size)2537812274SEric Fiselier operator new(std::size_t size) _THROW_BAD_ALLOC
2637812274SEric Fiselier {
2737812274SEric Fiselier     if (size == 0)
2837812274SEric Fiselier         size = 1;
2937812274SEric Fiselier     void* p;
30527a7fdfSBruce Mitchener     while ((p = ::malloc(size)) == nullptr)
3137812274SEric Fiselier     {
32b2577e5dSEric Fiselier         // If malloc fails and there is a new_handler,
33b2577e5dSEric Fiselier         // call it to try free up memory.
3437812274SEric Fiselier         std::new_handler nh = std::get_new_handler();
3537812274SEric Fiselier         if (nh)
3637812274SEric Fiselier             nh();
3737812274SEric Fiselier         else
3837812274SEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
3937812274SEric Fiselier             throw std::bad_alloc();
4037812274SEric Fiselier #else
4137812274SEric Fiselier             break;
4237812274SEric Fiselier #endif
4337812274SEric Fiselier     }
4437812274SEric Fiselier     return p;
4537812274SEric Fiselier }
4637812274SEric Fiselier 
4737812274SEric Fiselier _LIBCXXABI_WEAK
4837812274SEric Fiselier void*
operator new(size_t size,const std::nothrow_t &)495601305fSLouis Dionne operator new(size_t size, const std::nothrow_t&) noexcept
5037812274SEric Fiselier {
51527a7fdfSBruce Mitchener     void* p = nullptr;
5237812274SEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
5337812274SEric Fiselier     try
5437812274SEric Fiselier     {
55b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
5637812274SEric Fiselier         p = ::operator new(size);
5737812274SEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
5837812274SEric Fiselier     }
5937812274SEric Fiselier     catch (...)
6037812274SEric Fiselier     {
6137812274SEric Fiselier     }
62b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
6337812274SEric Fiselier     return p;
6437812274SEric Fiselier }
6537812274SEric Fiselier 
6637812274SEric Fiselier _LIBCXXABI_WEAK
6737812274SEric Fiselier void*
operator new[](size_t size)6837812274SEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC
6937812274SEric Fiselier {
7037812274SEric Fiselier     return ::operator new(size);
7137812274SEric Fiselier }
7237812274SEric Fiselier 
7337812274SEric Fiselier _LIBCXXABI_WEAK
7437812274SEric Fiselier void*
operator new[](size_t size,const std::nothrow_t &)755601305fSLouis Dionne operator new[](size_t size, const std::nothrow_t&) noexcept
7637812274SEric Fiselier {
77527a7fdfSBruce Mitchener     void* p = nullptr;
7837812274SEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
7937812274SEric Fiselier     try
8037812274SEric Fiselier     {
81b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
8237812274SEric Fiselier         p = ::operator new[](size);
8337812274SEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
8437812274SEric Fiselier     }
8537812274SEric Fiselier     catch (...)
8637812274SEric Fiselier     {
8737812274SEric Fiselier     }
88b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
8937812274SEric Fiselier     return p;
9037812274SEric Fiselier }
9137812274SEric Fiselier 
9237812274SEric Fiselier _LIBCXXABI_WEAK
9337812274SEric Fiselier void
operator delete(void * ptr)945601305fSLouis Dionne operator delete(void* ptr) noexcept
9537812274SEric Fiselier {
96b2577e5dSEric Fiselier     ::free(ptr);
9737812274SEric Fiselier }
9837812274SEric Fiselier 
9937812274SEric Fiselier _LIBCXXABI_WEAK
10037812274SEric Fiselier void
operator delete(void * ptr,const std::nothrow_t &)1015601305fSLouis Dionne operator delete(void* ptr, const std::nothrow_t&) noexcept
10237812274SEric Fiselier {
10337812274SEric Fiselier     ::operator delete(ptr);
10437812274SEric Fiselier }
10537812274SEric Fiselier 
106b2577e5dSEric Fiselier _LIBCXXABI_WEAK
107b2577e5dSEric Fiselier void
operator delete(void * ptr,size_t)1085601305fSLouis Dionne operator delete(void* ptr, size_t) noexcept
109b2577e5dSEric Fiselier {
110b2577e5dSEric Fiselier     ::operator delete(ptr);
111b2577e5dSEric Fiselier }
11237812274SEric Fiselier 
11337812274SEric Fiselier _LIBCXXABI_WEAK
11437812274SEric Fiselier void
operator delete[](void * ptr)1155601305fSLouis Dionne operator delete[] (void* ptr) noexcept
11637812274SEric Fiselier {
11737812274SEric Fiselier     ::operator delete(ptr);
11837812274SEric Fiselier }
11937812274SEric Fiselier 
12037812274SEric Fiselier _LIBCXXABI_WEAK
12137812274SEric Fiselier void
operator delete[](void * ptr,const std::nothrow_t &)1225601305fSLouis Dionne operator delete[] (void* ptr, const std::nothrow_t&) noexcept
12337812274SEric Fiselier {
12437812274SEric Fiselier     ::operator delete[](ptr);
12537812274SEric Fiselier }
126b2577e5dSEric Fiselier 
127b2577e5dSEric Fiselier _LIBCXXABI_WEAK
128b2577e5dSEric Fiselier void
operator delete[](void * ptr,size_t)1295601305fSLouis Dionne operator delete[] (void* ptr, size_t) noexcept
130b2577e5dSEric Fiselier {
131b2577e5dSEric Fiselier     ::operator delete[](ptr);
132b2577e5dSEric Fiselier }
133b2577e5dSEric Fiselier 
13451fbb2e7SEric Fiselier #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
135b2577e5dSEric Fiselier 
136b2577e5dSEric Fiselier _LIBCXXABI_WEAK
137b2577e5dSEric Fiselier void *
operator new(std::size_t size,std::align_val_t alignment)138b2577e5dSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
139b2577e5dSEric Fiselier {
140b2577e5dSEric Fiselier     if (size == 0)
141b2577e5dSEric Fiselier         size = 1;
142b2577e5dSEric Fiselier     if (static_cast<size_t>(alignment) < sizeof(void*))
143b2577e5dSEric Fiselier       alignment = std::align_val_t(sizeof(void*));
144a78aaa1aSLouis Dionne 
145a78aaa1aSLouis Dionne     // Try allocating memory. If allocation fails and there is a new_handler,
146a78aaa1aSLouis Dionne     // call it to try free up memory, and try again until it succeeds, or until
147a78aaa1aSLouis Dionne     // the new_handler decides to terminate.
148a78aaa1aSLouis Dionne     //
149a78aaa1aSLouis Dionne     // If allocation fails and there is no new_handler, we throw bad_alloc
150a78aaa1aSLouis Dionne     // (or return nullptr if exceptions are disabled).
151b2577e5dSEric Fiselier     void* p;
152a78aaa1aSLouis Dionne     while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
153b2577e5dSEric Fiselier     {
154b2577e5dSEric Fiselier         std::new_handler nh = std::get_new_handler();
155b2577e5dSEric Fiselier         if (nh)
156b2577e5dSEric Fiselier             nh();
157b2577e5dSEric Fiselier         else {
158b2577e5dSEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
159b2577e5dSEric Fiselier             throw std::bad_alloc();
160b2577e5dSEric Fiselier #else
161b2577e5dSEric Fiselier             break;
162b2577e5dSEric Fiselier #endif
163b2577e5dSEric Fiselier         }
164b2577e5dSEric Fiselier     }
165b2577e5dSEric Fiselier     return p;
166b2577e5dSEric Fiselier }
167b2577e5dSEric Fiselier 
168b2577e5dSEric Fiselier _LIBCXXABI_WEAK
169b2577e5dSEric Fiselier void*
operator new(size_t size,std::align_val_t alignment,const std::nothrow_t &)1705601305fSLouis Dionne operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
171b2577e5dSEric Fiselier {
172527a7fdfSBruce Mitchener     void* p = nullptr;
173b2577e5dSEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
174b2577e5dSEric Fiselier     try
175b2577e5dSEric Fiselier     {
176b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
177b2577e5dSEric Fiselier         p = ::operator new(size, alignment);
178b2577e5dSEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
179b2577e5dSEric Fiselier     }
180b2577e5dSEric Fiselier     catch (...)
181b2577e5dSEric Fiselier     {
182b2577e5dSEric Fiselier     }
183b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
184b2577e5dSEric Fiselier     return p;
185b2577e5dSEric Fiselier }
186b2577e5dSEric Fiselier 
187b2577e5dSEric Fiselier _LIBCXXABI_WEAK
188b2577e5dSEric Fiselier void*
operator new[](size_t size,std::align_val_t alignment)189b2577e5dSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
190b2577e5dSEric Fiselier {
191b2577e5dSEric Fiselier     return ::operator new(size, alignment);
192b2577e5dSEric Fiselier }
193b2577e5dSEric Fiselier 
194b2577e5dSEric Fiselier _LIBCXXABI_WEAK
195b2577e5dSEric Fiselier void*
operator new[](size_t size,std::align_val_t alignment,const std::nothrow_t &)1965601305fSLouis Dionne operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
197b2577e5dSEric Fiselier {
198527a7fdfSBruce Mitchener     void* p = nullptr;
199b2577e5dSEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
200b2577e5dSEric Fiselier     try
201b2577e5dSEric Fiselier     {
202b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
203b2577e5dSEric Fiselier         p = ::operator new[](size, alignment);
204b2577e5dSEric Fiselier #ifndef _LIBCXXABI_NO_EXCEPTIONS
205b2577e5dSEric Fiselier     }
206b2577e5dSEric Fiselier     catch (...)
207b2577e5dSEric Fiselier     {
208b2577e5dSEric Fiselier     }
209b2577e5dSEric Fiselier #endif // _LIBCXXABI_NO_EXCEPTIONS
210b2577e5dSEric Fiselier     return p;
211b2577e5dSEric Fiselier }
212b2577e5dSEric Fiselier 
213b2577e5dSEric Fiselier _LIBCXXABI_WEAK
214b2577e5dSEric Fiselier void
operator delete(void * ptr,std::align_val_t)2155601305fSLouis Dionne operator delete(void* ptr, std::align_val_t) noexcept
216b2577e5dSEric Fiselier {
217a78aaa1aSLouis Dionne     std::__libcpp_aligned_free(ptr);
218a78aaa1aSLouis Dionne }
219b2577e5dSEric Fiselier 
220b2577e5dSEric Fiselier _LIBCXXABI_WEAK
221b2577e5dSEric Fiselier void
operator delete(void * ptr,std::align_val_t alignment,const std::nothrow_t &)2225601305fSLouis Dionne operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
223b2577e5dSEric Fiselier {
224b2577e5dSEric Fiselier     ::operator delete(ptr, alignment);
225b2577e5dSEric Fiselier }
226b2577e5dSEric Fiselier 
227b2577e5dSEric Fiselier _LIBCXXABI_WEAK
228b2577e5dSEric Fiselier void
operator delete(void * ptr,size_t,std::align_val_t alignment)2295601305fSLouis Dionne operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
230b2577e5dSEric Fiselier {
231b2577e5dSEric Fiselier     ::operator delete(ptr, alignment);
232b2577e5dSEric Fiselier }
233b2577e5dSEric Fiselier 
234b2577e5dSEric Fiselier _LIBCXXABI_WEAK
235b2577e5dSEric Fiselier void
operator delete[](void * ptr,std::align_val_t alignment)2365601305fSLouis Dionne operator delete[] (void* ptr, std::align_val_t alignment) noexcept
237b2577e5dSEric Fiselier {
238b2577e5dSEric Fiselier     ::operator delete(ptr, alignment);
239b2577e5dSEric Fiselier }
240b2577e5dSEric Fiselier 
241b2577e5dSEric Fiselier _LIBCXXABI_WEAK
242b2577e5dSEric Fiselier void
operator delete[](void * ptr,std::align_val_t alignment,const std::nothrow_t &)2435601305fSLouis Dionne operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
244b2577e5dSEric Fiselier {
245b2577e5dSEric Fiselier     ::operator delete[](ptr, alignment);
246b2577e5dSEric Fiselier }
247b2577e5dSEric Fiselier 
248b2577e5dSEric Fiselier _LIBCXXABI_WEAK
249b2577e5dSEric Fiselier void
operator delete[](void * ptr,size_t,std::align_val_t alignment)2505601305fSLouis Dionne operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
251b2577e5dSEric Fiselier {
252b2577e5dSEric Fiselier     ::operator delete[](ptr, alignment);
253b2577e5dSEric Fiselier }
254b2577e5dSEric Fiselier 
25551fbb2e7SEric Fiselier #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
256