xref: /llvm-project-15.0.7/libcxx/src/new.cpp (revision 5601305f)
13e519524SHoward Hinnant //===--------------------------- new.cpp ----------------------------------===//
23e519524SHoward Hinnant //
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
63e519524SHoward Hinnant //
73e519524SHoward Hinnant //===----------------------------------------------------------------------===//
83e519524SHoward Hinnant 
9111e0cbeSNick Kledzik #include <stdlib.h>
10111e0cbeSNick Kledzik 
113e519524SHoward Hinnant #include "new"
12fbfaec70SWeiming Zhao #include "include/atomic_support.h"
133e519524SHoward Hinnant 
14d22c9dc4SEric Fiselier #if defined(_LIBCPP_ABI_MICROSOFT)
15e69290dcSEric Fiselier #   if !defined(_LIBCPP_ABI_VCRUNTIME)
16492d7134SShoaib Meenai #       include "support/runtime/new_handler_fallback.ipp"
17492d7134SShoaib Meenai #   endif
18d22c9dc4SEric Fiselier #elif defined(LIBCXX_BUILDING_LIBCXXABI)
19128ba719SHoward Hinnant #   include <cxxabi.h>
20d22c9dc4SEric Fiselier #elif defined(LIBCXXRT)
21d22c9dc4SEric Fiselier #   include <cxxabi.h>
22d22c9dc4SEric Fiselier #   include "support/runtime/new_handler_fallback.ipp"
23d22c9dc4SEric Fiselier #elif defined(__GLIBCXX__)
24d22c9dc4SEric Fiselier     // nothing to do
25a4bd340bSLouis Dionne #else
26d22c9dc4SEric Fiselier #   include "support/runtime/new_handler_fallback.ipp"
27d22c9dc4SEric Fiselier #endif
282c9c6a57SHoward Hinnant 
29d22c9dc4SEric Fiselier namespace std
30d22c9dc4SEric Fiselier {
31111e0cbeSNick Kledzik 
32926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
333663f26fSThomas Anderson const nothrow_t nothrow{};
34d22c9dc4SEric Fiselier #endif
35d22c9dc4SEric Fiselier 
36d22c9dc4SEric Fiselier #ifndef LIBSTDCXX
37d22c9dc4SEric Fiselier 
38d22c9dc4SEric Fiselier void
39d22c9dc4SEric Fiselier __throw_bad_alloc()
40d22c9dc4SEric Fiselier {
41d22c9dc4SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
42d22c9dc4SEric Fiselier     throw bad_alloc();
43d22c9dc4SEric Fiselier #else
44d22c9dc4SEric Fiselier     _VSTD::abort();
45d22c9dc4SEric Fiselier #endif
46d22c9dc4SEric Fiselier }
47d22c9dc4SEric Fiselier 
48d22c9dc4SEric Fiselier #endif // !LIBSTDCXX
49d22c9dc4SEric Fiselier 
50d22c9dc4SEric Fiselier }  // std
51d22c9dc4SEric Fiselier 
52492d7134SShoaib Meenai #if !defined(__GLIBCXX__) &&                                                   \
53e69290dcSEric Fiselier     !defined(_LIBCPP_ABI_VCRUNTIME) &&      \
543499263cSEric Fiselier     !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
55926aa5f4SPeter Collingbourne 
56111e0cbeSNick Kledzik // Implement all new and delete operators as weak definitions
5710fe4209SEric Fiselier // in this shared library, so that they can be overridden by programs
58111e0cbeSNick Kledzik // that define non-weak copies of the functions.
59111e0cbeSNick Kledzik 
60dce4218dSShoaib Meenai _LIBCPP_WEAK
61111e0cbeSNick Kledzik void *
620ae4f23fSEric Fiselier operator new(std::size_t size) _THROW_BAD_ALLOC
63111e0cbeSNick Kledzik {
64111e0cbeSNick Kledzik     if (size == 0)
65111e0cbeSNick Kledzik         size = 1;
66111e0cbeSNick Kledzik     void* p;
67527a7fdfSBruce Mitchener     while ((p = ::malloc(size)) == nullptr)
68111e0cbeSNick Kledzik     {
69111e0cbeSNick Kledzik         // If malloc fails and there is a new_handler,
70111e0cbeSNick Kledzik         // call it to try free up memory.
7175357bcdSHoward Hinnant         std::new_handler nh = std::get_new_handler();
72816cb897SHoward Hinnant         if (nh)
73816cb897SHoward Hinnant             nh();
74111e0cbeSNick Kledzik         else
7554b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
76111e0cbeSNick Kledzik             throw std::bad_alloc();
7754b409fdSHoward Hinnant #else
7854b409fdSHoward Hinnant             break;
7954b409fdSHoward Hinnant #endif
80111e0cbeSNick Kledzik     }
81111e0cbeSNick Kledzik     return p;
82111e0cbeSNick Kledzik }
83111e0cbeSNick Kledzik 
84dce4218dSShoaib Meenai _LIBCPP_WEAK
85111e0cbeSNick Kledzik void*
86*5601305fSLouis Dionne operator new(size_t size, const std::nothrow_t&) noexcept
8724a2ebe6SEric Fiselier {
88527a7fdfSBruce Mitchener     void* p = nullptr;
8924a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
9024a2ebe6SEric Fiselier     try
9124a2ebe6SEric Fiselier     {
9224a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
9324a2ebe6SEric Fiselier         p = ::operator new(size);
9424a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
9524a2ebe6SEric Fiselier     }
9624a2ebe6SEric Fiselier     catch (...)
9724a2ebe6SEric Fiselier     {
9824a2ebe6SEric Fiselier     }
9924a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
10024a2ebe6SEric Fiselier     return p;
10124a2ebe6SEric Fiselier }
10224a2ebe6SEric Fiselier 
10324a2ebe6SEric Fiselier _LIBCPP_WEAK
10424a2ebe6SEric Fiselier void*
10524a2ebe6SEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC
10624a2ebe6SEric Fiselier {
10724a2ebe6SEric Fiselier     return ::operator new(size);
10824a2ebe6SEric Fiselier }
10924a2ebe6SEric Fiselier 
11024a2ebe6SEric Fiselier _LIBCPP_WEAK
11124a2ebe6SEric Fiselier void*
112*5601305fSLouis Dionne operator new[](size_t size, const std::nothrow_t&) noexcept
11324a2ebe6SEric Fiselier {
114527a7fdfSBruce Mitchener     void* p = nullptr;
11524a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
11624a2ebe6SEric Fiselier     try
11724a2ebe6SEric Fiselier     {
11824a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
11924a2ebe6SEric Fiselier         p = ::operator new[](size);
12024a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
12124a2ebe6SEric Fiselier     }
12224a2ebe6SEric Fiselier     catch (...)
12324a2ebe6SEric Fiselier     {
12424a2ebe6SEric Fiselier     }
12524a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
12624a2ebe6SEric Fiselier     return p;
12724a2ebe6SEric Fiselier }
12824a2ebe6SEric Fiselier 
12924a2ebe6SEric Fiselier _LIBCPP_WEAK
13024a2ebe6SEric Fiselier void
131*5601305fSLouis Dionne operator delete(void* ptr) noexcept
13224a2ebe6SEric Fiselier {
13324a2ebe6SEric Fiselier     ::free(ptr);
13424a2ebe6SEric Fiselier }
13524a2ebe6SEric Fiselier 
13624a2ebe6SEric Fiselier _LIBCPP_WEAK
13724a2ebe6SEric Fiselier void
138*5601305fSLouis Dionne operator delete(void* ptr, const std::nothrow_t&) noexcept
13924a2ebe6SEric Fiselier {
14024a2ebe6SEric Fiselier     ::operator delete(ptr);
14124a2ebe6SEric Fiselier }
14224a2ebe6SEric Fiselier 
14324a2ebe6SEric Fiselier _LIBCPP_WEAK
14424a2ebe6SEric Fiselier void
145*5601305fSLouis Dionne operator delete(void* ptr, size_t) noexcept
14624a2ebe6SEric Fiselier {
14724a2ebe6SEric Fiselier     ::operator delete(ptr);
14824a2ebe6SEric Fiselier }
14924a2ebe6SEric Fiselier 
15024a2ebe6SEric Fiselier _LIBCPP_WEAK
15124a2ebe6SEric Fiselier void
152*5601305fSLouis Dionne operator delete[] (void* ptr) noexcept
15324a2ebe6SEric Fiselier {
15424a2ebe6SEric Fiselier     ::operator delete(ptr);
15524a2ebe6SEric Fiselier }
15624a2ebe6SEric Fiselier 
15724a2ebe6SEric Fiselier _LIBCPP_WEAK
15824a2ebe6SEric Fiselier void
159*5601305fSLouis Dionne operator delete[] (void* ptr, const std::nothrow_t&) noexcept
16024a2ebe6SEric Fiselier {
16124a2ebe6SEric Fiselier     ::operator delete[](ptr);
16224a2ebe6SEric Fiselier }
16324a2ebe6SEric Fiselier 
16424a2ebe6SEric Fiselier _LIBCPP_WEAK
16524a2ebe6SEric Fiselier void
166*5601305fSLouis Dionne operator delete[] (void* ptr, size_t) noexcept
16724a2ebe6SEric Fiselier {
16824a2ebe6SEric Fiselier     ::operator delete[](ptr);
16924a2ebe6SEric Fiselier }
17024a2ebe6SEric Fiselier 
17142f9868cSEric Fiselier #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
172efea0451SEric Fiselier 
17324a2ebe6SEric Fiselier _LIBCPP_WEAK
17424a2ebe6SEric Fiselier void *
1750ae4f23fSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1760ae4f23fSEric Fiselier {
1770ae4f23fSEric Fiselier     if (size == 0)
1780ae4f23fSEric Fiselier         size = 1;
1790ae4f23fSEric Fiselier     if (static_cast<size_t>(alignment) < sizeof(void*))
1800ae4f23fSEric Fiselier       alignment = std::align_val_t(sizeof(void*));
181a78aaa1aSLouis Dionne 
182a78aaa1aSLouis Dionne     // Try allocating memory. If allocation fails and there is a new_handler,
183a78aaa1aSLouis Dionne     // call it to try free up memory, and try again until it succeeds, or until
184a78aaa1aSLouis Dionne     // the new_handler decides to terminate.
185a78aaa1aSLouis Dionne     //
186a78aaa1aSLouis Dionne     // If allocation fails and there is no new_handler, we throw bad_alloc
187a78aaa1aSLouis Dionne     // (or return nullptr if exceptions are disabled).
1880ae4f23fSEric Fiselier     void* p;
189a78aaa1aSLouis Dionne     while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
1900ae4f23fSEric Fiselier     {
1910ae4f23fSEric Fiselier         std::new_handler nh = std::get_new_handler();
1920ae4f23fSEric Fiselier         if (nh)
1930ae4f23fSEric Fiselier             nh();
1940ae4f23fSEric Fiselier         else {
1950ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1960ae4f23fSEric Fiselier             throw std::bad_alloc();
1970ae4f23fSEric Fiselier #else
1980ae4f23fSEric Fiselier             break;
1990ae4f23fSEric Fiselier #endif
2000ae4f23fSEric Fiselier         }
2010ae4f23fSEric Fiselier     }
2020ae4f23fSEric Fiselier     return p;
2030ae4f23fSEric Fiselier }
2040ae4f23fSEric Fiselier 
205dce4218dSShoaib Meenai _LIBCPP_WEAK
2060ae4f23fSEric Fiselier void*
207*5601305fSLouis Dionne operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
2080ae4f23fSEric Fiselier {
209527a7fdfSBruce Mitchener     void* p = nullptr;
2100ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2110ae4f23fSEric Fiselier     try
2120ae4f23fSEric Fiselier     {
2130ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2140ae4f23fSEric Fiselier         p = ::operator new(size, alignment);
2150ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2160ae4f23fSEric Fiselier     }
2170ae4f23fSEric Fiselier     catch (...)
2180ae4f23fSEric Fiselier     {
2190ae4f23fSEric Fiselier     }
2200ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2210ae4f23fSEric Fiselier     return p;
2220ae4f23fSEric Fiselier }
2230ae4f23fSEric Fiselier 
224dce4218dSShoaib Meenai _LIBCPP_WEAK
2250ae4f23fSEric Fiselier void*
2260ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
2270ae4f23fSEric Fiselier {
2280ae4f23fSEric Fiselier     return ::operator new(size, alignment);
2290ae4f23fSEric Fiselier }
2300ae4f23fSEric Fiselier 
231dce4218dSShoaib Meenai _LIBCPP_WEAK
2320ae4f23fSEric Fiselier void*
233*5601305fSLouis Dionne operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
2340ae4f23fSEric Fiselier {
235527a7fdfSBruce Mitchener     void* p = nullptr;
2360ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2370ae4f23fSEric Fiselier     try
2380ae4f23fSEric Fiselier     {
2390ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2400ae4f23fSEric Fiselier         p = ::operator new[](size, alignment);
2410ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2420ae4f23fSEric Fiselier     }
2430ae4f23fSEric Fiselier     catch (...)
2440ae4f23fSEric Fiselier     {
2450ae4f23fSEric Fiselier     }
2460ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2470ae4f23fSEric Fiselier     return p;
2480ae4f23fSEric Fiselier }
2490ae4f23fSEric Fiselier 
250dce4218dSShoaib Meenai _LIBCPP_WEAK
251111e0cbeSNick Kledzik void
252*5601305fSLouis Dionne operator delete(void* ptr, std::align_val_t) noexcept
2530ae4f23fSEric Fiselier {
254a78aaa1aSLouis Dionne     std::__libcpp_aligned_free(ptr);
255a78aaa1aSLouis Dionne }
2560ae4f23fSEric Fiselier 
257dce4218dSShoaib Meenai _LIBCPP_WEAK
2580ae4f23fSEric Fiselier void
259*5601305fSLouis Dionne operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
2600ae4f23fSEric Fiselier {
2610ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2620ae4f23fSEric Fiselier }
2630ae4f23fSEric Fiselier 
264dce4218dSShoaib Meenai _LIBCPP_WEAK
2650ae4f23fSEric Fiselier void
266*5601305fSLouis Dionne operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
2670ae4f23fSEric Fiselier {
2680ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2690ae4f23fSEric Fiselier }
2700ae4f23fSEric Fiselier 
271dce4218dSShoaib Meenai _LIBCPP_WEAK
2720ae4f23fSEric Fiselier void
273*5601305fSLouis Dionne operator delete[] (void* ptr, std::align_val_t alignment) noexcept
2740ae4f23fSEric Fiselier {
2750ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2760ae4f23fSEric Fiselier }
2770ae4f23fSEric Fiselier 
278dce4218dSShoaib Meenai _LIBCPP_WEAK
2790ae4f23fSEric Fiselier void
280*5601305fSLouis Dionne operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
2810ae4f23fSEric Fiselier {
2820ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2830ae4f23fSEric Fiselier }
2840ae4f23fSEric Fiselier 
285dce4218dSShoaib Meenai _LIBCPP_WEAK
2860ae4f23fSEric Fiselier void
287*5601305fSLouis Dionne operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
2880ae4f23fSEric Fiselier {
2890ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2900ae4f23fSEric Fiselier }
2910ae4f23fSEric Fiselier 
29242f9868cSEric Fiselier #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
293e69290dcSEric Fiselier #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
294