xref: /freebsd/contrib/llvm-project/libcxx/src/new.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9*06c3fb27SDimitry Andric #include <__memory/aligned_alloc.h>
10*06c3fb27SDimitry Andric #include <cstdlib>
1181ad6265SDimitry Andric #include <new>
120b57cec5SDimitry Andric 
13*06c3fb27SDimitry Andric #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)
140b57cec5SDimitry Andric 
15*06c3fb27SDimitry Andric // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp
16*06c3fb27SDimitry Andric // file. The version in this file is the canonical one.
170b57cec5SDimitry Andric 
18*06c3fb27SDimitry Andric // ------------------ BEGIN COPY ------------------
190b57cec5SDimitry Andric // Implement all new and delete operators as weak definitions
200b57cec5SDimitry Andric // in this shared library, so that they can be overridden by programs
210b57cec5SDimitry Andric // that define non-weak copies of the functions.
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric _LIBCPP_WEAK
240b57cec5SDimitry Andric void *
250b57cec5SDimitry Andric operator new(std::size_t size) _THROW_BAD_ALLOC
260b57cec5SDimitry Andric {
270b57cec5SDimitry Andric     if (size == 0)
280b57cec5SDimitry Andric         size = 1;
290b57cec5SDimitry Andric     void* p;
30*06c3fb27SDimitry Andric     while ((p = std::malloc(size)) == nullptr)
310b57cec5SDimitry Andric     {
320b57cec5SDimitry Andric         // If malloc fails and there is a new_handler,
330b57cec5SDimitry Andric         // call it to try free up memory.
340b57cec5SDimitry Andric         std::new_handler nh = std::get_new_handler();
350b57cec5SDimitry Andric         if (nh)
360b57cec5SDimitry Andric             nh();
370b57cec5SDimitry Andric         else
38*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
390b57cec5SDimitry Andric             throw std::bad_alloc();
400b57cec5SDimitry Andric #else
410b57cec5SDimitry Andric             break;
420b57cec5SDimitry Andric #endif
430b57cec5SDimitry Andric     }
440b57cec5SDimitry Andric     return p;
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric _LIBCPP_WEAK
480b57cec5SDimitry Andric void*
49fe6060f1SDimitry Andric operator new(size_t size, const std::nothrow_t&) noexcept
500b57cec5SDimitry Andric {
51e8d8bef9SDimitry Andric     void* p = nullptr;
52*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
530b57cec5SDimitry Andric     try
540b57cec5SDimitry Andric     {
55*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
560b57cec5SDimitry Andric         p = ::operator new(size);
57*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
580b57cec5SDimitry Andric     }
590b57cec5SDimitry Andric     catch (...)
600b57cec5SDimitry Andric     {
610b57cec5SDimitry Andric     }
62*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
630b57cec5SDimitry Andric     return p;
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric _LIBCPP_WEAK
670b57cec5SDimitry Andric void*
680b57cec5SDimitry Andric operator new[](size_t size) _THROW_BAD_ALLOC
690b57cec5SDimitry Andric {
700b57cec5SDimitry Andric     return ::operator new(size);
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric _LIBCPP_WEAK
740b57cec5SDimitry Andric void*
75fe6060f1SDimitry Andric operator new[](size_t size, const std::nothrow_t&) noexcept
760b57cec5SDimitry Andric {
77e8d8bef9SDimitry Andric     void* p = nullptr;
78*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
790b57cec5SDimitry Andric     try
800b57cec5SDimitry Andric     {
81*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
820b57cec5SDimitry Andric         p = ::operator new[](size);
83*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
840b57cec5SDimitry Andric     }
850b57cec5SDimitry Andric     catch (...)
860b57cec5SDimitry Andric     {
870b57cec5SDimitry Andric     }
88*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
890b57cec5SDimitry Andric     return p;
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric _LIBCPP_WEAK
930b57cec5SDimitry Andric void
94fe6060f1SDimitry Andric operator delete(void* ptr) noexcept
950b57cec5SDimitry Andric {
96*06c3fb27SDimitry Andric     std::free(ptr);
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric _LIBCPP_WEAK
1000b57cec5SDimitry Andric void
101fe6060f1SDimitry Andric operator delete(void* ptr, const std::nothrow_t&) noexcept
1020b57cec5SDimitry Andric {
1030b57cec5SDimitry Andric     ::operator delete(ptr);
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric _LIBCPP_WEAK
1070b57cec5SDimitry Andric void
108fe6060f1SDimitry Andric operator delete(void* ptr, size_t) noexcept
1090b57cec5SDimitry Andric {
1100b57cec5SDimitry Andric     ::operator delete(ptr);
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric _LIBCPP_WEAK
1140b57cec5SDimitry Andric void
115fe6060f1SDimitry Andric operator delete[] (void* ptr) noexcept
1160b57cec5SDimitry Andric {
1170b57cec5SDimitry Andric     ::operator delete(ptr);
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric _LIBCPP_WEAK
1210b57cec5SDimitry Andric void
122fe6060f1SDimitry Andric operator delete[] (void* ptr, const std::nothrow_t&) noexcept
1230b57cec5SDimitry Andric {
1240b57cec5SDimitry Andric     ::operator delete[](ptr);
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric _LIBCPP_WEAK
1280b57cec5SDimitry Andric void
129fe6060f1SDimitry Andric operator delete[] (void* ptr, size_t) noexcept
1300b57cec5SDimitry Andric {
1310b57cec5SDimitry Andric     ::operator delete[](ptr);
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric _LIBCPP_WEAK
1370b57cec5SDimitry Andric void *
1380b57cec5SDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1390b57cec5SDimitry Andric {
1400b57cec5SDimitry Andric     if (size == 0)
1410b57cec5SDimitry Andric         size = 1;
1420b57cec5SDimitry Andric     if (static_cast<size_t>(alignment) < sizeof(void*))
1430b57cec5SDimitry Andric       alignment = std::align_val_t(sizeof(void*));
144e8d8bef9SDimitry Andric 
145e8d8bef9SDimitry Andric     // Try allocating memory. If allocation fails and there is a new_handler,
146e8d8bef9SDimitry Andric     // call it to try free up memory, and try again until it succeeds, or until
147e8d8bef9SDimitry Andric     // the new_handler decides to terminate.
148e8d8bef9SDimitry Andric     //
149e8d8bef9SDimitry Andric     // If allocation fails and there is no new_handler, we throw bad_alloc
150e8d8bef9SDimitry Andric     // (or return nullptr if exceptions are disabled).
1510b57cec5SDimitry Andric     void* p;
152e8d8bef9SDimitry Andric     while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
1530b57cec5SDimitry Andric     {
1540b57cec5SDimitry Andric         std::new_handler nh = std::get_new_handler();
1550b57cec5SDimitry Andric         if (nh)
1560b57cec5SDimitry Andric             nh();
1570b57cec5SDimitry Andric         else {
158*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1590b57cec5SDimitry Andric             throw std::bad_alloc();
1600b57cec5SDimitry Andric #else
1610b57cec5SDimitry Andric             break;
1620b57cec5SDimitry Andric #endif
1630b57cec5SDimitry Andric         }
1640b57cec5SDimitry Andric     }
1650b57cec5SDimitry Andric     return p;
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric _LIBCPP_WEAK
1690b57cec5SDimitry Andric void*
170fe6060f1SDimitry Andric operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
1710b57cec5SDimitry Andric {
172e8d8bef9SDimitry Andric     void* p = nullptr;
173*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1740b57cec5SDimitry Andric     try
1750b57cec5SDimitry Andric     {
176*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1770b57cec5SDimitry Andric         p = ::operator new(size, alignment);
178*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1790b57cec5SDimitry Andric     }
1800b57cec5SDimitry Andric     catch (...)
1810b57cec5SDimitry Andric     {
1820b57cec5SDimitry Andric     }
183*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1840b57cec5SDimitry Andric     return p;
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric _LIBCPP_WEAK
1880b57cec5SDimitry Andric void*
1890b57cec5SDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1900b57cec5SDimitry Andric {
1910b57cec5SDimitry Andric     return ::operator new(size, alignment);
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric _LIBCPP_WEAK
1950b57cec5SDimitry Andric void*
196fe6060f1SDimitry Andric operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
1970b57cec5SDimitry Andric {
198e8d8bef9SDimitry Andric     void* p = nullptr;
199*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2000b57cec5SDimitry Andric     try
2010b57cec5SDimitry Andric     {
202*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
2030b57cec5SDimitry Andric         p = ::operator new[](size, alignment);
204*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
2050b57cec5SDimitry Andric     }
2060b57cec5SDimitry Andric     catch (...)
2070b57cec5SDimitry Andric     {
2080b57cec5SDimitry Andric     }
209*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
2100b57cec5SDimitry Andric     return p;
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric _LIBCPP_WEAK
2140b57cec5SDimitry Andric void
215fe6060f1SDimitry Andric operator delete(void* ptr, std::align_val_t) noexcept
2160b57cec5SDimitry Andric {
217e8d8bef9SDimitry Andric     std::__libcpp_aligned_free(ptr);
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric _LIBCPP_WEAK
2210b57cec5SDimitry Andric void
222fe6060f1SDimitry Andric operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
2230b57cec5SDimitry Andric {
2240b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric _LIBCPP_WEAK
2280b57cec5SDimitry Andric void
229fe6060f1SDimitry Andric operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
2300b57cec5SDimitry Andric {
2310b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric _LIBCPP_WEAK
2350b57cec5SDimitry Andric void
236fe6060f1SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment) noexcept
2370b57cec5SDimitry Andric {
2380b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
2390b57cec5SDimitry Andric }
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric _LIBCPP_WEAK
2420b57cec5SDimitry Andric void
243fe6060f1SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
2440b57cec5SDimitry Andric {
2450b57cec5SDimitry Andric     ::operator delete[](ptr, alignment);
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric _LIBCPP_WEAK
2490b57cec5SDimitry Andric void
250fe6060f1SDimitry Andric operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
2510b57cec5SDimitry Andric {
2520b57cec5SDimitry Andric     ::operator delete[](ptr, alignment);
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
256*06c3fb27SDimitry Andric // ------------------ END COPY ------------------
257*06c3fb27SDimitry Andric 
258*06c3fb27SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME
259