xref: /llvm-project-15.0.7/libcxx/src/new.cpp (revision 1285e4d6)
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 
16*1285e4d6SEric Fiselier #if defined(__APPLE__) && !defined(LIBCXXRT) && \
17*1285e4d6SEric 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)
30*1285e4d6SEric Fiselier     #if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \
31*1285e4d6SEric 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 *
680ae4f23fSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
690ae4f23fSEric Fiselier {
700ae4f23fSEric Fiselier     if (size == 0)
710ae4f23fSEric Fiselier         size = 1;
720ae4f23fSEric Fiselier     if (static_cast<size_t>(alignment) < sizeof(void*))
730ae4f23fSEric Fiselier       alignment = std::align_val_t(sizeof(void*));
740ae4f23fSEric Fiselier     void* p;
753e835372SEric Fiselier #if defined(_WIN32)
763e835372SEric Fiselier     while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
773e835372SEric Fiselier #else
780ae4f23fSEric Fiselier     while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
793e835372SEric Fiselier #endif
800ae4f23fSEric Fiselier     {
810ae4f23fSEric Fiselier         // If posix_memalign fails and there is a new_handler,
820ae4f23fSEric Fiselier         // call it to try free up memory.
830ae4f23fSEric Fiselier         std::new_handler nh = std::get_new_handler();
840ae4f23fSEric Fiselier         if (nh)
850ae4f23fSEric Fiselier             nh();
860ae4f23fSEric Fiselier         else {
870ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
880ae4f23fSEric Fiselier             throw std::bad_alloc();
890ae4f23fSEric Fiselier #else
900ae4f23fSEric Fiselier             p = nullptr; // posix_memalign doesn't initialize 'p' on failure
910ae4f23fSEric Fiselier             break;
920ae4f23fSEric Fiselier #endif
930ae4f23fSEric Fiselier         }
940ae4f23fSEric Fiselier     }
950ae4f23fSEric Fiselier     return p;
960ae4f23fSEric Fiselier }
970ae4f23fSEric Fiselier 
98dce4218dSShoaib Meenai _LIBCPP_WEAK
990ae4f23fSEric Fiselier void*
100fafca58cSHoward Hinnant operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
101111e0cbeSNick Kledzik {
102111e0cbeSNick Kledzik     void* p = 0;
10354b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
104111e0cbeSNick Kledzik     try
105111e0cbeSNick Kledzik     {
106940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
107111e0cbeSNick Kledzik         p = ::operator new(size);
10854b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
109111e0cbeSNick Kledzik     }
110111e0cbeSNick Kledzik     catch (...)
111111e0cbeSNick Kledzik     {
112111e0cbeSNick Kledzik     }
113940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
114111e0cbeSNick Kledzik     return p;
115111e0cbeSNick Kledzik }
116111e0cbeSNick Kledzik 
117dce4218dSShoaib Meenai _LIBCPP_WEAK
118111e0cbeSNick Kledzik void*
1190ae4f23fSEric Fiselier operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
1200ae4f23fSEric Fiselier {
1210ae4f23fSEric Fiselier     void* p = 0;
1220ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1230ae4f23fSEric Fiselier     try
1240ae4f23fSEric Fiselier     {
1250ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1260ae4f23fSEric Fiselier         p = ::operator new(size, alignment);
1270ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1280ae4f23fSEric Fiselier     }
1290ae4f23fSEric Fiselier     catch (...)
1300ae4f23fSEric Fiselier     {
1310ae4f23fSEric Fiselier     }
1320ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1330ae4f23fSEric Fiselier     return p;
1340ae4f23fSEric Fiselier }
1350ae4f23fSEric Fiselier 
136dce4218dSShoaib Meenai _LIBCPP_WEAK
1370ae4f23fSEric Fiselier void*
1380ae4f23fSEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC
139111e0cbeSNick Kledzik {
140111e0cbeSNick Kledzik     return ::operator new(size);
141111e0cbeSNick Kledzik }
142111e0cbeSNick Kledzik 
143dce4218dSShoaib Meenai _LIBCPP_WEAK
144111e0cbeSNick Kledzik void*
1450ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1460ae4f23fSEric Fiselier {
1470ae4f23fSEric Fiselier     return ::operator new(size, alignment);
1480ae4f23fSEric Fiselier }
1490ae4f23fSEric Fiselier 
150dce4218dSShoaib Meenai _LIBCPP_WEAK
1510ae4f23fSEric Fiselier void*
152c206366fSHoward Hinnant operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
153111e0cbeSNick Kledzik {
154111e0cbeSNick Kledzik     void* p = 0;
15554b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
156111e0cbeSNick Kledzik     try
157111e0cbeSNick Kledzik     {
158940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
159111e0cbeSNick Kledzik         p = ::operator new[](size);
16054b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
161111e0cbeSNick Kledzik     }
162111e0cbeSNick Kledzik     catch (...)
163111e0cbeSNick Kledzik     {
164111e0cbeSNick Kledzik     }
165940e211cSHoward Hinnant #endif  // _LIBCPP_NO_EXCEPTIONS
166111e0cbeSNick Kledzik     return p;
167111e0cbeSNick Kledzik }
168111e0cbeSNick Kledzik 
169dce4218dSShoaib Meenai _LIBCPP_WEAK
1700ae4f23fSEric Fiselier void*
1710ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
1720ae4f23fSEric Fiselier {
1730ae4f23fSEric Fiselier     void* p = 0;
1740ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1750ae4f23fSEric Fiselier     try
1760ae4f23fSEric Fiselier     {
1770ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1780ae4f23fSEric Fiselier         p = ::operator new[](size, alignment);
1790ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1800ae4f23fSEric Fiselier     }
1810ae4f23fSEric Fiselier     catch (...)
1820ae4f23fSEric Fiselier     {
1830ae4f23fSEric Fiselier     }
1840ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
1850ae4f23fSEric Fiselier     return p;
1860ae4f23fSEric Fiselier }
1870ae4f23fSEric Fiselier 
188dce4218dSShoaib Meenai _LIBCPP_WEAK
189111e0cbeSNick Kledzik void
190fafca58cSHoward Hinnant operator delete(void* ptr) _NOEXCEPT
191111e0cbeSNick Kledzik {
192111e0cbeSNick Kledzik     if (ptr)
193111e0cbeSNick Kledzik         ::free(ptr);
194111e0cbeSNick Kledzik }
195111e0cbeSNick Kledzik 
196dce4218dSShoaib Meenai _LIBCPP_WEAK
197111e0cbeSNick Kledzik void
1980ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t) _NOEXCEPT
1990ae4f23fSEric Fiselier {
2000ae4f23fSEric Fiselier     if (ptr)
2010ae4f23fSEric Fiselier         ::free(ptr);
2020ae4f23fSEric Fiselier }
2030ae4f23fSEric Fiselier 
204dce4218dSShoaib Meenai _LIBCPP_WEAK
2050ae4f23fSEric Fiselier void
206fafca58cSHoward Hinnant operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
207111e0cbeSNick Kledzik {
208111e0cbeSNick Kledzik     ::operator delete(ptr);
209111e0cbeSNick Kledzik }
210111e0cbeSNick Kledzik 
211dce4218dSShoaib Meenai _LIBCPP_WEAK
212111e0cbeSNick Kledzik void
2130ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2140ae4f23fSEric Fiselier {
2150ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2160ae4f23fSEric Fiselier }
2170ae4f23fSEric Fiselier 
218dce4218dSShoaib Meenai _LIBCPP_WEAK
2190ae4f23fSEric Fiselier void
220e4864e0bSLarisse Voufo operator delete(void* ptr, size_t) _NOEXCEPT
221d36bd700SLarisse Voufo {
222d36bd700SLarisse Voufo     ::operator delete(ptr);
223d36bd700SLarisse Voufo }
224d36bd700SLarisse Voufo 
225dce4218dSShoaib Meenai _LIBCPP_WEAK
226d36bd700SLarisse Voufo void
2270ae4f23fSEric Fiselier operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2280ae4f23fSEric Fiselier {
2290ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2300ae4f23fSEric Fiselier }
2310ae4f23fSEric Fiselier 
232dce4218dSShoaib Meenai _LIBCPP_WEAK
2330ae4f23fSEric Fiselier void
234fafca58cSHoward Hinnant operator delete[] (void* ptr) _NOEXCEPT
235111e0cbeSNick Kledzik {
236111e0cbeSNick Kledzik     ::operator delete(ptr);
237111e0cbeSNick Kledzik }
238111e0cbeSNick Kledzik 
239dce4218dSShoaib Meenai _LIBCPP_WEAK
240111e0cbeSNick Kledzik void
2410ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
2420ae4f23fSEric Fiselier {
2430ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2440ae4f23fSEric Fiselier }
2450ae4f23fSEric Fiselier 
246dce4218dSShoaib Meenai _LIBCPP_WEAK
2470ae4f23fSEric Fiselier void
248fafca58cSHoward Hinnant operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
249111e0cbeSNick Kledzik {
250111e0cbeSNick Kledzik     ::operator delete[](ptr);
251111e0cbeSNick Kledzik }
252111e0cbeSNick Kledzik 
253dce4218dSShoaib Meenai _LIBCPP_WEAK
254d36bd700SLarisse Voufo void
2550ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2560ae4f23fSEric Fiselier {
2570ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2580ae4f23fSEric Fiselier }
2590ae4f23fSEric Fiselier 
260dce4218dSShoaib Meenai _LIBCPP_WEAK
2610ae4f23fSEric Fiselier void
262e4864e0bSLarisse Voufo operator delete[] (void* ptr, size_t) _NOEXCEPT
263d36bd700SLarisse Voufo {
264d36bd700SLarisse Voufo     ::operator delete[](ptr);
265d36bd700SLarisse Voufo }
266d36bd700SLarisse Voufo 
267dce4218dSShoaib Meenai _LIBCPP_WEAK
2680ae4f23fSEric Fiselier void
2690ae4f23fSEric Fiselier operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2700ae4f23fSEric Fiselier {
2710ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2720ae4f23fSEric Fiselier }
2730ae4f23fSEric Fiselier 
274926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
275926aa5f4SPeter Collingbourne 
2763e519524SHoward Hinnant namespace std
2773e519524SHoward Hinnant {
2783e519524SHoward Hinnant 
279926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
28062713dacSNick Kledzik const nothrow_t nothrow = {};
281926aa5f4SPeter Collingbourne #endif
28262713dacSNick Kledzik 
2832c9c6a57SHoward Hinnant #ifndef _LIBCPPABI_VERSION
2842c9c6a57SHoward Hinnant 
285926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
286926aa5f4SPeter Collingbourne 
28762713dacSNick Kledzik new_handler
288fafca58cSHoward Hinnant set_new_handler(new_handler handler) _NOEXCEPT
28962713dacSNick Kledzik {
2901596c453SHoward Hinnant     return __sync_lock_test_and_set(&__new_handler, handler);
2911596c453SHoward Hinnant }
2921596c453SHoward Hinnant 
2931596c453SHoward Hinnant new_handler
294fafca58cSHoward Hinnant get_new_handler() _NOEXCEPT
2951596c453SHoward Hinnant {
296634b9dd7SJoerg Sonnenberger     return __sync_fetch_and_add(&__new_handler, nullptr);
29762713dacSNick Kledzik }
29862713dacSNick Kledzik 
299926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
300926aa5f4SPeter Collingbourne 
301e1da544eSDavid Chisnall #ifndef LIBCXXRT
302e1da544eSDavid Chisnall 
303fafca58cSHoward Hinnant bad_alloc::bad_alloc() _NOEXCEPT
304111e0cbeSNick Kledzik {
305111e0cbeSNick Kledzik }
306111e0cbeSNick Kledzik 
307926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
308926aa5f4SPeter Collingbourne 
309fafca58cSHoward Hinnant bad_alloc::~bad_alloc() _NOEXCEPT
310111e0cbeSNick Kledzik {
311111e0cbeSNick Kledzik }
312111e0cbeSNick Kledzik 
313111e0cbeSNick Kledzik const char*
314fafca58cSHoward Hinnant bad_alloc::what() const _NOEXCEPT
315111e0cbeSNick Kledzik {
316111e0cbeSNick Kledzik     return "std::bad_alloc";
317111e0cbeSNick Kledzik }
318111e0cbeSNick Kledzik 
319926aa5f4SPeter Collingbourne #endif // !__GLIBCXX__
320926aa5f4SPeter Collingbourne 
321fafca58cSHoward Hinnant bad_array_new_length::bad_array_new_length() _NOEXCEPT
322111e0cbeSNick Kledzik {
323111e0cbeSNick Kledzik }
324111e0cbeSNick Kledzik 
325194e81f6SEric Fiselier #ifndef __GLIBCXX__
326194e81f6SEric Fiselier 
327fafca58cSHoward Hinnant bad_array_new_length::~bad_array_new_length() _NOEXCEPT
3283e519524SHoward Hinnant {
3293e519524SHoward Hinnant }
3303e519524SHoward Hinnant 
3311d558b84SEric Fiselier const char*
3321d558b84SEric Fiselier bad_array_new_length::what() const _NOEXCEPT
3331d558b84SEric Fiselier {
3341d558b84SEric Fiselier     return "bad_array_new_length";
3351d558b84SEric Fiselier }
3361d558b84SEric Fiselier 
337194e81f6SEric Fiselier #endif // !__GLIBCXX__
338194e81f6SEric Fiselier 
339fd465fe5SEric Fiselier #endif //LIBCXXRT
340fd465fe5SEric Fiselier 
341194e81f6SEric Fiselier bad_array_length::bad_array_length() _NOEXCEPT
342194e81f6SEric Fiselier {
343194e81f6SEric Fiselier }
344194e81f6SEric Fiselier 
345194e81f6SEric Fiselier #ifndef __GLIBCXX__
346194e81f6SEric Fiselier 
347194e81f6SEric Fiselier bad_array_length::~bad_array_length() _NOEXCEPT
348194e81f6SEric Fiselier {
349194e81f6SEric Fiselier }
350194e81f6SEric Fiselier 
3513e519524SHoward Hinnant const char*
3526e8ebb2cSMarshall Clow bad_array_length::what() const _NOEXCEPT
3536e8ebb2cSMarshall Clow {
3546e8ebb2cSMarshall Clow     return "bad_array_length";
3556e8ebb2cSMarshall Clow }
3566e8ebb2cSMarshall Clow 
357194e81f6SEric Fiselier #endif // !__GLIBCXX__
3586e8ebb2cSMarshall Clow 
3596e8ebb2cSMarshall Clow #endif // _LIBCPPABI_VERSION
3602c9c6a57SHoward Hinnant 
36126dd09e5SPeter Collingbourne #ifndef LIBSTDCXX
36226dd09e5SPeter Collingbourne 
3633e519524SHoward Hinnant void
3643e519524SHoward Hinnant __throw_bad_alloc()
3653e519524SHoward Hinnant {
36654b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
3673e519524SHoward Hinnant     throw bad_alloc();
368d437fa5cSMarshall Clow #else
369d437fa5cSMarshall Clow     _VSTD::abort();
37054b409fdSHoward Hinnant #endif
3713e519524SHoward Hinnant }
3723e519524SHoward Hinnant 
37326dd09e5SPeter Collingbourne #endif // !LIBSTDCXX
37426dd09e5SPeter Collingbourne 
3753e519524SHoward Hinnant }  // std
376