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*d22c9dc4SEric Fiselier #if defined(_LIBCPP_ABI_MICROSOFT) 17*d22c9dc4SEric Fiselier // nothing todo 18*d22c9dc4SEric Fiselier #elif defined(LIBCXX_BUILDING_LIBCXXABI) 19128ba719SHoward Hinnant #include <cxxabi.h> 20*d22c9dc4SEric Fiselier #elif defined(LIBCXXRT) 21*d22c9dc4SEric Fiselier #include <cxxabi.h> 22*d22c9dc4SEric Fiselier #include "support/runtime/new_handler_fallback.ipp" 23*d22c9dc4SEric Fiselier #elif defined(__GLIBCXX__) 24*d22c9dc4SEric Fiselier // nothing todo 25*d22c9dc4SEric Fiselier #else 26*d22c9dc4SEric Fiselier #include "support/runtime/new_handler_fallback.ipp" 27*d22c9dc4SEric Fiselier #endif 282c9c6a57SHoward Hinnant 29*d22c9dc4SEric Fiselier namespace std 30*d22c9dc4SEric Fiselier { 31111e0cbeSNick Kledzik 32926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__ 33*d22c9dc4SEric Fiselier const nothrow_t nothrow = {}; 34*d22c9dc4SEric Fiselier #endif 35*d22c9dc4SEric Fiselier 36*d22c9dc4SEric Fiselier #ifndef LIBSTDCXX 37*d22c9dc4SEric Fiselier 38*d22c9dc4SEric Fiselier void 39*d22c9dc4SEric Fiselier __throw_bad_alloc() 40*d22c9dc4SEric Fiselier { 41*d22c9dc4SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 42*d22c9dc4SEric Fiselier throw bad_alloc(); 43*d22c9dc4SEric Fiselier #else 44*d22c9dc4SEric Fiselier _VSTD::abort(); 45*d22c9dc4SEric Fiselier #endif 46*d22c9dc4SEric Fiselier } 47*d22c9dc4SEric Fiselier 48*d22c9dc4SEric Fiselier #endif // !LIBSTDCXX 49*d22c9dc4SEric Fiselier 50*d22c9dc4SEric Fiselier } // std 51*d22c9dc4SEric Fiselier 52*d22c9dc4SEric Fiselier #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_MICROSOFT) 53926aa5f4SPeter Collingbourne 54111e0cbeSNick Kledzik // Implement all new and delete operators as weak definitions 5510fe4209SEric Fiselier // in this shared library, so that they can be overridden by programs 56111e0cbeSNick Kledzik // that define non-weak copies of the functions. 57111e0cbeSNick Kledzik 58dce4218dSShoaib Meenai _LIBCPP_WEAK 59111e0cbeSNick Kledzik void * 600ae4f23fSEric Fiselier operator new(std::size_t size) _THROW_BAD_ALLOC 61111e0cbeSNick Kledzik { 62111e0cbeSNick Kledzik if (size == 0) 63111e0cbeSNick Kledzik size = 1; 64111e0cbeSNick Kledzik void* p; 65111e0cbeSNick Kledzik while ((p = ::malloc(size)) == 0) 66111e0cbeSNick Kledzik { 67111e0cbeSNick Kledzik // If malloc fails and there is a new_handler, 68111e0cbeSNick Kledzik // call it to try free up memory. 6975357bcdSHoward Hinnant std::new_handler nh = std::get_new_handler(); 70816cb897SHoward Hinnant if (nh) 71816cb897SHoward Hinnant nh(); 72111e0cbeSNick Kledzik else 7354b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 74111e0cbeSNick Kledzik throw std::bad_alloc(); 7554b409fdSHoward Hinnant #else 7654b409fdSHoward Hinnant break; 7754b409fdSHoward Hinnant #endif 78111e0cbeSNick Kledzik } 79111e0cbeSNick Kledzik return p; 80111e0cbeSNick Kledzik } 81111e0cbeSNick Kledzik 82dce4218dSShoaib Meenai _LIBCPP_WEAK 83111e0cbeSNick Kledzik void* 8424a2ebe6SEric Fiselier operator new(size_t size, const std::nothrow_t&) _NOEXCEPT 8524a2ebe6SEric Fiselier { 8624a2ebe6SEric Fiselier void* p = 0; 8724a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 8824a2ebe6SEric Fiselier try 8924a2ebe6SEric Fiselier { 9024a2ebe6SEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 9124a2ebe6SEric Fiselier p = ::operator new(size); 9224a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 9324a2ebe6SEric Fiselier } 9424a2ebe6SEric Fiselier catch (...) 9524a2ebe6SEric Fiselier { 9624a2ebe6SEric Fiselier } 9724a2ebe6SEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 9824a2ebe6SEric Fiselier return p; 9924a2ebe6SEric Fiselier } 10024a2ebe6SEric Fiselier 10124a2ebe6SEric Fiselier _LIBCPP_WEAK 10224a2ebe6SEric Fiselier void* 10324a2ebe6SEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC 10424a2ebe6SEric Fiselier { 10524a2ebe6SEric Fiselier return ::operator new(size); 10624a2ebe6SEric Fiselier } 10724a2ebe6SEric Fiselier 10824a2ebe6SEric Fiselier _LIBCPP_WEAK 10924a2ebe6SEric Fiselier void* 11024a2ebe6SEric Fiselier operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT 11124a2ebe6SEric Fiselier { 11224a2ebe6SEric Fiselier void* p = 0; 11324a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 11424a2ebe6SEric Fiselier try 11524a2ebe6SEric Fiselier { 11624a2ebe6SEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 11724a2ebe6SEric Fiselier p = ::operator new[](size); 11824a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 11924a2ebe6SEric Fiselier } 12024a2ebe6SEric Fiselier catch (...) 12124a2ebe6SEric Fiselier { 12224a2ebe6SEric Fiselier } 12324a2ebe6SEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 12424a2ebe6SEric Fiselier return p; 12524a2ebe6SEric Fiselier } 12624a2ebe6SEric Fiselier 12724a2ebe6SEric Fiselier _LIBCPP_WEAK 12824a2ebe6SEric Fiselier void 12924a2ebe6SEric Fiselier operator delete(void* ptr) _NOEXCEPT 13024a2ebe6SEric Fiselier { 13124a2ebe6SEric Fiselier if (ptr) 13224a2ebe6SEric Fiselier ::free(ptr); 13324a2ebe6SEric Fiselier } 13424a2ebe6SEric Fiselier 13524a2ebe6SEric Fiselier _LIBCPP_WEAK 13624a2ebe6SEric Fiselier void 13724a2ebe6SEric Fiselier operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT 13824a2ebe6SEric Fiselier { 13924a2ebe6SEric Fiselier ::operator delete(ptr); 14024a2ebe6SEric Fiselier } 14124a2ebe6SEric Fiselier 14224a2ebe6SEric Fiselier _LIBCPP_WEAK 14324a2ebe6SEric Fiselier void 14424a2ebe6SEric Fiselier operator delete(void* ptr, size_t) _NOEXCEPT 14524a2ebe6SEric Fiselier { 14624a2ebe6SEric Fiselier ::operator delete(ptr); 14724a2ebe6SEric Fiselier } 14824a2ebe6SEric Fiselier 14924a2ebe6SEric Fiselier _LIBCPP_WEAK 15024a2ebe6SEric Fiselier void 15124a2ebe6SEric Fiselier operator delete[] (void* ptr) _NOEXCEPT 15224a2ebe6SEric Fiselier { 15324a2ebe6SEric Fiselier ::operator delete(ptr); 15424a2ebe6SEric Fiselier } 15524a2ebe6SEric Fiselier 15624a2ebe6SEric Fiselier _LIBCPP_WEAK 15724a2ebe6SEric Fiselier void 15824a2ebe6SEric Fiselier operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT 15924a2ebe6SEric Fiselier { 16024a2ebe6SEric Fiselier ::operator delete[](ptr); 16124a2ebe6SEric Fiselier } 16224a2ebe6SEric Fiselier 16324a2ebe6SEric Fiselier _LIBCPP_WEAK 16424a2ebe6SEric Fiselier void 16524a2ebe6SEric Fiselier operator delete[] (void* ptr, size_t) _NOEXCEPT 16624a2ebe6SEric Fiselier { 16724a2ebe6SEric Fiselier ::operator delete[](ptr); 16824a2ebe6SEric Fiselier } 16924a2ebe6SEric Fiselier 170efea0451SEric Fiselier #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 171efea0451SEric Fiselier 17224a2ebe6SEric Fiselier _LIBCPP_WEAK 17324a2ebe6SEric Fiselier void * 1740ae4f23fSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC 1750ae4f23fSEric Fiselier { 1760ae4f23fSEric Fiselier if (size == 0) 1770ae4f23fSEric Fiselier size = 1; 1780ae4f23fSEric Fiselier if (static_cast<size_t>(alignment) < sizeof(void*)) 1790ae4f23fSEric Fiselier alignment = std::align_val_t(sizeof(void*)); 1800ae4f23fSEric Fiselier void* p; 181b2826a1dSSaleem Abdulrasool #if defined(_LIBCPP_MSVCRT) 1823e835372SEric Fiselier while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr) 1833e835372SEric Fiselier #else 1840ae4f23fSEric Fiselier while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0) 1853e835372SEric Fiselier #endif 1860ae4f23fSEric Fiselier { 1870ae4f23fSEric Fiselier // If posix_memalign fails and there is a new_handler, 1880ae4f23fSEric Fiselier // call it to try free up memory. 1890ae4f23fSEric Fiselier std::new_handler nh = std::get_new_handler(); 1900ae4f23fSEric Fiselier if (nh) 1910ae4f23fSEric Fiselier nh(); 1920ae4f23fSEric Fiselier else { 1930ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 1940ae4f23fSEric Fiselier throw std::bad_alloc(); 1950ae4f23fSEric Fiselier #else 1960ae4f23fSEric Fiselier p = nullptr; // posix_memalign doesn't initialize 'p' on failure 1970ae4f23fSEric Fiselier break; 1980ae4f23fSEric Fiselier #endif 1990ae4f23fSEric Fiselier } 2000ae4f23fSEric Fiselier } 2010ae4f23fSEric Fiselier return p; 2020ae4f23fSEric Fiselier } 2030ae4f23fSEric Fiselier 204dce4218dSShoaib Meenai _LIBCPP_WEAK 2050ae4f23fSEric Fiselier void* 2060ae4f23fSEric Fiselier operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT 2070ae4f23fSEric Fiselier { 2080ae4f23fSEric Fiselier void* p = 0; 2090ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 2100ae4f23fSEric Fiselier try 2110ae4f23fSEric Fiselier { 2120ae4f23fSEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 2130ae4f23fSEric Fiselier p = ::operator new(size, alignment); 2140ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 2150ae4f23fSEric Fiselier } 2160ae4f23fSEric Fiselier catch (...) 2170ae4f23fSEric Fiselier { 2180ae4f23fSEric Fiselier } 2190ae4f23fSEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 2200ae4f23fSEric Fiselier return p; 2210ae4f23fSEric Fiselier } 2220ae4f23fSEric Fiselier 223dce4218dSShoaib Meenai _LIBCPP_WEAK 2240ae4f23fSEric Fiselier void* 2250ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC 2260ae4f23fSEric Fiselier { 2270ae4f23fSEric Fiselier return ::operator new(size, alignment); 2280ae4f23fSEric Fiselier } 2290ae4f23fSEric Fiselier 230dce4218dSShoaib Meenai _LIBCPP_WEAK 2310ae4f23fSEric Fiselier void* 2320ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT 2330ae4f23fSEric Fiselier { 2340ae4f23fSEric Fiselier void* p = 0; 2350ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 2360ae4f23fSEric Fiselier try 2370ae4f23fSEric Fiselier { 2380ae4f23fSEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 2390ae4f23fSEric Fiselier p = ::operator new[](size, alignment); 2400ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS 2410ae4f23fSEric Fiselier } 2420ae4f23fSEric Fiselier catch (...) 2430ae4f23fSEric Fiselier { 2440ae4f23fSEric Fiselier } 2450ae4f23fSEric Fiselier #endif // _LIBCPP_NO_EXCEPTIONS 2460ae4f23fSEric Fiselier return p; 2470ae4f23fSEric Fiselier } 2480ae4f23fSEric Fiselier 249dce4218dSShoaib Meenai _LIBCPP_WEAK 250111e0cbeSNick Kledzik void 2510ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t) _NOEXCEPT 2520ae4f23fSEric Fiselier { 2530ae4f23fSEric Fiselier if (ptr) 2547ce92f73SShoaib Meenai #if defined(_LIBCPP_MSVCRT) 2557ce92f73SShoaib Meenai ::_aligned_free(ptr); 2567ce92f73SShoaib Meenai #else 2570ae4f23fSEric Fiselier ::free(ptr); 2587ce92f73SShoaib Meenai #endif 2590ae4f23fSEric Fiselier } 2600ae4f23fSEric Fiselier 261dce4218dSShoaib Meenai _LIBCPP_WEAK 2620ae4f23fSEric Fiselier void 2630ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT 2640ae4f23fSEric Fiselier { 2650ae4f23fSEric Fiselier ::operator delete(ptr, alignment); 2660ae4f23fSEric Fiselier } 2670ae4f23fSEric Fiselier 268dce4218dSShoaib Meenai _LIBCPP_WEAK 2690ae4f23fSEric Fiselier void 2700ae4f23fSEric Fiselier operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT 2710ae4f23fSEric Fiselier { 2720ae4f23fSEric Fiselier ::operator delete(ptr, alignment); 2730ae4f23fSEric Fiselier } 2740ae4f23fSEric Fiselier 275dce4218dSShoaib Meenai _LIBCPP_WEAK 2760ae4f23fSEric Fiselier void 2770ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT 2780ae4f23fSEric Fiselier { 2790ae4f23fSEric Fiselier ::operator delete(ptr, alignment); 2800ae4f23fSEric Fiselier } 2810ae4f23fSEric Fiselier 282dce4218dSShoaib Meenai _LIBCPP_WEAK 2830ae4f23fSEric Fiselier void 2840ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT 2850ae4f23fSEric Fiselier { 2860ae4f23fSEric Fiselier ::operator delete[](ptr, alignment); 2870ae4f23fSEric Fiselier } 2880ae4f23fSEric Fiselier 289dce4218dSShoaib Meenai _LIBCPP_WEAK 2900ae4f23fSEric Fiselier void 2910ae4f23fSEric Fiselier operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT 2920ae4f23fSEric Fiselier { 2930ae4f23fSEric Fiselier ::operator delete[](ptr, alignment); 2940ae4f23fSEric Fiselier } 2950ae4f23fSEric Fiselier 296*d22c9dc4SEric Fiselier #endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION 297*d22c9dc4SEric Fiselier #endif // !__GLIBCXX__ && !_LIBCPP_ABI_MICROSOFT 298