diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -392,6 +392,7 @@ __mbstate_t.h __memory/addressof.h __memory/align.h + __memory/aligned_alloc.h __memory/allocate_at_least.h __memory/allocation_guard.h __memory/allocator.h diff --git a/libcxx/include/__memory/aligned_alloc.h b/libcxx/include/__memory/aligned_alloc.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__memory/aligned_alloc.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H +#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Low-level helpers to call the aligned allocation and deallocation functions +// on the target platform. This is used to implement libc++'s own memory +// allocation routines -- if you need to allocate memory inside the library, +// chances are that you want to use `__libcpp_allocate` instead. +// +// Returns the allocated memory, or `nullptr` on failure. +inline _LIBCPP_HIDE_FROM_ABI +void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) { +#if defined(_LIBCPP_MSVCRT_LIKE) + return ::_aligned_malloc(__size, __alignment); +#else + void* __result = nullptr; + (void)::posix_memalign(&__result, __alignment, __size); + // If posix_memalign fails, __result is unmodified so we still return `nullptr`. + return __result; +#endif +} + +inline _LIBCPP_HIDE_FROM_ABI +void __libcpp_aligned_free(void* __ptr) { +#if defined(_LIBCPP_MSVCRT_LIKE) + ::_aligned_free(__ptr); +#else + ::free(__ptr); +#endif +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1029,6 +1029,7 @@ module __memory { module addressof { private header "__memory/addressof.h" } module align { private header "__memory/align.h" } + module aligned_alloc { private header "__memory/aligned_alloc.h" } module allocate_at_least { private header "__memory/allocate_at_least.h" } module allocation_guard { private header "__memory/allocation_guard.h" } module allocator { private header "__memory/allocator.h" } diff --git a/libcxx/include/new b/libcxx/include/new --- a/libcxx/include/new +++ b/libcxx/include/new @@ -330,36 +330,6 @@ #endif } -#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) -// Low-level helpers to call the aligned allocation and deallocation functions -// on the target platform. This is used to implement libc++'s own memory -// allocation routines -- if you need to allocate memory inside the library, -// chances are that you want to use `__libcpp_allocate` instead. -// -// Returns the allocated memory, or `nullptr` on failure. -inline _LIBCPP_INLINE_VISIBILITY -void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) { -#if defined(_LIBCPP_MSVCRT_LIKE) - return ::_aligned_malloc(__size, __alignment); -#else - void* __result = nullptr; - (void)::posix_memalign(&__result, __alignment, __size); - // If posix_memalign fails, __result is unmodified so we still return `nullptr`. - return __result; -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY -void __libcpp_aligned_free(void* __ptr) { -#if defined(_LIBCPP_MSVCRT_LIKE) - ::_aligned_free(__ptr); -#else - ::free(__ptr); -#endif -} -#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION - - template _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -9,6 +9,10 @@ #include #include +#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# include <__memory/aligned_alloc.h> +#endif + #include "include/atomic_support.h" #if defined(_LIBCPP_ABI_MICROSOFT) diff --git a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp --- a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -40,6 +40,8 @@ #include #include +#include <__memory/aligned_alloc.h> + #include "test_macros.h" struct alloc_stats { diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp --- a/libcxx/test/libcxx/private_headers.verify.cpp +++ b/libcxx/test/libcxx/private_headers.verify.cpp @@ -423,6 +423,7 @@ #include <__mbstate_t.h> // expected-error@*:* {{use of private header from outside its module: '__mbstate_t.h'}} #include <__memory/addressof.h> // expected-error@*:* {{use of private header from outside its module: '__memory/addressof.h'}} #include <__memory/align.h> // expected-error@*:* {{use of private header from outside its module: '__memory/align.h'}} +#include <__memory/aligned_alloc.h> // expected-error@*:* {{use of private header from outside its module: '__memory/aligned_alloc.h'}} #include <__memory/allocate_at_least.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocate_at_least.h'}} #include <__memory/allocation_guard.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocation_guard.h'}} #include <__memory/allocator.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocator.h'}} diff --git a/libcxxabi/src/fallback_malloc.cpp b/libcxxabi/src/fallback_malloc.cpp --- a/libcxxabi/src/fallback_malloc.cpp +++ b/libcxxabi/src/fallback_malloc.cpp @@ -20,6 +20,10 @@ #include // for memset #include // for std::__libcpp_aligned_{alloc,free} +#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# include <__memory/aligned_alloc.h> +#endif + // A small, simple heap manager based (loosely) on // the startup heap manager from FreeBSD, optimized for space. // diff --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp --- a/libcxxabi/src/stdlib_new_delete.cpp +++ b/libcxxabi/src/stdlib_new_delete.cpp @@ -12,6 +12,10 @@ #include #include +#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# include <__memory/aligned_alloc.h> +#endif + #if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK) #error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \ already be defined by libc++.