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

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@284206 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2016-10-14 06:46:30 +00:00
parent 4289b6ea05
commit 9acbffa370
17 changed files with 1135 additions and 22 deletions

View File

@@ -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;
@@ -64,6 +61,34 @@ operator new(std::size_t size)
return p;
}
_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,14 +110,37 @@ operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
_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
@@ -112,6 +160,25 @@ operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
return p;
}
_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
@@ -120,6 +187,14 @@ operator delete(void* ptr) _NOEXCEPT
::free(ptr);
}
_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
@@ -127,6 +202,13 @@ operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
::operator delete(ptr);
}
_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
@@ -134,6 +216,13 @@ 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);
}
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
operator delete[] (void* ptr) _NOEXCEPT
@@ -141,6 +230,13 @@ operator delete[] (void* ptr) _NOEXCEPT
::operator delete(ptr);
}
_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
@@ -148,6 +244,13 @@ operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
::operator delete[](ptr);
}
_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
@@ -155,6 +258,13 @@ 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