Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🍒] Unconditionally lower std::string's alignment requirement from 16 to 8 (#68925) #79480

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions libcxx/docs/ReleaseNotes/18.rst
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,10 @@ ABI Affecting Changes
results in an ABI break, however in practice we expect uses of ``std::projected`` in ABI-sensitive places to be
extremely rare. Any error resulting from this change should result in a link-time error.

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

- The layout of some range adaptors that use the ``movable-box`` exposition-only type as an implementation
Expand Down
5 changes: 0 additions & 5 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,6 @@
// The implementation moved to the header, but we still export the symbols from
// the dylib for backwards compatibility.
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
// Save 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
# define _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
# elif _LIBCPP_ABI_VERSION == 1
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
// Enable compiling copies of now inline methods into the dylib to support
Expand Down
7 changes: 1 addition & 6 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -1937,12 +1937,7 @@ private:
return (__s + (__a - 1)) & ~(__a - 1);
}
enum {
__alignment =
#ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
8
#else
16
#endif
__alignment = 8
};
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
if (__s < __min_cap) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.13|10.15|11.0}}

// <string>

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

#include "test_macros.h"

// alignment of the string heap buffer is hardcoded to either 16 or 8

const std::size_t alignment =
#ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
8;
#else
16;
#endif
// alignment of the string heap buffer is hardcoded to 8
const std::size_t alignment = 8;

int main(int, char**) {
std::string input_string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,8 @@

#include "test_macros.h"

// alignment of the string heap buffer is hardcoded to 16

static const std::size_t alignment =
#ifdef _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
8;
#else
16;
#endif
// 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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: no-exceptions

// After changing the alignment of the allocated pointer from 16 to 8, the exception thrown is no longer `bad_alloc`
// but instead length_error on systems using new headers but older dylibs.
//
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.13|10.15|11.0}}

// <string>

// size_type max_size() const; // constexpr since C++20
Expand Down
Loading