xref: /llvm-project-15.0.7/libcxx/src/new.cpp (revision 3e835372)
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 
1622b131ffSEric Fiselier #if defined(__APPLE__) && !defined(LIBCXXRT)
17128ba719SHoward Hinnant     #include <cxxabi.h>
182c9c6a57SHoward Hinnant 
192c9c6a57SHoward Hinnant     #ifndef _LIBCPPABI_VERSION
20111e0cbeSNick Kledzik         // On Darwin, there are two STL shared libraries and a lower level ABI
21c1cf9818SMarshall Clow         // shared library.  The global holding the current new handler is
22111e0cbeSNick Kledzik         // in the ABI library and named __cxa_new_handler.
23111e0cbeSNick Kledzik         #define __new_handler __cxxabiapple::__cxa_new_handler
242c9c6a57SHoward Hinnant     #endif
25940e211cSHoward Hinnant #else  // __APPLE__
26929df471SBenjamin Kramer     #if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
27dce0696aSHoward Hinnant         #include <cxxabi.h>
28929df471SBenjamin Kramer     #endif  // defined(LIBCXX_BUILDING_LIBCXXABI)
29926aa5f4SPeter Collingbourne     #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
30111e0cbeSNick Kledzik         static std::new_handler __new_handler;
31dce0696aSHoward Hinnant     #endif  // _LIBCPPABI_VERSION
32111e0cbeSNick Kledzik #endif
33111e0cbeSNick Kledzik 
34926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
35926aa5f4SPeter Collingbourne 
36111e0cbeSNick Kledzik // Implement all new and delete operators as weak definitions
3710fe4209SEric Fiselier // in this shared library, so that they can be overridden by programs
38111e0cbeSNick Kledzik // that define non-weak copies of the functions.
39111e0cbeSNick Kledzik 
40dce4218dSShoaib Meenai _LIBCPP_WEAK
41111e0cbeSNick Kledzik void *
420ae4f23fSEric Fiselier operator new(std::size_t size) _THROW_BAD_ALLOC
43111e0cbeSNick Kledzik {
44111e0cbeSNick Kledzik     if (size == 0)
45111e0cbeSNick Kledzik         size = 1;
46111e0cbeSNick Kledzik     void* p;
47111e0cbeSNick Kledzik     while ((p = ::malloc(size)) == 0)
48111e0cbeSNick Kledzik     {
49111e0cbeSNick Kledzik         // If malloc fails and there is a new_handler,
50111e0cbeSNick Kledzik         // call it to try free up memory.
5175357bcdSHoward Hinnant         std::new_handler nh = std::get_new_handler();
52816cb897SHoward Hinnant         if (nh)
53816cb897SHoward Hinnant             nh();
54111e0cbeSNick Kledzik         else
5554b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
56111e0cbeSNick Kledzik             throw std::bad_alloc();
5754b409fdSHoward Hinnant #else
5854b409fdSHoward Hinnant             break;
5954b409fdSHoward Hinnant #endif
60111e0cbeSNick Kledzik     }
61111e0cbeSNick Kledzik     return p;
62111e0cbeSNick Kledzik }
63111e0cbeSNick Kledzik 
64dce4218dSShoaib Meenai _LIBCPP_WEAK
65111e0cbeSNick Kledzik void *
660ae4f23fSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
670ae4f23fSEric Fiselier {
680ae4f23fSEric Fiselier     if (size == 0)
690ae4f23fSEric Fiselier         size = 1;
700ae4f23fSEric Fiselier     if (static_cast<size_t>(alignment) < sizeof(void*))
710ae4f23fSEric Fiselier       alignment = std::align_val_t(sizeof(void*));
720ae4f23fSEric Fiselier     void* p;
73*3e835372SEric Fiselier #if defined(_WIN32)
74*3e835372SEric Fiselier     while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
75*3e835372SEric Fiselier #else
760ae4f23fSEric Fiselier     while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
77*3e835372SEric Fiselier #endif
780ae4f23fSEric Fiselier     {
790ae4f23fSEric Fiselier         // If posix_memalign fails and there is a new_handler,
800ae4f23fSEric Fiselier         // call it to try free up memory.
810ae4f23fSEric Fiselier         std::new_handler nh = std::get_new_handler();
820ae4f23fSEric Fiselier         if (nh)
830ae4f23fSEric Fiselier             nh();
840ae4f23fSEric Fiselier         else {
850ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
860ae4f23fSEric Fiselier             throw std::bad_alloc();
870ae4f23fSEric Fiselier #else
880ae4f23fSEric Fiselier             p = nullptr; // posix_memalign doesn't initialize 'p' on failure
890ae4f23fSEric Fiselier             break;
900ae4f23fSEric Fiselier #endif
910ae4f23fSEric Fiselier         }
920ae4f23fSEric Fiselier     }
930ae4f23fSEric Fiselier     return p;
940ae4f23fSEric Fiselier }
950ae4f23fSEric Fiselier 
96dce4218dSShoaib Meenai _LIBCPP_WEAK
970ae4f23fSEric Fiselier void*
98fafca58cSHoward Hinnant operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
99111e0cbeSNick Kledzik {
100111e0cbeSNick Kledzik     void* p = 0;
10154b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
102111e0cbeSNick Kledzik     try
103111e0cbeSNick Kledzik     {
104940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
105111e0cbeSNick Kledzik         p = ::operator new(size);
10654b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
107111e0cbeSNick Kledzik     }
108111e0cbeSNick Kledzik     catch (...)
109111e0cbeSNick Kledzik     {
110111e0cbeSNick Kledzik     }
111940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
112111e0cbeSNick Kledzik     return p;
113111e0cbeSNick Kledzik }
114111e0cbeSNick Kledzik 
115dce4218dSShoaib Meenai _LIBCPP_WEAK
116111e0cbeSNick Kledzik void*
1170ae4f23fSEric Fiselier operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
1180ae4f23fSEric Fiselier {
1190ae4f23fSEric Fiselier     void* p = 0;
1200ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1210ae4f23fSEric Fiselier     try
1220ae4f23fSEric Fiselier     {
1230ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1240ae4f23fSEric Fiselier         p = ::operator new(size, alignment);
1250ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1260ae4f23fSEric Fiselier     }
1270ae4f23fSEric Fiselier     catch (...)
1280ae4f23fSEric Fiselier     {
1290ae4f23fSEric Fiselier     }
1300ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1310ae4f23fSEric Fiselier     return p;
1320ae4f23fSEric Fiselier }
1330ae4f23fSEric Fiselier 
134dce4218dSShoaib Meenai _LIBCPP_WEAK
1350ae4f23fSEric Fiselier void*
1360ae4f23fSEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC
137111e0cbeSNick Kledzik {
138111e0cbeSNick Kledzik     return ::operator new(size);
139111e0cbeSNick Kledzik }
140111e0cbeSNick Kledzik 
141dce4218dSShoaib Meenai _LIBCPP_WEAK
142111e0cbeSNick Kledzik void*
1430ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1440ae4f23fSEric Fiselier {
1450ae4f23fSEric Fiselier     return ::operator new(size, alignment);
1460ae4f23fSEric Fiselier }
1470ae4f23fSEric Fiselier 
148dce4218dSShoaib Meenai _LIBCPP_WEAK
1490ae4f23fSEric Fiselier void*
150c206366fSHoward Hinnant operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
151111e0cbeSNick Kledzik {
152111e0cbeSNick Kledzik     void* p = 0;
15354b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
154111e0cbeSNick Kledzik     try
155111e0cbeSNick Kledzik     {
156940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
157111e0cbeSNick Kledzik         p = ::operator new[](size);
15854b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
159111e0cbeSNick Kledzik     }
160111e0cbeSNick Kledzik     catch (...)
161111e0cbeSNick Kledzik     {
162111e0cbeSNick Kledzik     }
163940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
164111e0cbeSNick Kledzik     return p;
165111e0cbeSNick Kledzik }
166111e0cbeSNick Kledzik 
167dce4218dSShoaib Meenai _LIBCPP_WEAK
1680ae4f23fSEric Fiselier void*
1690ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
1700ae4f23fSEric Fiselier {
1710ae4f23fSEric Fiselier     void* p = 0;
1720ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1730ae4f23fSEric Fiselier     try
1740ae4f23fSEric Fiselier     {
1750ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1760ae4f23fSEric Fiselier         p = ::operator new[](size, alignment);
1770ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1780ae4f23fSEric Fiselier     }
1790ae4f23fSEric Fiselier     catch (...)
1800ae4f23fSEric Fiselier     {
1810ae4f23fSEric Fiselier     }
1820ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1830ae4f23fSEric Fiselier     return p;
1840ae4f23fSEric Fiselier }
1850ae4f23fSEric Fiselier 
186dce4218dSShoaib Meenai _LIBCPP_WEAK
187111e0cbeSNick Kledzik void
188fafca58cSHoward Hinnant operator delete(void* ptr) _NOEXCEPT
189111e0cbeSNick Kledzik {
190111e0cbeSNick Kledzik     if (ptr)
191111e0cbeSNick Kledzik         ::free(ptr);
192111e0cbeSNick Kledzik }
193111e0cbeSNick Kledzik 
194dce4218dSShoaib Meenai _LIBCPP_WEAK
195111e0cbeSNick Kledzik void
1960ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t) _NOEXCEPT
1970ae4f23fSEric Fiselier {
1980ae4f23fSEric Fiselier     if (ptr)
1990ae4f23fSEric Fiselier         ::free(ptr);
2000ae4f23fSEric Fiselier }
2010ae4f23fSEric Fiselier 
202dce4218dSShoaib Meenai _LIBCPP_WEAK
2030ae4f23fSEric Fiselier void
204fafca58cSHoward Hinnant operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
205111e0cbeSNick Kledzik {
206111e0cbeSNick Kledzik     ::operator delete(ptr);
207111e0cbeSNick Kledzik }
208111e0cbeSNick Kledzik 
209dce4218dSShoaib Meenai _LIBCPP_WEAK
210111e0cbeSNick Kledzik void
2110ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2120ae4f23fSEric Fiselier {
2130ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2140ae4f23fSEric Fiselier }
2150ae4f23fSEric Fiselier 
216dce4218dSShoaib Meenai _LIBCPP_WEAK
2170ae4f23fSEric Fiselier void
218e4864e0bSLarisse Voufo operator delete(void* ptr, size_t) _NOEXCEPT
219d36bd700SLarisse Voufo {
220d36bd700SLarisse Voufo     ::operator delete(ptr);
221d36bd700SLarisse Voufo }
222d36bd700SLarisse Voufo 
223dce4218dSShoaib Meenai _LIBCPP_WEAK
224d36bd700SLarisse Voufo void
2250ae4f23fSEric Fiselier operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2260ae4f23fSEric Fiselier {
2270ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2280ae4f23fSEric Fiselier }
2290ae4f23fSEric Fiselier 
230dce4218dSShoaib Meenai _LIBCPP_WEAK
2310ae4f23fSEric Fiselier void
232fafca58cSHoward Hinnant operator delete[] (void* ptr) _NOEXCEPT
233111e0cbeSNick Kledzik {
234111e0cbeSNick Kledzik     ::operator delete(ptr);
235111e0cbeSNick Kledzik }
236111e0cbeSNick Kledzik 
237dce4218dSShoaib Meenai _LIBCPP_WEAK
238111e0cbeSNick Kledzik void
2390ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
2400ae4f23fSEric Fiselier {
2410ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2420ae4f23fSEric Fiselier }
2430ae4f23fSEric Fiselier 
244dce4218dSShoaib Meenai _LIBCPP_WEAK
2450ae4f23fSEric Fiselier void
246fafca58cSHoward Hinnant operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
247111e0cbeSNick Kledzik {
248111e0cbeSNick Kledzik     ::operator delete[](ptr);
249111e0cbeSNick Kledzik }
250111e0cbeSNick Kledzik 
251dce4218dSShoaib Meenai _LIBCPP_WEAK
252d36bd700SLarisse Voufo void
2530ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2540ae4f23fSEric Fiselier {
2550ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2560ae4f23fSEric Fiselier }
2570ae4f23fSEric Fiselier 
258dce4218dSShoaib Meenai _LIBCPP_WEAK
2590ae4f23fSEric Fiselier void
260e4864e0bSLarisse Voufo operator delete[] (void* ptr, size_t) _NOEXCEPT
261d36bd700SLarisse Voufo {
262d36bd700SLarisse Voufo     ::operator delete[](ptr);
263d36bd700SLarisse Voufo }
264d36bd700SLarisse Voufo 
265dce4218dSShoaib Meenai _LIBCPP_WEAK
2660ae4f23fSEric Fiselier void
2670ae4f23fSEric Fiselier operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2680ae4f23fSEric Fiselier {
2690ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2700ae4f23fSEric Fiselier }
2710ae4f23fSEric Fiselier 
272926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
273926aa5f4SPeter Collingbourne 
2743e519524SHoward Hinnant namespace std
2753e519524SHoward Hinnant {
2763e519524SHoward Hinnant 
277926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
27862713dacSNick Kledzik const nothrow_t nothrow = {};
279926aa5f4SPeter Collingbourne #endif
28062713dacSNick Kledzik 
2812c9c6a57SHoward Hinnant #ifndef _LIBCPPABI_VERSION
2822c9c6a57SHoward Hinnant 
283926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
284926aa5f4SPeter Collingbourne 
28562713dacSNick Kledzik new_handler
286fafca58cSHoward Hinnant set_new_handler(new_handler handler) _NOEXCEPT
28762713dacSNick Kledzik {
2881596c453SHoward Hinnant     return __sync_lock_test_and_set(&__new_handler, handler);
2891596c453SHoward Hinnant }
2901596c453SHoward Hinnant 
2911596c453SHoward Hinnant new_handler
292fafca58cSHoward Hinnant get_new_handler() _NOEXCEPT
2931596c453SHoward Hinnant {
294634b9dd7SJoerg Sonnenberger     return __sync_fetch_and_add(&__new_handler, nullptr);
29562713dacSNick Kledzik }
29662713dacSNick Kledzik 
297926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
298926aa5f4SPeter Collingbourne 
299e1da544eSDavid Chisnall #ifndef LIBCXXRT
300e1da544eSDavid Chisnall 
301fafca58cSHoward Hinnant bad_alloc::bad_alloc() _NOEXCEPT
302111e0cbeSNick Kledzik {
303111e0cbeSNick Kledzik }
304111e0cbeSNick Kledzik 
305926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
306926aa5f4SPeter Collingbourne 
307fafca58cSHoward Hinnant bad_alloc::~bad_alloc() _NOEXCEPT
308111e0cbeSNick Kledzik {
309111e0cbeSNick Kledzik }
310111e0cbeSNick Kledzik 
311111e0cbeSNick Kledzik const char*
312fafca58cSHoward Hinnant bad_alloc::what() const _NOEXCEPT
313111e0cbeSNick Kledzik {
314111e0cbeSNick Kledzik     return "std::bad_alloc";
315111e0cbeSNick Kledzik }
316111e0cbeSNick Kledzik 
317926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
318926aa5f4SPeter Collingbourne 
319fafca58cSHoward Hinnant bad_array_new_length::bad_array_new_length() _NOEXCEPT
320111e0cbeSNick Kledzik {
321111e0cbeSNick Kledzik }
322111e0cbeSNick Kledzik 
323194e81f6SEric Fiselier #ifndef __GLIBCXX__
324194e81f6SEric Fiselier 
325fafca58cSHoward Hinnant bad_array_new_length::~bad_array_new_length() _NOEXCEPT
3263e519524SHoward Hinnant {
3273e519524SHoward Hinnant }
3283e519524SHoward Hinnant 
3291d558b84SEric Fiselier const char*
3301d558b84SEric Fiselier bad_array_new_length::what() const _NOEXCEPT
3311d558b84SEric Fiselier {
3321d558b84SEric Fiselier     return "bad_array_new_length";
3331d558b84SEric Fiselier }
3341d558b84SEric Fiselier 
335194e81f6SEric Fiselier #endif // !__GLIBCXX__
336194e81f6SEric Fiselier 
337fd465fe5SEric Fiselier #endif //LIBCXXRT
338fd465fe5SEric Fiselier 
339194e81f6SEric Fiselier bad_array_length::bad_array_length() _NOEXCEPT
340194e81f6SEric Fiselier {
341194e81f6SEric Fiselier }
342194e81f6SEric Fiselier 
343194e81f6SEric Fiselier #ifndef __GLIBCXX__
344194e81f6SEric Fiselier 
345194e81f6SEric Fiselier bad_array_length::~bad_array_length() _NOEXCEPT
346194e81f6SEric Fiselier {
347194e81f6SEric Fiselier }
348194e81f6SEric Fiselier 
3493e519524SHoward Hinnant const char*
3506e8ebb2cSMarshall Clow bad_array_length::what() const _NOEXCEPT
3516e8ebb2cSMarshall Clow {
3526e8ebb2cSMarshall Clow     return "bad_array_length";
3536e8ebb2cSMarshall Clow }
3546e8ebb2cSMarshall Clow 
355194e81f6SEric Fiselier #endif // !__GLIBCXX__
3566e8ebb2cSMarshall Clow 
3576e8ebb2cSMarshall Clow #endif // _LIBCPPABI_VERSION
3582c9c6a57SHoward Hinnant 
35926dd09e5SPeter Collingbourne #ifndef LIBSTDCXX
36026dd09e5SPeter Collingbourne 
3613e519524SHoward Hinnant void
3623e519524SHoward Hinnant __throw_bad_alloc()
3633e519524SHoward Hinnant {
36454b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
3653e519524SHoward Hinnant     throw bad_alloc();
366d437fa5cSMarshall Clow #else
367d437fa5cSMarshall Clow     _VSTD::abort();
36854b409fdSHoward Hinnant #endif
3693e519524SHoward Hinnant }
3703e519524SHoward Hinnant 
37126dd09e5SPeter Collingbourne #endif // !LIBSTDCXX
37226dd09e5SPeter Collingbourne 
3733e519524SHoward Hinnant }  // std
374