Skip to content

Commit 3608043

Browse files
committed
[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
1 parent 2e31530 commit 3608043

File tree

10 files changed

+81
-42
lines changed

10 files changed

+81
-42
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ set(files
414414
__mbstate_t.h
415415
__memory/addressof.h
416416
__memory/align.h
417+
__memory/aligned_alloc.h
417418
__memory/allocate_at_least.h
418419
__memory/allocation_guard.h
419420
__memory/allocator.h
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H
10+
#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H
11+
12+
#include <__config>
13+
#include <cstddef>
14+
#include <cstdlib>
15+
16+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17+
# pragma GCC system_header
18+
#endif
19+
20+
_LIBCPP_BEGIN_NAMESPACE_STD
21+
22+
#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
23+
24+
// Low-level helpers to call the aligned allocation and deallocation functions
25+
// on the target platform. This is used to implement libc++'s own memory
26+
// allocation routines -- if you need to allocate memory inside the library,
27+
// chances are that you want to use `__libcpp_allocate` instead.
28+
//
29+
// Returns the allocated memory, or `nullptr` on failure.
30+
inline _LIBCPP_HIDE_FROM_ABI
31+
void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
32+
# if defined(_LIBCPP_MSVCRT_LIKE)
33+
return ::_aligned_malloc(__size, __alignment);
34+
# elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
35+
// aligned_alloc() requires that __size is a multiple of __alignment,
36+
// but for C++ [new.delete.general], only states "if the value of an
37+
// alignment argument passed to any of these functions is not a valid
38+
// alignment value, the behavior is undefined".
39+
// To handle calls such as ::operator new(1, std::align_val_t(128)), we
40+
// round __size up to the next multiple of __alignment.
41+
size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
42+
// Rounding up could have wrapped around to zero, so we have to add another
43+
// max() ternary to the actual call site to avoid succeeded in that case.
44+
return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
45+
# else
46+
void* __result = nullptr;
47+
(void)::posix_memalign(&__result, __alignment, __size);
48+
// If posix_memalign fails, __result is unmodified so we still return `nullptr`.
49+
return __result;
50+
# endif
51+
}
52+
53+
inline _LIBCPP_HIDE_FROM_ABI
54+
void __libcpp_aligned_free(void* __ptr) {
55+
#if defined(_LIBCPP_MSVCRT_LIKE)
56+
::_aligned_free(__ptr);
57+
#else
58+
::free(__ptr);
59+
#endif
60+
}
61+
62+
#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
63+
64+
_LIBCPP_END_NAMESPACE_STD
65+
66+
#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H

libcxx/include/module.modulemap.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,7 @@ module std [system] {
10611061
module __memory {
10621062
module addressof { private header "__memory/addressof.h" }
10631063
module align { private header "__memory/align.h" }
1064+
module aligned_alloc { private header "__memory/aligned_alloc.h" }
10641065
module allocate_at_least { private header "__memory/allocate_at_least.h" }
10651066
module allocation_guard { private header "__memory/allocation_guard.h" }
10661067
module allocator { private header "__memory/allocator.h" }

libcxx/include/new

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -332,46 +332,6 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
332332
#endif
333333
}
334334

335-
#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
336-
// Low-level helpers to call the aligned allocation and deallocation functions
337-
// on the target platform. This is used to implement libc++'s own memory
338-
// allocation routines -- if you need to allocate memory inside the library,
339-
// chances are that you want to use `__libcpp_allocate` instead.
340-
//
341-
// Returns the allocated memory, or `nullptr` on failure.
342-
inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
343-
# if defined(_LIBCPP_MSVCRT_LIKE)
344-
return ::_aligned_malloc(__size, __alignment);
345-
# elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
346-
// aligned_alloc() requires that __size is a multiple of __alignment,
347-
// but for C++ [new.delete.general], only states "if the value of an
348-
// alignment argument passed to any of these functions is not a valid
349-
// alignment value, the behavior is undefined".
350-
// To handle calls such as ::operator new(1, std::align_val_t(128)), we
351-
// round __size up to the next multiple of __alignment.
352-
size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
353-
// Rounding up could have wrapped around to zero, so we have to add another
354-
// max() ternary to the actual call site to avoid succeeded in that case.
355-
return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
356-
# else
357-
void* __result = nullptr;
358-
(void)::posix_memalign(&__result, __alignment, __size);
359-
// If posix_memalign fails, __result is unmodified so we still return `nullptr`.
360-
return __result;
361-
# endif
362-
}
363-
364-
inline _LIBCPP_INLINE_VISIBILITY
365-
void __libcpp_aligned_free(void* __ptr) {
366-
#if defined(_LIBCPP_MSVCRT_LIKE)
367-
::_aligned_free(__ptr);
368-
#else
369-
::free(__ptr);
370-
#endif
371-
}
372-
#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
373-
374-
375335
template <class _Tp>
376336
_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
377337
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT

libcxx/src/new.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include <__memory/aligned_alloc.h>
910
#include <new>
1011
#include <stdlib.h>
1112

libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242

4343
#include "test_macros.h"
4444

45+
TEST_DIAGNOSTIC_PUSH
46+
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
47+
#include <__memory/aligned_alloc.h>
48+
TEST_DIAGNOSTIC_POP
49+
4550
struct alloc_stats {
4651
alloc_stats() { reset(); }
4752

libcxx/test/libcxx/private_headers.verify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ END-SCRIPT
445445
#include <__mbstate_t.h> // expected-error@*:* {{use of private header from outside its module: '__mbstate_t.h'}}
446446
#include <__memory/addressof.h> // expected-error@*:* {{use of private header from outside its module: '__memory/addressof.h'}}
447447
#include <__memory/align.h> // expected-error@*:* {{use of private header from outside its module: '__memory/align.h'}}
448+
#include <__memory/aligned_alloc.h> // expected-error@*:* {{use of private header from outside its module: '__memory/aligned_alloc.h'}}
448449
#include <__memory/allocate_at_least.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocate_at_least.h'}}
449450
#include <__memory/allocation_guard.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocation_guard.h'}}
450451
#include <__memory/allocator.h> // expected-error@*:* {{use of private header from outside its module: '__memory/allocator.h'}}

libcxxabi/src/fallback_malloc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
#endif
1616
#endif
1717

18+
#include <__memory/aligned_alloc.h>
1819
#include <assert.h>
1920
#include <stdlib.h> // for malloc, calloc, free
2021
#include <string.h> // for memset
21-
#include <new> // for std::__libcpp_aligned_{alloc,free}
2222

2323
// A small, simple heap manager based (loosely) on
2424
// the startup heap manager from FreeBSD, optimized for space.

libcxxabi/src/stdlib_new_delete.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
//===----------------------------------------------------------------------===//
1010

1111
#include "__cxxabi_config.h"
12-
#include <new>
12+
#include <__memory/aligned_alloc.h>
1313
#include <cstdlib>
14+
#include <new>
1415

1516
#if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK)
1617
#error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \

libcxxabi/test/test_fallback_malloc.pass.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@
2424

2525
typedef std::deque<void *> container;
2626

27+
TEST_DIAGNOSTIC_PUSH
28+
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
2729
// #define DEBUG_FALLBACK_MALLOC
2830
#define INSTRUMENT_FALLBACK_MALLOC
2931
#include "../src/fallback_malloc.cpp"
32+
TEST_DIAGNOSTIC_POP
3033

3134
void assertAlignment(void* ptr) { assert(reinterpret_cast<size_t>(ptr) % alignof(FallbackMaxAlignType) == 0); }
3235

0 commit comments

Comments
 (0)