Skip to content

Commit efe2fa3

Browse files
committed
Unconditionally lower std::string's alignment requirement from 16 to 8.
As requested in llvm#68807
1 parent 64d78d8 commit efe2fa3

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

libcxx/docs/ReleaseNotes/18.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ 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+
- The internal alignment requirements for heap allocations inside std::string has decreased from 16 to 8.
137+
This save memory since string requests fewer additional bytes than it did previously. However, this
138+
also changes the return value of std::string::max_length and can cause code compiled against older
139+
libc++ versions but linked at runtime to a new version to thrown a different exception
140+
when attempting allocations that are too large (std::bad_alloc vs std::length_error).
141+
136142
Build System Changes
137143
--------------------
138144

libcxx/include/string

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,7 @@ 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 { __alignment = 8 };
18551855
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
18561856
size_type __recommend(size_type __s) _NOEXCEPT
18571857
{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
14+
#include <algorithm>
15+
#include <cassert>
16+
#include <cstddef>
17+
#include <string>
18+
19+
#include "test_macros.h"
20+
21+
int main(int, char**) {
22+
std::string input_string;
23+
input_string.resize(64, 'a');
24+
25+
// Call a constructor which selects its size using __recommend.
26+
std::string test_string(input_string.data());
27+
constexpr std::size_t expected_align8_size = 71;
28+
// Previously, when the alignment used to be 16 bytes, the expected
29+
// capacity was 79.
30+
assert(test_string.capacity() == expected_align8_size);
31+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
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 = 8;
2223

2324
template <class = int>
2425
TEST_CONSTEXPR_CXX20 void full_size() {

0 commit comments

Comments
 (0)