File tree Expand file tree Collapse file tree 5 files changed +72
-2
lines changed
test/libcxx/strings/basic.string/string.capacity Expand file tree Collapse file tree 5 files changed +72
-2
lines changed Original file line number Diff line number Diff line change @@ -133,6 +133,13 @@ ABI Affecting Changes
133133 results in an ABI break, however in practice we expect uses of ``std::projected `` in ABI-sensitive places to be
134134 extremely rare. Any error resulting from this change should result in a link-time error.
135135
136+ - Under the unstable ABI, the internal alignment requirements for heap allocations
137+ inside ``std::string `` has decreased from 16 to 8 This save memory since string requests fewer additional
138+ bytes than it did previously. However, this also changes the return value of ``std::string::max_size ``
139+ and can cause code compiled against older libc++ versions but linked at runtime to a new version
140+ to throw a different exception when attempting allocations that are too large
141+ (``std::bad_alloc `` vs ``std::length_error ``).
142+
136143Build System Changes
137144--------------------
138145
Original file line number Diff line number Diff line change 167167// The implementation moved to the header, but we still export the symbols from
168168// the dylib for backwards compatibility.
169169# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
170+ // Save memory by providing the allocator more freedom to allocate the most
171+ // efficient size class by dropping the alignment requirements for std::string's
172+ // pointer from 16 to 8. This changes the output of std::string::max_size,
173+ // which makes it ABI breaking
174+ # define _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
170175# elif _LIBCPP_ABI_VERSION == 1
171176# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
172177// Enable compiling copies of now inline methods into the dylib to support
Original file line number Diff line number Diff line change @@ -1851,7 +1851,14 @@ private:
18511851 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18521852 size_type __align_it (size_type __s) _NOEXCEPT
18531853 {return (__s + (__a-1 )) & ~(__a-1 );}
1854- enum {__alignment = 16 };
1854+ enum {
1855+ __alignment =
1856+ #ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
1857+ 8
1858+ #else
1859+ 16
1860+ #endif
1861+ };
18551862 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18561863 size_type __recommend (size_type __s) _NOEXCEPT
18571864 {
Original file line number Diff line number Diff line change 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+ // <string>
10+
11+ // This test demonstrates the smaller allocation sizes when the alignment
12+ // requirements of std::string are dropped from 16 to 8.
13+ #include < algorithm>
14+ #include < cassert>
15+ #include < cstddef>
16+ #include < string>
17+
18+ #include " test_macros.h"
19+
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
28+
29+ int main (int , char **) {
30+ std::string input_string;
31+ input_string.resize (64 , ' a' );
32+
33+ // Call a constructor which selects its size using __recommend.
34+ std::string test_string (input_string.data ());
35+ const std::size_t expected_align8_size = 71 ;
36+
37+ // Demonstrate the lesser capacity/allocation size when the alignment requirement is 8.
38+ if (alignment == 8 ) {
39+ assert (test_string.capacity () == expected_align8_size);
40+ } else {
41+ assert (test_string.capacity () == expected_align8_size + 8 );
42+ }
43+
44+ return 0 ;
45+ }
Original file line number Diff line number Diff line change 1818#include " test_macros.h"
1919
2020// alignment of the string heap buffer is hardcoded to 16
21- static const std::size_t alignment = 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
2228
2329template <class = int >
2430TEST_CONSTEXPR_CXX20 void full_size () {
You can’t perform that action at this time.
0 commit comments