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