1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <__memory/aligned_alloc.h> 10 #include <cstdlib> 11 #include <new> 12 13 #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME) 14 15 // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp 16 // file. The version in this file is the canonical one. 17 18 // ------------------ BEGIN COPY ------------------ 19 // Implement all new and delete operators as weak definitions 20 // in this shared library, so that they can be overridden by programs 21 // that define non-weak copies of the functions. 22 23 static void* operator_new_impl(std::size_t size) noexcept { 24 if (size == 0) 25 size = 1; 26 void* p; 27 while ((p = std::malloc(size)) == nullptr) { 28 // If malloc fails and there is a new_handler, 29 // call it to try free up memory. 30 std::new_handler nh = std::get_new_handler(); 31 if (nh) 32 nh(); 33 else 34 break; 35 } 36 return p; 37 } 38 39 _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { 40 void* p = operator_new_impl(size); 41 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 42 if (p == nullptr) 43 throw std::bad_alloc(); 44 # endif 45 return p; 46 } 47 48 _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { 49 void* p = nullptr; 50 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 51 try { 52 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 53 p = ::operator new(size); 54 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 55 } catch (...) { 56 } 57 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 58 return p; 59 } 60 61 _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); } 62 63 _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept { 64 void* p = nullptr; 65 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 66 try { 67 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 68 p = ::operator new[](size); 69 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 70 } catch (...) { 71 } 72 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 73 return p; 74 } 75 76 _LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); } 77 78 _LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); } 79 80 _LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); } 81 82 _LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); } 83 84 _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); } 85 86 _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); } 87 88 # if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) 89 90 static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept { 91 if (size == 0) 92 size = 1; 93 if (static_cast<size_t>(alignment) < sizeof(void*)) 94 alignment = std::align_val_t(sizeof(void*)); 95 96 // Try allocating memory. If allocation fails and there is a new_handler, 97 // call it to try free up memory, and try again until it succeeds, or until 98 // the new_handler decides to terminate. 99 void* p; 100 while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) { 101 std::new_handler nh = std::get_new_handler(); 102 if (nh) 103 nh(); 104 else 105 break; 106 } 107 return p; 108 } 109 110 _LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { 111 void* p = operator_new_aligned_impl(size, alignment); 112 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 113 if (p == nullptr) 114 throw std::bad_alloc(); 115 # endif 116 return p; 117 } 118 119 _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { 120 void* p = nullptr; 121 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 122 try { 123 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 124 p = ::operator new(size, alignment); 125 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 126 } catch (...) { 127 } 128 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 129 return p; 130 } 131 132 _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { 133 return ::operator new(size, alignment); 134 } 135 136 _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { 137 void* p = nullptr; 138 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 139 try { 140 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 141 p = ::operator new[](size, alignment); 142 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 143 } catch (...) { 144 } 145 # endif // _LIBCPP_HAS_NO_EXCEPTIONS 146 return p; 147 } 148 149 _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); } 150 151 _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept { 152 ::operator delete(ptr, alignment); 153 } 154 155 _LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept { 156 ::operator delete(ptr, alignment); 157 } 158 159 _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept { 160 ::operator delete(ptr, alignment); 161 } 162 163 _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept { 164 ::operator delete[](ptr, alignment); 165 } 166 167 _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept { 168 ::operator delete[](ptr, alignment); 169 } 170 171 # endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION 172 // ------------------ END COPY ------------------ 173 174 #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME 175