1349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 9*06c3fb27SDimitry Andric #include <__memory/aligned_alloc.h> 10*06c3fb27SDimitry Andric #include <cstdlib> 1181ad6265SDimitry Andric #include <new> 120b57cec5SDimitry Andric 13*06c3fb27SDimitry Andric #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME) 140b57cec5SDimitry Andric 15*06c3fb27SDimitry Andric // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp 16*06c3fb27SDimitry Andric // file. The version in this file is the canonical one. 170b57cec5SDimitry Andric 18*06c3fb27SDimitry Andric // ------------------ BEGIN COPY ------------------ 190b57cec5SDimitry Andric // Implement all new and delete operators as weak definitions 200b57cec5SDimitry Andric // in this shared library, so that they can be overridden by programs 210b57cec5SDimitry Andric // that define non-weak copies of the functions. 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric _LIBCPP_WEAK 240b57cec5SDimitry Andric void * 250b57cec5SDimitry Andric operator new(std::size_t size) _THROW_BAD_ALLOC 260b57cec5SDimitry Andric { 270b57cec5SDimitry Andric if (size == 0) 280b57cec5SDimitry Andric size = 1; 290b57cec5SDimitry Andric void* p; 30*06c3fb27SDimitry Andric while ((p = std::malloc(size)) == nullptr) 310b57cec5SDimitry Andric { 320b57cec5SDimitry Andric // If malloc fails and there is a new_handler, 330b57cec5SDimitry Andric // call it to try free up memory. 340b57cec5SDimitry Andric std::new_handler nh = std::get_new_handler(); 350b57cec5SDimitry Andric if (nh) 360b57cec5SDimitry Andric nh(); 370b57cec5SDimitry Andric else 38*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 390b57cec5SDimitry Andric throw std::bad_alloc(); 400b57cec5SDimitry Andric #else 410b57cec5SDimitry Andric break; 420b57cec5SDimitry Andric #endif 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric return p; 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric _LIBCPP_WEAK 480b57cec5SDimitry Andric void* 49fe6060f1SDimitry Andric operator new(size_t size, const std::nothrow_t&) noexcept 500b57cec5SDimitry Andric { 51e8d8bef9SDimitry Andric void* p = nullptr; 52*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 530b57cec5SDimitry Andric try 540b57cec5SDimitry Andric { 55*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 560b57cec5SDimitry Andric p = ::operator new(size); 57*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric catch (...) 600b57cec5SDimitry Andric { 610b57cec5SDimitry Andric } 62*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 630b57cec5SDimitry Andric return p; 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric _LIBCPP_WEAK 670b57cec5SDimitry Andric void* 680b57cec5SDimitry Andric operator new[](size_t size) _THROW_BAD_ALLOC 690b57cec5SDimitry Andric { 700b57cec5SDimitry Andric return ::operator new(size); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric _LIBCPP_WEAK 740b57cec5SDimitry Andric void* 75fe6060f1SDimitry Andric operator new[](size_t size, const std::nothrow_t&) noexcept 760b57cec5SDimitry Andric { 77e8d8bef9SDimitry Andric void* p = nullptr; 78*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 790b57cec5SDimitry Andric try 800b57cec5SDimitry Andric { 81*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 820b57cec5SDimitry Andric p = ::operator new[](size); 83*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric catch (...) 860b57cec5SDimitry Andric { 870b57cec5SDimitry Andric } 88*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 890b57cec5SDimitry Andric return p; 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric _LIBCPP_WEAK 930b57cec5SDimitry Andric void 94fe6060f1SDimitry Andric operator delete(void* ptr) noexcept 950b57cec5SDimitry Andric { 96*06c3fb27SDimitry Andric std::free(ptr); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric _LIBCPP_WEAK 1000b57cec5SDimitry Andric void 101fe6060f1SDimitry Andric operator delete(void* ptr, const std::nothrow_t&) noexcept 1020b57cec5SDimitry Andric { 1030b57cec5SDimitry Andric ::operator delete(ptr); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric _LIBCPP_WEAK 1070b57cec5SDimitry Andric void 108fe6060f1SDimitry Andric operator delete(void* ptr, size_t) noexcept 1090b57cec5SDimitry Andric { 1100b57cec5SDimitry Andric ::operator delete(ptr); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric _LIBCPP_WEAK 1140b57cec5SDimitry Andric void 115fe6060f1SDimitry Andric operator delete[] (void* ptr) noexcept 1160b57cec5SDimitry Andric { 1170b57cec5SDimitry Andric ::operator delete(ptr); 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric _LIBCPP_WEAK 1210b57cec5SDimitry Andric void 122fe6060f1SDimitry Andric operator delete[] (void* ptr, const std::nothrow_t&) noexcept 1230b57cec5SDimitry Andric { 1240b57cec5SDimitry Andric ::operator delete[](ptr); 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric _LIBCPP_WEAK 1280b57cec5SDimitry Andric void 129fe6060f1SDimitry Andric operator delete[] (void* ptr, size_t) noexcept 1300b57cec5SDimitry Andric { 1310b57cec5SDimitry Andric ::operator delete[](ptr); 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric _LIBCPP_WEAK 1370b57cec5SDimitry Andric void * 1380b57cec5SDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC 1390b57cec5SDimitry Andric { 1400b57cec5SDimitry Andric if (size == 0) 1410b57cec5SDimitry Andric size = 1; 1420b57cec5SDimitry Andric if (static_cast<size_t>(alignment) < sizeof(void*)) 1430b57cec5SDimitry Andric alignment = std::align_val_t(sizeof(void*)); 144e8d8bef9SDimitry Andric 145e8d8bef9SDimitry Andric // Try allocating memory. If allocation fails and there is a new_handler, 146e8d8bef9SDimitry Andric // call it to try free up memory, and try again until it succeeds, or until 147e8d8bef9SDimitry Andric // the new_handler decides to terminate. 148e8d8bef9SDimitry Andric // 149e8d8bef9SDimitry Andric // If allocation fails and there is no new_handler, we throw bad_alloc 150e8d8bef9SDimitry Andric // (or return nullptr if exceptions are disabled). 1510b57cec5SDimitry Andric void* p; 152e8d8bef9SDimitry Andric while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) 1530b57cec5SDimitry Andric { 1540b57cec5SDimitry Andric std::new_handler nh = std::get_new_handler(); 1550b57cec5SDimitry Andric if (nh) 1560b57cec5SDimitry Andric nh(); 1570b57cec5SDimitry Andric else { 158*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1590b57cec5SDimitry Andric throw std::bad_alloc(); 1600b57cec5SDimitry Andric #else 1610b57cec5SDimitry Andric break; 1620b57cec5SDimitry Andric #endif 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric return p; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric _LIBCPP_WEAK 1690b57cec5SDimitry Andric void* 170fe6060f1SDimitry Andric operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept 1710b57cec5SDimitry Andric { 172e8d8bef9SDimitry Andric void* p = nullptr; 173*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1740b57cec5SDimitry Andric try 1750b57cec5SDimitry Andric { 176*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 1770b57cec5SDimitry Andric p = ::operator new(size, alignment); 178*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric catch (...) 1810b57cec5SDimitry Andric { 1820b57cec5SDimitry Andric } 183*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 1840b57cec5SDimitry Andric return p; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric _LIBCPP_WEAK 1880b57cec5SDimitry Andric void* 1890b57cec5SDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC 1900b57cec5SDimitry Andric { 1910b57cec5SDimitry Andric return ::operator new(size, alignment); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric _LIBCPP_WEAK 1950b57cec5SDimitry Andric void* 196fe6060f1SDimitry Andric operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept 1970b57cec5SDimitry Andric { 198e8d8bef9SDimitry Andric void* p = nullptr; 199*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2000b57cec5SDimitry Andric try 2010b57cec5SDimitry Andric { 202*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 2030b57cec5SDimitry Andric p = ::operator new[](size, alignment); 204*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric catch (...) 2070b57cec5SDimitry Andric { 2080b57cec5SDimitry Andric } 209*06c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS 2100b57cec5SDimitry Andric return p; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric _LIBCPP_WEAK 2140b57cec5SDimitry Andric void 215fe6060f1SDimitry Andric operator delete(void* ptr, std::align_val_t) noexcept 2160b57cec5SDimitry Andric { 217e8d8bef9SDimitry Andric std::__libcpp_aligned_free(ptr); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric _LIBCPP_WEAK 2210b57cec5SDimitry Andric void 222fe6060f1SDimitry Andric operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept 2230b57cec5SDimitry Andric { 2240b57cec5SDimitry Andric ::operator delete(ptr, alignment); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric _LIBCPP_WEAK 2280b57cec5SDimitry Andric void 229fe6060f1SDimitry Andric operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept 2300b57cec5SDimitry Andric { 2310b57cec5SDimitry Andric ::operator delete(ptr, alignment); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric _LIBCPP_WEAK 2350b57cec5SDimitry Andric void 236fe6060f1SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment) noexcept 2370b57cec5SDimitry Andric { 2380b57cec5SDimitry Andric ::operator delete(ptr, alignment); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric _LIBCPP_WEAK 2420b57cec5SDimitry Andric void 243fe6060f1SDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept 2440b57cec5SDimitry Andric { 2450b57cec5SDimitry Andric ::operator delete[](ptr, alignment); 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric _LIBCPP_WEAK 2490b57cec5SDimitry Andric void 250fe6060f1SDimitry Andric operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept 2510b57cec5SDimitry Andric { 2520b57cec5SDimitry Andric ::operator delete[](ptr, alignment); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION 256*06c3fb27SDimitry Andric // ------------------ END COPY ------------------ 257*06c3fb27SDimitry Andric 258*06c3fb27SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME 259