xref: /freebsd/contrib/llvm-project/libcxx/src/new.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric //===--------------------------- new.cpp ----------------------------------===//
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 
90b57cec5SDimitry Andric #include <stdlib.h>
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "new"
120b57cec5SDimitry Andric #include "include/atomic_support.h"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #if defined(_LIBCPP_ABI_MICROSOFT)
150b57cec5SDimitry Andric #   if !defined(_LIBCPP_ABI_VCRUNTIME)
160b57cec5SDimitry Andric #       include "support/runtime/new_handler_fallback.ipp"
170b57cec5SDimitry Andric #   endif
180b57cec5SDimitry Andric #elif defined(LIBCXX_BUILDING_LIBCXXABI)
190b57cec5SDimitry Andric #   include <cxxabi.h>
200b57cec5SDimitry Andric #elif defined(LIBCXXRT)
210b57cec5SDimitry Andric #   include <cxxabi.h>
220b57cec5SDimitry Andric #   include "support/runtime/new_handler_fallback.ipp"
230b57cec5SDimitry Andric #elif defined(__GLIBCXX__)
240b57cec5SDimitry Andric     // nothing to do
250b57cec5SDimitry Andric #else
260b57cec5SDimitry Andric #   include "support/runtime/new_handler_fallback.ipp"
270b57cec5SDimitry Andric #endif
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric namespace std
300b57cec5SDimitry Andric {
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #ifndef __GLIBCXX__
330b57cec5SDimitry Andric const nothrow_t nothrow{};
340b57cec5SDimitry Andric #endif
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #ifndef LIBSTDCXX
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric void
390b57cec5SDimitry Andric __throw_bad_alloc()
400b57cec5SDimitry Andric {
410b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
420b57cec5SDimitry Andric     throw bad_alloc();
430b57cec5SDimitry Andric #else
440b57cec5SDimitry Andric     _VSTD::abort();
450b57cec5SDimitry Andric #endif
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric #endif // !LIBSTDCXX
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric }  // std
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric #if !defined(__GLIBCXX__) &&                                                   \
530b57cec5SDimitry Andric     !defined(_LIBCPP_ABI_VCRUNTIME) &&      \
540b57cec5SDimitry Andric     !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric // Implement all new and delete operators as weak definitions
570b57cec5SDimitry Andric // in this shared library, so that they can be overridden by programs
580b57cec5SDimitry Andric // that define non-weak copies of the functions.
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric _LIBCPP_WEAK
610b57cec5SDimitry Andric void *
620b57cec5SDimitry Andric operator new(std::size_t size) _THROW_BAD_ALLOC
630b57cec5SDimitry Andric {
640b57cec5SDimitry Andric     if (size == 0)
650b57cec5SDimitry Andric         size = 1;
660b57cec5SDimitry Andric     void* p;
67*e8d8bef9SDimitry Andric     while ((p = ::malloc(size)) == nullptr)
680b57cec5SDimitry Andric     {
690b57cec5SDimitry Andric         // If malloc fails and there is a new_handler,
700b57cec5SDimitry Andric         // call it to try free up memory.
710b57cec5SDimitry Andric         std::new_handler nh = std::get_new_handler();
720b57cec5SDimitry Andric         if (nh)
730b57cec5SDimitry Andric             nh();
740b57cec5SDimitry Andric         else
750b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
760b57cec5SDimitry Andric             throw std::bad_alloc();
770b57cec5SDimitry Andric #else
780b57cec5SDimitry Andric             break;
790b57cec5SDimitry Andric #endif
800b57cec5SDimitry Andric     }
810b57cec5SDimitry Andric     return p;
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric _LIBCPP_WEAK
850b57cec5SDimitry Andric void*
860b57cec5SDimitry Andric operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
870b57cec5SDimitry Andric {
88*e8d8bef9SDimitry Andric     void* p = nullptr;
890b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
900b57cec5SDimitry Andric     try
910b57cec5SDimitry Andric     {
920b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
930b57cec5SDimitry Andric         p = ::operator new(size);
940b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
950b57cec5SDimitry Andric     }
960b57cec5SDimitry Andric     catch (...)
970b57cec5SDimitry Andric     {
980b57cec5SDimitry Andric     }
990b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
1000b57cec5SDimitry Andric     return p;
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric _LIBCPP_WEAK
1040b57cec5SDimitry Andric void*
1050b57cec5SDimitry Andric operator new[](size_t size) _THROW_BAD_ALLOC
1060b57cec5SDimitry Andric {
1070b57cec5SDimitry Andric     return ::operator new(size);
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric _LIBCPP_WEAK
1110b57cec5SDimitry Andric void*
1120b57cec5SDimitry Andric operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
1130b57cec5SDimitry Andric {
114*e8d8bef9SDimitry Andric     void* p = nullptr;
1150b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
1160b57cec5SDimitry Andric     try
1170b57cec5SDimitry Andric     {
1180b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
1190b57cec5SDimitry Andric         p = ::operator new[](size);
1200b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
1210b57cec5SDimitry Andric     }
1220b57cec5SDimitry Andric     catch (...)
1230b57cec5SDimitry Andric     {
1240b57cec5SDimitry Andric     }
1250b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
1260b57cec5SDimitry Andric     return p;
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric _LIBCPP_WEAK
1300b57cec5SDimitry Andric void
1310b57cec5SDimitry Andric operator delete(void* ptr) _NOEXCEPT
1320b57cec5SDimitry Andric {
1330b57cec5SDimitry Andric     ::free(ptr);
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric _LIBCPP_WEAK
1370b57cec5SDimitry Andric void
1380b57cec5SDimitry Andric operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
1390b57cec5SDimitry Andric {
1400b57cec5SDimitry Andric     ::operator delete(ptr);
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric _LIBCPP_WEAK
1440b57cec5SDimitry Andric void
1450b57cec5SDimitry Andric operator delete(void* ptr, size_t) _NOEXCEPT
1460b57cec5SDimitry Andric {
1470b57cec5SDimitry Andric     ::operator delete(ptr);
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric _LIBCPP_WEAK
1510b57cec5SDimitry Andric void
1520b57cec5SDimitry Andric operator delete[] (void* ptr) _NOEXCEPT
1530b57cec5SDimitry Andric {
1540b57cec5SDimitry Andric     ::operator delete(ptr);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric _LIBCPP_WEAK
1580b57cec5SDimitry Andric void
1590b57cec5SDimitry Andric operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
1600b57cec5SDimitry Andric {
1610b57cec5SDimitry Andric     ::operator delete[](ptr);
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric _LIBCPP_WEAK
1650b57cec5SDimitry Andric void
1660b57cec5SDimitry Andric operator delete[] (void* ptr, size_t) _NOEXCEPT
1670b57cec5SDimitry Andric {
1680b57cec5SDimitry Andric     ::operator delete[](ptr);
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric _LIBCPP_WEAK
1740b57cec5SDimitry Andric void *
1750b57cec5SDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1760b57cec5SDimitry Andric {
1770b57cec5SDimitry Andric     if (size == 0)
1780b57cec5SDimitry Andric         size = 1;
1790b57cec5SDimitry Andric     if (static_cast<size_t>(alignment) < sizeof(void*))
1800b57cec5SDimitry Andric       alignment = std::align_val_t(sizeof(void*));
181*e8d8bef9SDimitry Andric 
182*e8d8bef9SDimitry Andric     // Try allocating memory. If allocation fails and there is a new_handler,
183*e8d8bef9SDimitry Andric     // call it to try free up memory, and try again until it succeeds, or until
184*e8d8bef9SDimitry Andric     // the new_handler decides to terminate.
185*e8d8bef9SDimitry Andric     //
186*e8d8bef9SDimitry Andric     // If allocation fails and there is no new_handler, we throw bad_alloc
187*e8d8bef9SDimitry Andric     // (or return nullptr if exceptions are disabled).
1880b57cec5SDimitry Andric     void* p;
189*e8d8bef9SDimitry Andric     while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
1900b57cec5SDimitry Andric     {
1910b57cec5SDimitry Andric         std::new_handler nh = std::get_new_handler();
1920b57cec5SDimitry Andric         if (nh)
1930b57cec5SDimitry Andric             nh();
1940b57cec5SDimitry Andric         else {
1950b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
1960b57cec5SDimitry Andric             throw std::bad_alloc();
1970b57cec5SDimitry Andric #else
1980b57cec5SDimitry Andric             break;
1990b57cec5SDimitry Andric #endif
2000b57cec5SDimitry Andric         }
2010b57cec5SDimitry Andric     }
2020b57cec5SDimitry Andric     return p;
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric _LIBCPP_WEAK
2060b57cec5SDimitry Andric void*
2070b57cec5SDimitry Andric operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2080b57cec5SDimitry Andric {
209*e8d8bef9SDimitry Andric     void* p = nullptr;
2100b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
2110b57cec5SDimitry Andric     try
2120b57cec5SDimitry Andric     {
2130b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
2140b57cec5SDimitry Andric         p = ::operator new(size, alignment);
2150b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
2160b57cec5SDimitry Andric     }
2170b57cec5SDimitry Andric     catch (...)
2180b57cec5SDimitry Andric     {
2190b57cec5SDimitry Andric     }
2200b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
2210b57cec5SDimitry Andric     return p;
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric _LIBCPP_WEAK
2250b57cec5SDimitry Andric void*
2260b57cec5SDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
2270b57cec5SDimitry Andric {
2280b57cec5SDimitry Andric     return ::operator new(size, alignment);
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric _LIBCPP_WEAK
2320b57cec5SDimitry Andric void*
2330b57cec5SDimitry Andric operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2340b57cec5SDimitry Andric {
235*e8d8bef9SDimitry Andric     void* p = nullptr;
2360b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
2370b57cec5SDimitry Andric     try
2380b57cec5SDimitry Andric     {
2390b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
2400b57cec5SDimitry Andric         p = ::operator new[](size, alignment);
2410b57cec5SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
2420b57cec5SDimitry Andric     }
2430b57cec5SDimitry Andric     catch (...)
2440b57cec5SDimitry Andric     {
2450b57cec5SDimitry Andric     }
2460b57cec5SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
2470b57cec5SDimitry Andric     return p;
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric _LIBCPP_WEAK
2510b57cec5SDimitry Andric void
2520b57cec5SDimitry Andric operator delete(void* ptr, std::align_val_t) _NOEXCEPT
2530b57cec5SDimitry Andric {
254*e8d8bef9SDimitry Andric     std::__libcpp_aligned_free(ptr);
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric _LIBCPP_WEAK
2580b57cec5SDimitry Andric void
2590b57cec5SDimitry Andric operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2600b57cec5SDimitry Andric {
2610b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric _LIBCPP_WEAK
2650b57cec5SDimitry Andric void
2660b57cec5SDimitry Andric operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2670b57cec5SDimitry Andric {
2680b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric _LIBCPP_WEAK
2720b57cec5SDimitry Andric void
2730b57cec5SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
2740b57cec5SDimitry Andric {
2750b57cec5SDimitry Andric     ::operator delete(ptr, alignment);
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric _LIBCPP_WEAK
2790b57cec5SDimitry Andric void
2800b57cec5SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2810b57cec5SDimitry Andric {
2820b57cec5SDimitry Andric     ::operator delete[](ptr, alignment);
2830b57cec5SDimitry Andric }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric _LIBCPP_WEAK
2860b57cec5SDimitry Andric void
2870b57cec5SDimitry Andric operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2880b57cec5SDimitry Andric {
2890b57cec5SDimitry Andric     ::operator delete[](ptr, alignment);
2900b57cec5SDimitry Andric }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
2930b57cec5SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
294