Skip to content

Commit d2182db

Browse files
EricWFtstellar
authored andcommitted
[🍒] Unconditionally lower std::string's alignment requirement from 16 to 8 (llvm#68925) (llvm#79480)
This change saves memory by providing the allocator more freedom to allocate the most efficient size class by dropping the alignment requirements for std::string's pointer from 16 to 8. This changes the output of std::string::max_size, which makes it ABI breaking. That said, the discussion concluded that we don't care about this ABI break. and would like this change enabled universally. The ABI break isn't one of layout or "class size", but rather the value of "max_size()" changes, which in turn changes whether `std::bad_alloc` or `std::length_error` is thrown for large allocations. This change is the child of PR llvm#68807, which enabled the change behind an ABI flag.
1 parent 4e1a93e commit d2182db

File tree

6 files changed

+17
-32
lines changed

6 files changed

+17
-32
lines changed

libcxx/docs/ReleaseNotes/18.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,10 @@ ABI Affecting Changes
275275
results in an ABI break, however in practice we expect uses of ``std::projected`` in ABI-sensitive places to be
276276
extremely rare. Any error resulting from this change should result in a link-time error.
277277

278-
- Under the unstable ABI, the internal alignment requirements for heap allocations
279-
inside ``std::string`` has decreased from 16 to 8. This saves memory since string requests fewer additional
280-
bytes than it did previously. However, this also changes the return value of ``std::string::max_size``
281-
and can cause code compiled against older libc++ versions but linked at runtime to a new version
282-
to throw a different exception when attempting allocations that are too large
278+
- The internal alignment requirements for heap allocations inside ``std::string`` has decreased from 16 to 8. This
279+
saves memory since string requests fewer additional bytes than it did previously. However, this also changes the
280+
return value of ``std::string::max_size`` and can cause code compiled against older libc++ versions but linked at
281+
runtime to a new version to throw a different exception when attempting allocations that are too large
283282
(``std::bad_alloc`` vs ``std::length_error``).
284283

285284
- The layout of some range adaptors that use the ``movable-box`` exposition-only type as an implementation

libcxx/include/__config

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,6 @@
174174
// The implementation moved to the header, but we still export the symbols from
175175
// the dylib for backwards compatibility.
176176
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
177-
// Save memory by providing the allocator more freedom to allocate the most
178-
// efficient size class by dropping the alignment requirements for std::string's
179-
// pointer from 16 to 8. This changes the output of std::string::max_size,
180-
// which makes it ABI breaking
181-
# define _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
182177
# elif _LIBCPP_ABI_VERSION == 1
183178
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
184179
// Enable compiling copies of now inline methods into the dylib to support

libcxx/include/string

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,12 +1937,7 @@ private:
19371937
return (__s + (__a - 1)) & ~(__a - 1);
19381938
}
19391939
enum {
1940-
__alignment =
1941-
#ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
1942-
8
1943-
#else
1944-
16
1945-
#endif
1940+
__alignment = 8
19461941
};
19471942
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
19481943
if (__s < __min_cap) {

libcxx/test/libcxx/strings/basic.string/string.capacity/allocation_size.pass.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.13|10.15|11.0}}
10+
911
// <string>
1012

1113
// This test demonstrates the smaller allocation sizes when the alignment
@@ -17,14 +19,8 @@
1719

1820
#include "test_macros.h"
1921

20-
// alignment of the string heap buffer is hardcoded to either 16 or 8
21-
22-
const std::size_t alignment =
23-
#ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
24-
8;
25-
#else
26-
16;
27-
#endif
22+
// alignment of the string heap buffer is hardcoded to 8
23+
const std::size_t alignment = 8;
2824

2925
int main(int, char**) {
3026
std::string input_string;

libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,8 @@
1717

1818
#include "test_macros.h"
1919

20-
// alignment of the string heap buffer is hardcoded to 16
21-
22-
static const std::size_t alignment =
23-
#ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
24-
8;
25-
#else
26-
16;
27-
#endif
20+
// alignment of the string heap buffer is hardcoded to 8
21+
static const std::size_t alignment = 8;
2822

2923
template <class = int>
3024
TEST_CONSTEXPR_CXX20 void full_size() {

libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp

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

99
// UNSUPPORTED: no-exceptions
10+
11+
// After changing the alignment of the allocated pointer from 16 to 8, the exception thrown is no longer `bad_alloc`
12+
// but instead length_error on systems using new headers but older dylibs.
13+
//
14+
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.13|10.15|11.0}}
15+
1016
// <string>
1117

1218
// size_type max_size() const; // constexpr since C++20

0 commit comments

Comments
 (0)