Implement P0035R4 -- Add C++17 aligned allocation functions
Summary:
This patch implements the library side of P0035R4. The implementation is thanks to @rsmith.
In addition to the C++17 implementation, the library implementation can be explicitly turned on using `-faligned-allocation` in all dialects.
Reviewers: mclow.lists, rsmith
Subscribers: rsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D25591
llvm-svn: 284206
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 0ae4f23fdcd8a278c58ea3ae2f062220763bcb66
diff --git a/src/new.cpp b/src/new.cpp
index d5db461..8e002d4 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -39,10 +39,7 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void *
-operator new(std::size_t size)
-#if !__has_feature(cxx_noexcept)
- throw(std::bad_alloc)
-#endif
+operator new(std::size_t size) _THROW_BAD_ALLOC
{
if (size == 0)
size = 1;
@@ -65,6 +62,34 @@
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void *
+operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
+{
+ if (size == 0)
+ size = 1;
+ if (static_cast<size_t>(alignment) < sizeof(void*))
+ alignment = std::align_val_t(sizeof(void*));
+ void* p;
+ while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
+ {
+ // If posix_memalign fails and there is a new_handler,
+ // call it to try free up memory.
+ std::new_handler nh = std::get_new_handler();
+ if (nh)
+ nh();
+ else {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ p = nullptr; // posix_memalign doesn't initialize 'p' on failure
+ break;
+#endif
+ }
+ }
+ return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void*
operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
{
@@ -85,16 +110,39 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void*
-operator new[](size_t size)
-#if !__has_feature(cxx_noexcept)
- throw(std::bad_alloc)
-#endif
+operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ void* p = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ p = ::operator new(size, alignment);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+ return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
+operator new[](size_t size) _THROW_BAD_ALLOC
{
return ::operator new(size);
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void*
+operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
+{
+ return ::operator new(size, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
{
void* p = 0;
@@ -113,6 +161,25 @@
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
+operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ void* p = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ p = ::operator new[](size, alignment);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+ return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
operator delete(void* ptr) _NOEXCEPT
{
@@ -122,6 +189,14 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete(void* ptr, std::align_val_t) _NOEXCEPT
+{
+ if (ptr)
+ ::free(ptr);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
{
::operator delete(ptr);
@@ -129,6 +204,13 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete(void* ptr, size_t) _NOEXCEPT
{
::operator delete(ptr);
@@ -136,6 +218,13 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
+{
+ ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete[] (void* ptr) _NOEXCEPT
{
::operator delete(ptr);
@@ -143,6 +232,13 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
+{
+ ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
{
::operator delete[](ptr);
@@ -150,11 +246,25 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
+operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+ ::operator delete[](ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
operator delete[] (void* ptr, size_t) _NOEXCEPT
{
::operator delete[](ptr);
}
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
+operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
+{
+ ::operator delete[](ptr, alignment);
+}
+
#endif // !__GLIBCXX__
namespace std