[libcxx-commits] [libcxx] 3608043 - [libc++] Move the definition of aligned allocation helpers outside of <new>

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 26 11:41:30 PST 2023


Author: Louis Dionne
Date: 2023-01-26T14:41:13-05:00
New Revision: 36080434a8858c33f2af2382be748caed131385f

URL: https://github.com/llvm/llvm-project/commit/36080434a8858c33f2af2382be748caed131385f
DIFF: https://github.com/llvm/llvm-project/commit/36080434a8858c33f2af2382be748caed131385f.diff

LOG: [libc++] Move the definition of aligned allocation helpers outside of <new>

They are not needed in <new> -- in fact they are only needed in .cpp files.
Getting those out of the way makes the headers smaller and also makes it
easier to use the library on platforms where aligned allocation is not
available.

Differential Revision: https://reviews.llvm.org/D139231

Added: 
    libcxx/include/__memory/aligned_alloc.h

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/module.modulemap.in
    libcxx/include/new
    libcxx/src/new.cpp
    libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
    libcxx/test/libcxx/private_headers.verify.cpp
    libcxxabi/src/fallback_malloc.cpp
    libcxxabi/src/stdlib_new_delete.cpp
    libcxxabi/test/test_fallback_malloc.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a12aa1de1356..7b6ef9b59f84 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -414,6 +414,7 @@ set(files
   __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
index 000000000000..41520cffaa46
--- /dev/null
+++ b/libcxx/include/__memory/aligned_alloc.h
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstddef>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _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_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);
+#  elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
+    // aligned_alloc() requires that __size is a multiple of __alignment,
+    // but for C++ [new.delete.general], only states "if the value of an
+    // alignment argument passed to any of these functions is not a valid
+    // alignment value, the behavior is undefined".
+    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
+    // round __size up to the next multiple of __alignment.
+    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
+    // Rounding up could have wrapped around to zero, so we have to add another
+    // max() ternary to the actual call site to avoid succeeded in that case.
+    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
+#  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
+}
+
+#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 1f1d67dbb7fc..6bc64be69d60 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1061,6 +1061,7 @@ module std [system] {
     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
index 0c826f4a061c..97c8fc4e811b 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -332,46 +332,6 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
 #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);
-#  elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
-    // aligned_alloc() requires that __size is a multiple of __alignment,
-    // but for C++ [new.delete.general], only states "if the value of an
-    // alignment argument passed to any of these functions is not a valid
-    // alignment value, the behavior is undefined".
-    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
-    // round __size up to the next multiple of __alignment.
-    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
-    // Rounding up could have wrapped around to zero, so we have to add another
-    // max() ternary to the actual call site to avoid succeeded in that case.
-    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
-#  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 <class _Tp>
 _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
index 48d6f997fdda..f2ca698512ff 100644
--- a/libcxx/src/new.cpp
+++ b/libcxx/src/new.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <__memory/aligned_alloc.h>
 #include <new>
 #include <stdlib.h>
 

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
index 545032b096fd..28c964d4ccab 100644
--- a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
+++ b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -42,6 +42,11 @@
 
 #include "test_macros.h"
 
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__memory/aligned_alloc.h>
+TEST_DIAGNOSTIC_POP
+
 struct alloc_stats {
   alloc_stats() { reset(); }
 

diff  --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index ebbd50bcb35b..f629ce0162c3 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -445,6 +445,7 @@ END-SCRIPT
 #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
index 591efbefc8a5..f9fb1bc46302 100644
--- a/libcxxabi/src/fallback_malloc.cpp
+++ b/libcxxabi/src/fallback_malloc.cpp
@@ -15,10 +15,10 @@
 #endif
 #endif
 
+#include <__memory/aligned_alloc.h>
 #include <assert.h>
 #include <stdlib.h> // for malloc, calloc, free
 #include <string.h> // for memset
-#include <new> // for std::__libcpp_aligned_{alloc,free}
 
 //  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
index 4a664e15a50f..483b9f1e81e9 100644
--- a/libcxxabi/src/stdlib_new_delete.cpp
+++ b/libcxxabi/src/stdlib_new_delete.cpp
@@ -9,8 +9,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "__cxxabi_config.h"
-#include <new>
+#include <__memory/aligned_alloc.h>
 #include <cstdlib>
+#include <new>
 
 #if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK)
 #error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \

diff  --git a/libcxxabi/test/test_fallback_malloc.pass.cpp b/libcxxabi/test/test_fallback_malloc.pass.cpp
index d7decd9d7924..e7d22a57d2bc 100644
--- a/libcxxabi/test/test_fallback_malloc.pass.cpp
+++ b/libcxxabi/test/test_fallback_malloc.pass.cpp
@@ -24,9 +24,12 @@
 
 typedef std::deque<void *> container;
 
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
 // #define  DEBUG_FALLBACK_MALLOC
 #define INSTRUMENT_FALLBACK_MALLOC
 #include "../src/fallback_malloc.cpp"
+TEST_DIAGNOSTIC_POP
 
 void assertAlignment(void* ptr) { assert(reinterpret_cast<size_t>(ptr) % alignof(FallbackMaxAlignType) == 0); }
 


        


More information about the libcxx-commits mailing list