[libcxx-commits] [libcxx] [libc++] Base string's alignment on __STDCPP_DEFAULT_NEW_ALIGNMENT__ (PR #171785)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jan 28 07:38:38 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Nikolas Klauser (philnik777)
<details>
<summary>Changes</summary>
This allows users to influence how much we overalign `string`s allocations and tune it to the new/delete implementation via `-fnew-alignment`. If we don't have `__STDCPP_DEFAULT_NEW_ALGINMENT__` or we're not using `std::allocator`, we default to an alignment of `sizeof(void*)`.
---
Full diff: https://github.com/llvm/llvm-project/pull/171785.diff
5 Files Affected:
- (modified) libcxx/include/string (+9-1)
- (removed) libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp (-37)
- (removed) libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp (-117)
- (modified) libcxx/test/libcxx/strings/basic.string/string.capacity/allocation_size.pass.cpp (+5-2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp (+5-2)
``````````diff
diff --git a/libcxx/include/string b/libcxx/include/string
index c4bf970e55004..531185da2c4cf 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2364,7 +2364,15 @@ private:
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __align_it(size_type __s) _NOEXCEPT {
return (__s + (__a - 1)) & ~(__a - 1);
}
- enum { __alignment = 8 };
+
+# ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+ static inline const size_t
+ __alignment = __is_std_allocator_v<allocator_type> && __STDCPP_DEFAULT_NEW_ALIGNMENT__ > sizeof(void*)
+ ? __STDCPP_DEFAULT_NEW_ALIGNMENT__
+ : sizeof(void*);
+# else
+ static inline const size_t __alignment = sizeof(void*);
+# endif
// This makes sure that we're using a capacity with some extra alignment, since allocators almost always over-align
// the allocations anyways, improving memory usage. More importantly, this ensures that the lowest bit is never set
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp
deleted file mode 100644
index 77da29225957b..0000000000000
--- a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <string>
-
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <string>
-
-#include "test_macros.h"
-
-// alignment of the string heap buffer is hardcoded to 8
-const std::size_t alignment = 8;
-
-int main(int, char**) {
- std::string input_string;
- input_string.resize(64, 'a');
-
- // Call a constructor which selects its size using __recommend.
- std::string test_string(input_string.data());
- const std::size_t expected_align8_size = 71;
-
- // Demonstrate the lesser capacity/allocation size when the alignment requirement is 8.
- if (alignment == 8) {
- assert(test_string.capacity() == expected_align8_size);
- } else {
- assert(test_string.capacity() == expected_align8_size + 8);
- }
-
- return 0;
-}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
deleted file mode 100644
index 73825ef4845f2..0000000000000
--- a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <string>
-
-// This test ensures that the correct max_size() is returned depending on the platform.
-
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <string>
-
-#include "test_macros.h"
-
-// alignment of the string heap buffer is hardcoded to 8
-static const std::size_t alignment = 8;
-
-template <class = int>
-TEST_CONSTEXPR_CXX20 void full_size() {
- std::string str;
- assert(str.max_size() == std::numeric_limits<std::size_t>::max() - alignment - 1);
-
-#ifndef TEST_HAS_NO_CHAR8_T
- std::u8string u8str;
- assert(u8str.max_size() == std::numeric_limits<std::size_t>::max() - alignment - 1);
-#endif
-
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- std::wstring wstr;
- assert(wstr.max_size() ==
- ((std::numeric_limits<std::size_t>::max() / sizeof(wchar_t) - alignment) & ~std::size_t(1)) - 1);
-#endif
-
- std::u16string u16str;
- std::u32string u32str;
- assert(u16str.max_size() == ((std::numeric_limits<std::size_t>::max() / 2 - alignment) & ~std::size_t(1)) - 1);
- assert(u32str.max_size() == ((std::numeric_limits<std::size_t>::max() / 4 - alignment) & ~std::size_t(1)) - 1);
-}
-
-template <class = int>
-TEST_CONSTEXPR_CXX20 void half_size() {
- std::string str;
- assert(str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment - 1);
-
-#ifndef TEST_HAS_NO_CHAR8_T
- std::u8string u8str;
- assert(u8str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment - 1);
-#endif
-
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- std::wstring wstr;
- assert(wstr.max_size() ==
- std::numeric_limits<std::size_t>::max() / std::max<size_t>(2ul, sizeof(wchar_t)) - alignment - 1);
-#endif
-
- std::u16string u16str;
- std::u32string u32str;
- assert(u16str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment - 1);
- assert(u32str.max_size() == std::numeric_limits<std::size_t>::max() / 4 - alignment - 1);
-}
-
-TEST_CONSTEXPR_CXX20 bool test() {
-#if _LIBCPP_ABI_VERSION == 1
-
-# if defined(__x86_64__) || defined(__i386__)
- full_size();
-# elif defined(__APPLE__) && defined(__aarch64__)
- half_size();
-# elif defined(__arm__) || defined(__aarch64__)
-# ifdef __BIG_ENDIAN__
- half_size();
-# else
- full_size();
-# endif
-# elif defined(__powerpc__) || defined(__powerpc64__)
-# ifdef __BIG_ENDIAN__
- half_size();
-# else
- full_size();
-# endif
-# elif defined(__sparc64__)
- half_size();
-# elif defined(__riscv)
- full_size();
-# elif defined(_WIN32)
- full_size();
-# else
-# error "Your target system seems to be unsupported."
-# endif
-
-#else
-
-# if defined(__arm__) || defined(__aarch64__)
-# ifdef __BIG_ENDIAN__
- full_size();
-# else
- half_size();
-# endif
-# else
- half_size();
-# endif
-
-#endif
-
- return true;
-}
-
-int main(int, char**) {
- test();
-
- return 0;
-}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.capacity/allocation_size.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.capacity/allocation_size.pass.cpp
index 77da29225957b..367a58897cec0 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.capacity/allocation_size.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.capacity/allocation_size.pass.cpp
@@ -15,8 +15,11 @@
#include "test_macros.h"
-// alignment of the string heap buffer is hardcoded to 8
-const std::size_t alignment = 8;
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+static const std::size_t alignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
+#else
+static const std::size_t alginment = 8;
+#endif
int main(int, char**) {
std::string input_string;
diff --git a/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp
index 6bfcb5d4bfcd8..ea4520031475b 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -17,8 +17,11 @@
#include "test_macros.h"
-// alignment of the string heap buffer is hardcoded to 8
-static const std::size_t alignment = 8;
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+static const std::size_t alignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
+#else
+static const std::size_t alginment = 8;
+#endif
template <class = int>
TEST_CONSTEXPR_CXX20 void full_size() {
``````````
</details>
https://github.com/llvm/llvm-project/pull/171785
More information about the libcxx-commits
mailing list