[libcxx-commits] [libcxx] e494a96 - [libc++][NFC] Refactor the core logic of operator new into helper functions (#69407)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Oct 18 11:33:10 PDT 2023
Author: Louis Dionne
Date: 2023-10-18T11:33:05-07:00
New Revision: e494a96a69050c7401828f2d5199e1419d3ea55e
URL: https://github.com/llvm/llvm-project/commit/e494a96a69050c7401828f2d5199e1419d3ea55e
DIFF: https://github.com/llvm/llvm-project/commit/e494a96a69050c7401828f2d5199e1419d3ea55e.diff
LOG: [libc++][NFC] Refactor the core logic of operator new into helper functions (#69407)
This will make it easier to implement new(nothrow) without calling the
throwing version of new when exceptions are disabled. See
https://llvm.org/D150610 for the full discussion.
Added:
Modified:
libcxx/src/new.cpp
libcxxabi/src/stdlib_new_delete.cpp
Removed:
################################################################################
diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp
index a1c9be6107bee62..033bba5c1fc95b6 100644
--- a/libcxx/src/new.cpp
+++ b/libcxx/src/new.cpp
@@ -20,7 +20,7 @@
// in this shared library, so that they can be overridden by programs
// that define non-weak copies of the functions.
-_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
+static void* operator_new_impl(std::size_t size) noexcept {
if (size == 0)
size = 1;
void* p;
@@ -31,15 +31,20 @@ _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
if (nh)
nh();
else
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- throw std::bad_alloc();
-# else
break;
-# endif
}
return p;
}
+_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
+ void* p = operator_new_impl(size);
+# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ if (p == nullptr)
+ throw std::bad_alloc();
+# endif
+ return p;
+}
+
_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
void* p = nullptr;
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
@@ -82,7 +87,7 @@ _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator del
# if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
-_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
+static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept {
if (size == 0)
size = 1;
if (static_cast<size_t>(alignment) < sizeof(void*))
@@ -91,25 +96,26 @@ _LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _T
// Try allocating memory. If allocation fails and there is a new_handler,
// call it to try free up memory, and try again until it succeeds, or until
// the new_handler decides to terminate.
- //
- // If allocation fails and there is no new_handler, we throw bad_alloc
- // (or return nullptr if exceptions are disabled).
void* p;
while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
std::new_handler nh = std::get_new_handler();
if (nh)
nh();
- else {
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- throw std::bad_alloc();
-# else
+ else
break;
-# endif
- }
}
return p;
}
+_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
+ void* p = operator_new_aligned_impl(size, alignment);
+# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ if (p == nullptr)
+ throw std::bad_alloc();
+# endif
+ return p;
+}
+
_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
void* p = nullptr;
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
diff --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp
index 71c98793cae4093..6c9990f063dde66 100644
--- a/libcxxabi/src/stdlib_new_delete.cpp
+++ b/libcxxabi/src/stdlib_new_delete.cpp
@@ -30,8 +30,7 @@
// in this shared library, so that they can be overridden by programs
// that define non-weak copies of the functions.
-_LIBCPP_WEAK
-void* operator new(std::size_t size) _THROW_BAD_ALLOC {
+static void* operator_new_impl(std::size_t size) noexcept {
if (size == 0)
size = 1;
void* p;
@@ -42,15 +41,21 @@ void* operator new(std::size_t size) _THROW_BAD_ALLOC {
if (nh)
nh();
else
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- throw std::bad_alloc();
-#else
break;
-#endif
}
return p;
}
+_LIBCPP_WEAK
+void* operator new(std::size_t size) _THROW_BAD_ALLOC {
+ void* p = operator_new_impl(size);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ if (p == nullptr)
+ throw std::bad_alloc();
+#endif
+ return p;
+}
+
_LIBCPP_WEAK
void* operator new(size_t size, const std::nothrow_t&) noexcept {
void* p = nullptr;
@@ -102,8 +107,7 @@ void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
-_LIBCPP_WEAK
-void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
+static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept {
if (size == 0)
size = 1;
if (static_cast<size_t>(alignment) < sizeof(void*))
@@ -112,25 +116,27 @@ void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLO
// Try allocating memory. If allocation fails and there is a new_handler,
// call it to try free up memory, and try again until it succeeds, or until
// the new_handler decides to terminate.
- //
- // If allocation fails and there is no new_handler, we throw bad_alloc
- // (or return nullptr if exceptions are disabled).
void* p;
while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
std::new_handler nh = std::get_new_handler();
if (nh)
nh();
- else {
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- throw std::bad_alloc();
-# else
+ else
break;
-# endif
- }
}
return p;
}
+_LIBCPP_WEAK
+void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
+ void* p = operator_new_aligned_impl(size, alignment);
+# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ if (p == nullptr)
+ throw std::bad_alloc();
+# endif
+ return p;
+}
+
_LIBCPP_WEAK
void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
void* p = nullptr;
More information about the libcxx-commits
mailing list