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