Author: ericwf Date: Thu Mar 2 13:25:53 2017 New Revision: 296787 URL: http://llvm.org/viewvc/llvm-project?rev=296787&view=rev Log: [libc++abi] Update new/delete definitions to match libc++
Summary: Currently both libc++ and libc++abi provide definitions for new/delete. However libc++abi's definitions haven't been updated to include aligned new/delete or sized deallocation. I don't see any reason why libc++abi shouldn't provide these newer overloads. This patch copies libc++'s implementation of `new/delete` into libc++abi so that it's now up to date. After applying this patch I plan to fix a longstanding bug where both libc++ and libc++abi provide definitions for new/delete. Reviewers: mclow.lists, mehdi_amini, dexonsmith, danalbert, smeenai, rmaprath, jroelofs Reviewed By: mehdi_amini Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D30514 Modified: libcxxabi/trunk/src/stdlib_new_delete.cpp Modified: libcxxabi/trunk/src/stdlib_new_delete.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/stdlib_new_delete.cpp?rev=296787&r1=296786&r2=296787&view=diff ============================================================================== --- libcxxabi/trunk/src/stdlib_new_delete.cpp (original) +++ libcxxabi/trunk/src/stdlib_new_delete.cpp Thu Mar 2 13:25:53 2017 @@ -1,4 +1,4 @@ -//===------------------------ cxa_new_delete.cpp --------------------------===// +//===--------------------- stdlib_new_delete.cpp --------------------------===// // // The LLVM Compiler Infrastructure // @@ -10,33 +10,19 @@ //===----------------------------------------------------------------------===// #define _LIBCPP_BUILDING_NEW - +#define _LIBCPP_BUILDING_LIBRARY #include "__cxxabi_config.h" #include <new> #include <cstdlib> -#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) -#error _THROW_BAD_ALLOC and _NOEXCEPT libc++ macros must already be defined \ - by libc++. +#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) || !defined(_LIBCXXABI_WEAK) +#error The _THROW_BAD_ALLOC, _NOEXCEPT, and _LIBCXXABI_WEAK libc++ macros must \ + already be defined by libc++. #endif +// Implement all new and delete operators as weak definitions +// in this shared library, so that they can be overridden by programs +// that define non-weak copies of the functions. -/* -[new.delete.single] - -* Executes a loop: Within the loop, the function first attempts to allocate - the requested storage. Whether the attempt involves a call to the Standard C - library function malloc is unspecified. - -* Returns a pointer to the allocated storage if the attempt is successful. - Otherwise, if the current new_handler (18.6.2.5) is a null pointer value, - throws bad_alloc. - -* Otherwise, the function calls the current new_handler function (18.6.2.3). - If the called function returns, the loop repeats. - -* The loop terminates when an attempt to allocate the requested storage is - successful or when a called new_handler function does not return. -*/ _LIBCXXABI_WEAK void * operator new(std::size_t size) _THROW_BAD_ALLOC @@ -44,8 +30,10 @@ operator new(std::size_t size) _THROW_BA if (size == 0) size = 1; void* p; - while ((p = std::malloc(size)) == 0) + while ((p = ::malloc(size)) == 0) { + // If malloc 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(); @@ -59,18 +47,6 @@ operator new(std::size_t size) _THROW_BA return p; } -/* -Note: The relationships among these operators is both carefully considered -and standard in C++11. Please do not change them without fully understanding -the consequences of doing so. Reference: -http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2158.html -*/ -/* -[new.delete.single] - -Calls operator new(size). If the call returns normally, returns the result of -that call. Otherwise, returns a null pointer. -*/ _LIBCXXABI_WEAK void* operator new(size_t size, const std::nothrow_t&) _NOEXCEPT @@ -79,22 +55,17 @@ operator new(size_t size, const std::not #ifndef _LIBCXXABI_NO_EXCEPTIONS try { -#endif +#endif // _LIBCXXABI_NO_EXCEPTIONS p = ::operator new(size); #ifndef _LIBCXXABI_NO_EXCEPTIONS } catch (...) { } -#endif +#endif // _LIBCXXABI_NO_EXCEPTIONS return p; } -/* -[new.delete.array] - -Returns operator new(size). -*/ _LIBCXXABI_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC @@ -102,12 +73,6 @@ operator new[](size_t size) _THROW_BAD_A return ::operator new(size); } -/* -[new.delete.array] - -Calls operator new[](size). If the call returns normally, returns the result -of that call. Otherwise, returns a null pointer. -*/ _LIBCXXABI_WEAK void* operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT @@ -116,36 +81,25 @@ operator new[](size_t size, const std::n #ifndef _LIBCXXABI_NO_EXCEPTIONS try { -#endif +#endif // _LIBCXXABI_NO_EXCEPTIONS p = ::operator new[](size); #ifndef _LIBCXXABI_NO_EXCEPTIONS } catch (...) { } -#endif +#endif // _LIBCXXABI_NO_EXCEPTIONS return p; } -/* -[new.delete.single] - -If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the -earlier call to operator new. -*/ _LIBCXXABI_WEAK void operator delete(void* ptr) _NOEXCEPT { if (ptr) - std::free(ptr); + ::free(ptr); } -/* -[new.delete.single] - -calls operator delete(ptr) -*/ _LIBCXXABI_WEAK void operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT @@ -153,11 +107,13 @@ operator delete(void* ptr, const std::no ::operator delete(ptr); } -/* -[new.delete.array] +_LIBCXXABI_WEAK +void +operator delete(void* ptr, size_t) _NOEXCEPT +{ + ::operator delete(ptr); +} -Calls operator delete(ptr) -*/ _LIBCXXABI_WEAK void operator delete[] (void* ptr) _NOEXCEPT @@ -165,14 +121,144 @@ operator delete[] (void* ptr) _NOEXCEPT ::operator delete(ptr); } -/* -[new.delete.array] - -calls operator delete[](ptr) -*/ _LIBCXXABI_WEAK void operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT { ::operator delete[](ptr); } + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, size_t) _NOEXCEPT +{ + ::operator delete[](ptr); +} + +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + +_LIBCXXABI_WEAK +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; +#if defined(_LIBCPP_MSVCRT) + while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr) +#else + while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0) +#endif + { + // 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 _LIBCXXABI_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + p = nullptr; // posix_memalign doesn't initialize 'p' on failure + break; +#endif + } + } + return p; +} + +_LIBCXXABI_WEAK +void* +operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif // _LIBCXXABI_NO_EXCEPTIONS + p = ::operator new(size, alignment); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCXXABI_NO_EXCEPTIONS + return p; +} + +_LIBCXXABI_WEAK +void* +operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC +{ + return ::operator new(size, alignment); +} + +_LIBCXXABI_WEAK +void* +operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif // _LIBCXXABI_NO_EXCEPTIONS + p = ::operator new[](size, alignment); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCXXABI_NO_EXCEPTIONS + return p; +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, std::align_val_t) _NOEXCEPT +{ + if (ptr) +#if defined(_LIBCPP_MSVCRT) + ::_aligned_free(ptr); +#else + ::free(ptr); +#endif +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete[](ptr, alignment); +} + +#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits