xref: /llvm-project-15.0.7/libcxx/src/new.cpp (revision efea0451)
13e519524SHoward Hinnant //===--------------------------- new.cpp ----------------------------------===//
23e519524SHoward Hinnant //
35b08a8a4SHoward Hinnant //                     The LLVM Compiler Infrastructure
43e519524SHoward Hinnant //
5412dbebeSHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open
6412dbebeSHoward Hinnant // Source Licenses. See LICENSE.TXT for details.
73e519524SHoward Hinnant //
83e519524SHoward Hinnant //===----------------------------------------------------------------------===//
93e519524SHoward Hinnant 
106e8ebb2cSMarshall Clow #define _LIBCPP_BUILDING_NEW
116e8ebb2cSMarshall Clow 
12111e0cbeSNick Kledzik #include <stdlib.h>
13111e0cbeSNick Kledzik 
143e519524SHoward Hinnant #include "new"
153e519524SHoward Hinnant 
161285e4d6SEric Fiselier #if defined(__APPLE__) && !defined(LIBCXXRT) && \
171285e4d6SEric Fiselier     !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
18128ba719SHoward Hinnant     #include <cxxabi.h>
192c9c6a57SHoward Hinnant 
202c9c6a57SHoward Hinnant     #ifndef _LIBCPPABI_VERSION
21111e0cbeSNick Kledzik         // On Darwin, there are two STL shared libraries and a lower level ABI
22c1cf9818SMarshall Clow         // shared library.  The global holding the current new handler is
23111e0cbeSNick Kledzik         // in the ABI library and named __cxa_new_handler.
24111e0cbeSNick Kledzik         #define __new_handler __cxxabiapple::__cxa_new_handler
252c9c6a57SHoward Hinnant     #endif
26940e211cSHoward Hinnant #else  // __APPLE__
27929df471SBenjamin Kramer     #if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
28dce0696aSHoward Hinnant         #include <cxxabi.h>
29929df471SBenjamin Kramer     #endif  // defined(LIBCXX_BUILDING_LIBCXXABI)
301285e4d6SEric Fiselier     #if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \
311285e4d6SEric Fiselier         (!defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__))
32111e0cbeSNick Kledzik         static std::new_handler __new_handler;
33dce0696aSHoward Hinnant     #endif  // _LIBCPPABI_VERSION
34111e0cbeSNick Kledzik #endif
35111e0cbeSNick Kledzik 
36926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
37926aa5f4SPeter Collingbourne 
38111e0cbeSNick Kledzik // Implement all new and delete operators as weak definitions
3910fe4209SEric Fiselier // in this shared library, so that they can be overridden by programs
40111e0cbeSNick Kledzik // that define non-weak copies of the functions.
41111e0cbeSNick Kledzik 
42dce4218dSShoaib Meenai _LIBCPP_WEAK
43111e0cbeSNick Kledzik void *
440ae4f23fSEric Fiselier operator new(std::size_t size) _THROW_BAD_ALLOC
45111e0cbeSNick Kledzik {
46111e0cbeSNick Kledzik     if (size == 0)
47111e0cbeSNick Kledzik         size = 1;
48111e0cbeSNick Kledzik     void* p;
49111e0cbeSNick Kledzik     while ((p = ::malloc(size)) == 0)
50111e0cbeSNick Kledzik     {
51111e0cbeSNick Kledzik         // If malloc fails and there is a new_handler,
52111e0cbeSNick Kledzik         // call it to try free up memory.
5375357bcdSHoward Hinnant         std::new_handler nh = std::get_new_handler();
54816cb897SHoward Hinnant         if (nh)
55816cb897SHoward Hinnant             nh();
56111e0cbeSNick Kledzik         else
5754b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
58111e0cbeSNick Kledzik             throw std::bad_alloc();
5954b409fdSHoward Hinnant #else
6054b409fdSHoward Hinnant             break;
6154b409fdSHoward Hinnant #endif
62111e0cbeSNick Kledzik     }
63111e0cbeSNick Kledzik     return p;
64111e0cbeSNick Kledzik }
65111e0cbeSNick Kledzik 
66dce4218dSShoaib Meenai _LIBCPP_WEAK
67111e0cbeSNick Kledzik void*
6824a2ebe6SEric Fiselier operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
6924a2ebe6SEric Fiselier {
7024a2ebe6SEric Fiselier     void* p = 0;
7124a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
7224a2ebe6SEric Fiselier     try
7324a2ebe6SEric Fiselier     {
7424a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
7524a2ebe6SEric Fiselier         p = ::operator new(size);
7624a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
7724a2ebe6SEric Fiselier     }
7824a2ebe6SEric Fiselier     catch (...)
7924a2ebe6SEric Fiselier     {
8024a2ebe6SEric Fiselier     }
8124a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
8224a2ebe6SEric Fiselier     return p;
8324a2ebe6SEric Fiselier }
8424a2ebe6SEric Fiselier 
8524a2ebe6SEric Fiselier _LIBCPP_WEAK
8624a2ebe6SEric Fiselier void*
8724a2ebe6SEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC
8824a2ebe6SEric Fiselier {
8924a2ebe6SEric Fiselier     return ::operator new(size);
9024a2ebe6SEric Fiselier }
9124a2ebe6SEric Fiselier 
9224a2ebe6SEric Fiselier _LIBCPP_WEAK
9324a2ebe6SEric Fiselier void*
9424a2ebe6SEric Fiselier operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
9524a2ebe6SEric Fiselier {
9624a2ebe6SEric Fiselier     void* p = 0;
9724a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
9824a2ebe6SEric Fiselier     try
9924a2ebe6SEric Fiselier     {
10024a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
10124a2ebe6SEric Fiselier         p = ::operator new[](size);
10224a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
10324a2ebe6SEric Fiselier     }
10424a2ebe6SEric Fiselier     catch (...)
10524a2ebe6SEric Fiselier     {
10624a2ebe6SEric Fiselier     }
10724a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
10824a2ebe6SEric Fiselier     return p;
10924a2ebe6SEric Fiselier }
11024a2ebe6SEric Fiselier 
11124a2ebe6SEric Fiselier _LIBCPP_WEAK
11224a2ebe6SEric Fiselier void
11324a2ebe6SEric Fiselier operator delete(void* ptr) _NOEXCEPT
11424a2ebe6SEric Fiselier {
11524a2ebe6SEric Fiselier     if (ptr)
11624a2ebe6SEric Fiselier         ::free(ptr);
11724a2ebe6SEric Fiselier }
11824a2ebe6SEric Fiselier 
11924a2ebe6SEric Fiselier _LIBCPP_WEAK
12024a2ebe6SEric Fiselier void
12124a2ebe6SEric Fiselier operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
12224a2ebe6SEric Fiselier {
12324a2ebe6SEric Fiselier     ::operator delete(ptr);
12424a2ebe6SEric Fiselier }
12524a2ebe6SEric Fiselier 
12624a2ebe6SEric Fiselier _LIBCPP_WEAK
12724a2ebe6SEric Fiselier void
12824a2ebe6SEric Fiselier operator delete(void* ptr, size_t) _NOEXCEPT
12924a2ebe6SEric Fiselier {
13024a2ebe6SEric Fiselier     ::operator delete(ptr);
13124a2ebe6SEric Fiselier }
13224a2ebe6SEric Fiselier 
13324a2ebe6SEric Fiselier _LIBCPP_WEAK
13424a2ebe6SEric Fiselier void
13524a2ebe6SEric Fiselier operator delete[] (void* ptr) _NOEXCEPT
13624a2ebe6SEric Fiselier {
13724a2ebe6SEric Fiselier     ::operator delete(ptr);
13824a2ebe6SEric Fiselier }
13924a2ebe6SEric Fiselier 
14024a2ebe6SEric Fiselier _LIBCPP_WEAK
14124a2ebe6SEric Fiselier void
14224a2ebe6SEric Fiselier operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
14324a2ebe6SEric Fiselier {
14424a2ebe6SEric Fiselier     ::operator delete[](ptr);
14524a2ebe6SEric Fiselier }
14624a2ebe6SEric Fiselier 
14724a2ebe6SEric Fiselier _LIBCPP_WEAK
14824a2ebe6SEric Fiselier void
14924a2ebe6SEric Fiselier operator delete[] (void* ptr, size_t) _NOEXCEPT
15024a2ebe6SEric Fiselier {
15124a2ebe6SEric Fiselier     ::operator delete[](ptr);
15224a2ebe6SEric Fiselier }
15324a2ebe6SEric Fiselier 
154*efea0451SEric Fiselier #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
155*efea0451SEric Fiselier 
15624a2ebe6SEric Fiselier _LIBCPP_WEAK
15724a2ebe6SEric Fiselier void *
1580ae4f23fSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1590ae4f23fSEric Fiselier {
1600ae4f23fSEric Fiselier     if (size == 0)
1610ae4f23fSEric Fiselier         size = 1;
1620ae4f23fSEric Fiselier     if (static_cast<size_t>(alignment) < sizeof(void*))
1630ae4f23fSEric Fiselier       alignment = std::align_val_t(sizeof(void*));
1640ae4f23fSEric Fiselier     void* p;
165b2826a1dSSaleem Abdulrasool #if defined(_LIBCPP_MSVCRT)
1663e835372SEric Fiselier     while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
1673e835372SEric Fiselier #else
1680ae4f23fSEric Fiselier     while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
1693e835372SEric Fiselier #endif
1700ae4f23fSEric Fiselier     {
1710ae4f23fSEric Fiselier         // If posix_memalign fails and there is a new_handler,
1720ae4f23fSEric Fiselier         // call it to try free up memory.
1730ae4f23fSEric Fiselier         std::new_handler nh = std::get_new_handler();
1740ae4f23fSEric Fiselier         if (nh)
1750ae4f23fSEric Fiselier             nh();
1760ae4f23fSEric Fiselier         else {
1770ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1780ae4f23fSEric Fiselier             throw std::bad_alloc();
1790ae4f23fSEric Fiselier #else
1800ae4f23fSEric Fiselier             p = nullptr; // posix_memalign doesn't initialize 'p' on failure
1810ae4f23fSEric Fiselier             break;
1820ae4f23fSEric Fiselier #endif
1830ae4f23fSEric Fiselier         }
1840ae4f23fSEric Fiselier     }
1850ae4f23fSEric Fiselier     return p;
1860ae4f23fSEric Fiselier }
1870ae4f23fSEric Fiselier 
188dce4218dSShoaib Meenai _LIBCPP_WEAK
1890ae4f23fSEric Fiselier void*
1900ae4f23fSEric Fiselier operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
1910ae4f23fSEric Fiselier {
1920ae4f23fSEric Fiselier     void* p = 0;
1930ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1940ae4f23fSEric Fiselier     try
1950ae4f23fSEric Fiselier     {
1960ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1970ae4f23fSEric Fiselier         p = ::operator new(size, alignment);
1980ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1990ae4f23fSEric Fiselier     }
2000ae4f23fSEric Fiselier     catch (...)
2010ae4f23fSEric Fiselier     {
2020ae4f23fSEric Fiselier     }
2030ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2040ae4f23fSEric Fiselier     return p;
2050ae4f23fSEric Fiselier }
2060ae4f23fSEric Fiselier 
207dce4218dSShoaib Meenai _LIBCPP_WEAK
2080ae4f23fSEric Fiselier void*
2090ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
2100ae4f23fSEric Fiselier {
2110ae4f23fSEric Fiselier     return ::operator new(size, alignment);
2120ae4f23fSEric Fiselier }
2130ae4f23fSEric Fiselier 
214dce4218dSShoaib Meenai _LIBCPP_WEAK
2150ae4f23fSEric Fiselier void*
2160ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2170ae4f23fSEric Fiselier {
2180ae4f23fSEric Fiselier     void* p = 0;
2190ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2200ae4f23fSEric Fiselier     try
2210ae4f23fSEric Fiselier     {
2220ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2230ae4f23fSEric Fiselier         p = ::operator new[](size, alignment);
2240ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2250ae4f23fSEric Fiselier     }
2260ae4f23fSEric Fiselier     catch (...)
2270ae4f23fSEric Fiselier     {
2280ae4f23fSEric Fiselier     }
2290ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2300ae4f23fSEric Fiselier     return p;
2310ae4f23fSEric Fiselier }
2320ae4f23fSEric Fiselier 
233dce4218dSShoaib Meenai _LIBCPP_WEAK
234111e0cbeSNick Kledzik void
2350ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t) _NOEXCEPT
2360ae4f23fSEric Fiselier {
2370ae4f23fSEric Fiselier     if (ptr)
2387ce92f73SShoaib Meenai #if defined(_LIBCPP_MSVCRT)
2397ce92f73SShoaib Meenai         ::_aligned_free(ptr);
2407ce92f73SShoaib Meenai #else
2410ae4f23fSEric Fiselier         ::free(ptr);
2427ce92f73SShoaib Meenai #endif
2430ae4f23fSEric Fiselier }
2440ae4f23fSEric Fiselier 
245dce4218dSShoaib Meenai _LIBCPP_WEAK
2460ae4f23fSEric Fiselier void
2470ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2480ae4f23fSEric Fiselier {
2490ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2500ae4f23fSEric Fiselier }
2510ae4f23fSEric Fiselier 
252dce4218dSShoaib Meenai _LIBCPP_WEAK
2530ae4f23fSEric Fiselier void
2540ae4f23fSEric Fiselier operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2550ae4f23fSEric Fiselier {
2560ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2570ae4f23fSEric Fiselier }
2580ae4f23fSEric Fiselier 
259dce4218dSShoaib Meenai _LIBCPP_WEAK
2600ae4f23fSEric Fiselier void
2610ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
2620ae4f23fSEric Fiselier {
2630ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2640ae4f23fSEric Fiselier }
2650ae4f23fSEric Fiselier 
266dce4218dSShoaib Meenai _LIBCPP_WEAK
2670ae4f23fSEric Fiselier void
2680ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2690ae4f23fSEric Fiselier {
2700ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2710ae4f23fSEric Fiselier }
2720ae4f23fSEric Fiselier 
273dce4218dSShoaib Meenai _LIBCPP_WEAK
2740ae4f23fSEric Fiselier void
2750ae4f23fSEric Fiselier operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2760ae4f23fSEric Fiselier {
2770ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2780ae4f23fSEric Fiselier }
2790ae4f23fSEric Fiselier 
280*efea0451SEric Fiselier #endif // !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
281*efea0451SEric Fiselier 
282926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
283926aa5f4SPeter Collingbourne 
2843e519524SHoward Hinnant namespace std
2853e519524SHoward Hinnant {
2863e519524SHoward Hinnant 
287926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
28862713dacSNick Kledzik const nothrow_t nothrow = {};
289926aa5f4SPeter Collingbourne #endif
29062713dacSNick Kledzik 
2912c9c6a57SHoward Hinnant #ifndef _LIBCPPABI_VERSION
2922c9c6a57SHoward Hinnant 
293926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
294926aa5f4SPeter Collingbourne 
29562713dacSNick Kledzik new_handler
296fafca58cSHoward Hinnant set_new_handler(new_handler handler) _NOEXCEPT
29762713dacSNick Kledzik {
2981596c453SHoward Hinnant     return __sync_lock_test_and_set(&__new_handler, handler);
2991596c453SHoward Hinnant }
3001596c453SHoward Hinnant 
3011596c453SHoward Hinnant new_handler
302fafca58cSHoward Hinnant get_new_handler() _NOEXCEPT
3031596c453SHoward Hinnant {
304634b9dd7SJoerg Sonnenberger     return __sync_fetch_and_add(&__new_handler, nullptr);
30562713dacSNick Kledzik }
30662713dacSNick Kledzik 
307926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
308926aa5f4SPeter Collingbourne 
309e1da544eSDavid Chisnall #ifndef LIBCXXRT
310e1da544eSDavid Chisnall 
311fafca58cSHoward Hinnant bad_alloc::bad_alloc() _NOEXCEPT
312111e0cbeSNick Kledzik {
313111e0cbeSNick Kledzik }
314111e0cbeSNick Kledzik 
315926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
316926aa5f4SPeter Collingbourne 
317fafca58cSHoward Hinnant bad_alloc::~bad_alloc() _NOEXCEPT
318111e0cbeSNick Kledzik {
319111e0cbeSNick Kledzik }
320111e0cbeSNick Kledzik 
321111e0cbeSNick Kledzik const char*
322fafca58cSHoward Hinnant bad_alloc::what() const _NOEXCEPT
323111e0cbeSNick Kledzik {
324111e0cbeSNick Kledzik     return "std::bad_alloc";
325111e0cbeSNick Kledzik }
326111e0cbeSNick Kledzik 
327926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
328926aa5f4SPeter Collingbourne 
329fafca58cSHoward Hinnant bad_array_new_length::bad_array_new_length() _NOEXCEPT
330111e0cbeSNick Kledzik {
331111e0cbeSNick Kledzik }
332111e0cbeSNick Kledzik 
333194e81f6SEric Fiselier #ifndef __GLIBCXX__
334194e81f6SEric Fiselier 
335fafca58cSHoward Hinnant bad_array_new_length::~bad_array_new_length() _NOEXCEPT
3363e519524SHoward Hinnant {
3373e519524SHoward Hinnant }
3383e519524SHoward Hinnant 
3391d558b84SEric Fiselier const char*
3401d558b84SEric Fiselier bad_array_new_length::what() const _NOEXCEPT
3411d558b84SEric Fiselier {
3421d558b84SEric Fiselier     return "bad_array_new_length";
3431d558b84SEric Fiselier }
3441d558b84SEric Fiselier 
345194e81f6SEric Fiselier #endif // !__GLIBCXX__
346194e81f6SEric Fiselier 
347fd465fe5SEric Fiselier #endif //LIBCXXRT
348fd465fe5SEric Fiselier 
349194e81f6SEric Fiselier bad_array_length::bad_array_length() _NOEXCEPT
350194e81f6SEric Fiselier {
351194e81f6SEric Fiselier }
352194e81f6SEric Fiselier 
353194e81f6SEric Fiselier #ifndef __GLIBCXX__
354194e81f6SEric Fiselier 
355194e81f6SEric Fiselier bad_array_length::~bad_array_length() _NOEXCEPT
356194e81f6SEric Fiselier {
357194e81f6SEric Fiselier }
358194e81f6SEric Fiselier 
3593e519524SHoward Hinnant const char*
3606e8ebb2cSMarshall Clow bad_array_length::what() const _NOEXCEPT
3616e8ebb2cSMarshall Clow {
3626e8ebb2cSMarshall Clow     return "bad_array_length";
3636e8ebb2cSMarshall Clow }
3646e8ebb2cSMarshall Clow 
365194e81f6SEric Fiselier #endif // !__GLIBCXX__
3666e8ebb2cSMarshall Clow 
3676e8ebb2cSMarshall Clow #endif // _LIBCPPABI_VERSION
3682c9c6a57SHoward Hinnant 
36926dd09e5SPeter Collingbourne #ifndef LIBSTDCXX
37026dd09e5SPeter Collingbourne 
3713e519524SHoward Hinnant void
3723e519524SHoward Hinnant __throw_bad_alloc()
3733e519524SHoward Hinnant {
37454b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
3753e519524SHoward Hinnant     throw bad_alloc();
376d437fa5cSMarshall Clow #else
377d437fa5cSMarshall Clow     _VSTD::abort();
37854b409fdSHoward Hinnant #endif
3793e519524SHoward Hinnant }
3803e519524SHoward Hinnant 
38126dd09e5SPeter Collingbourne #endif // !LIBSTDCXX
38226dd09e5SPeter Collingbourne 
3833e519524SHoward Hinnant }  // std
384