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 906c3fb27SDimitry Andric #include <__memory/aligned_alloc.h> 1006c3fb27SDimitry Andric #include <cstdlib> 1181ad6265SDimitry Andric #include <new> 120b57cec5SDimitry Andric 1306c3fb27SDimitry Andric #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME) 140b57cec5SDimitry Andric 1506c3fb27SDimitry Andric // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp 1606c3fb27SDimitry Andric // file. The version in this file is the canonical one. 170b57cec5SDimitry Andric 1806c3fb27SDimitry 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 23*5f757f3fSDimitry Andric static void* operator_new_impl(std::size_t size) noexcept { 240b57cec5SDimitry Andric if (size == 0) 250b57cec5SDimitry Andric size = 1; 260b57cec5SDimitry Andric void* p; 27*5f757f3fSDimitry Andric while ((p = std::malloc(size)) == nullptr) { 280b57cec5SDimitry Andric // If malloc fails and there is a new_handler, 290b57cec5SDimitry Andric // call it to try free up memory. 300b57cec5SDimitry Andric std::new_handler nh = std::get_new_handler(); 310b57cec5SDimitry Andric if (nh) 320b57cec5SDimitry Andric nh(); 330b57cec5SDimitry Andric else 340b57cec5SDimitry Andric break; 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric return p; 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 39*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { 40*5f757f3fSDimitry Andric void* p = operator_new_impl(size); 41*5f757f3fSDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 42*5f757f3fSDimitry Andric if (p == nullptr) 43*5f757f3fSDimitry Andric throw std::bad_alloc(); 44*5f757f3fSDimitry Andric # endif 45*5f757f3fSDimitry Andric return p; 46*5f757f3fSDimitry Andric } 47*5f757f3fSDimitry Andric 48*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { 49e8d8bef9SDimitry Andric void* p = nullptr; 5006c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 51*5f757f3fSDimitry Andric try { 5206c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 530b57cec5SDimitry Andric p = ::operator new(size); 5406c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 55*5f757f3fSDimitry Andric } catch (...) { 560b57cec5SDimitry Andric } 5706c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 580b57cec5SDimitry Andric return p; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 61*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); } 620b57cec5SDimitry Andric 63*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept { 64e8d8bef9SDimitry Andric void* p = nullptr; 6506c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 66*5f757f3fSDimitry Andric try { 6706c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 680b57cec5SDimitry Andric p = ::operator new[](size); 6906c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 70*5f757f3fSDimitry Andric } catch (...) { 710b57cec5SDimitry Andric } 7206c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 730b57cec5SDimitry Andric return p; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 76*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); } 770b57cec5SDimitry Andric 78*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); } 790b57cec5SDimitry Andric 80*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); } 810b57cec5SDimitry Andric 82*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); } 830b57cec5SDimitry Andric 84*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); } 850b57cec5SDimitry Andric 86*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric # if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) 890b57cec5SDimitry Andric 90*5f757f3fSDimitry Andric static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept { 910b57cec5SDimitry Andric if (size == 0) 920b57cec5SDimitry Andric size = 1; 930b57cec5SDimitry Andric if (static_cast<size_t>(alignment) < sizeof(void*)) 940b57cec5SDimitry Andric alignment = std::align_val_t(sizeof(void*)); 95e8d8bef9SDimitry Andric 96e8d8bef9SDimitry Andric // Try allocating memory. If allocation fails and there is a new_handler, 97e8d8bef9SDimitry Andric // call it to try free up memory, and try again until it succeeds, or until 98e8d8bef9SDimitry Andric // the new_handler decides to terminate. 990b57cec5SDimitry Andric void* p; 100*5f757f3fSDimitry Andric while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) { 1010b57cec5SDimitry Andric std::new_handler nh = std::get_new_handler(); 1020b57cec5SDimitry Andric if (nh) 1030b57cec5SDimitry Andric nh(); 104*5f757f3fSDimitry Andric else 1050b57cec5SDimitry Andric break; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric return p; 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 110*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { 111*5f757f3fSDimitry Andric void* p = operator_new_aligned_impl(size, alignment); 112*5f757f3fSDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 113*5f757f3fSDimitry Andric if (p == nullptr) 114*5f757f3fSDimitry Andric throw std::bad_alloc(); 115*5f757f3fSDimitry Andric # endif 116*5f757f3fSDimitry Andric return p; 117*5f757f3fSDimitry Andric } 118*5f757f3fSDimitry Andric 119*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { 120e8d8bef9SDimitry Andric void* p = nullptr; 12106c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 122*5f757f3fSDimitry Andric try { 12306c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 1240b57cec5SDimitry Andric p = ::operator new(size, alignment); 12506c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 126*5f757f3fSDimitry Andric } catch (...) { 1270b57cec5SDimitry Andric } 12806c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 1290b57cec5SDimitry Andric return p; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 132*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { 1330b57cec5SDimitry Andric return ::operator new(size, alignment); 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric 136*5f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { 137e8d8bef9SDimitry Andric void* p = nullptr; 13806c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 139*5f757f3fSDimitry Andric try { 14006c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 1410b57cec5SDimitry Andric p = ::operator new[](size, alignment); 14206c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 143*5f757f3fSDimitry Andric } catch (...) { 1440b57cec5SDimitry Andric } 14506c3fb27SDimitry Andric # endif // _LIBCPP_HAS_NO_EXCEPTIONS 1460b57cec5SDimitry Andric return p; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 149*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); } 1500b57cec5SDimitry Andric 151*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept { 1520b57cec5SDimitry Andric ::operator delete(ptr, alignment); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 155*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept { 1560b57cec5SDimitry Andric ::operator delete(ptr, alignment); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 159*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept { 1600b57cec5SDimitry Andric ::operator delete(ptr, alignment); 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 163*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept { 1640b57cec5SDimitry Andric ::operator delete[](ptr, alignment); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 167*5f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept { 1680b57cec5SDimitry Andric ::operator delete[](ptr, alignment); 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric # endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION 17206c3fb27SDimitry Andric // ------------------ END COPY ------------------ 17306c3fb27SDimitry Andric 17406c3fb27SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME 175