diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1872,7 +1872,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __align_it(size_type __s) _NOEXCEPT {return (__s + (__a-1)) & ~(__a-1);} - enum {__alignment = 16}; + enum {__alignment = 8}; static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT { @@ -2318,10 +2318,20 @@ size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap - 1) __throw_length_error(); - pointer __old_p = __get_pointer(); - size_type __cap = __old_cap < __ms / 2 - __alignment ? - __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : - __ms - 1; + pointer __old_p; + size_type __cap; + if (__is_long()) { + __old_p = __get_long_pointer(); + __cap = __old_cap < __ms / 2 - __alignment + ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) + : __ms - 1; + } else { + // On first allocation SSO -> long, do not apply a minimum doubling + // of capacity/ This results in a minimum allocation size of 48 and we + // only need to guarantee amortized growth on subsequent growth. + __old_p = __get_short_pointer(); + __cap = __recommend(__old_cap + __delta_cap); + } auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); pointer __p = __allocation.ptr; __begin_lifetime(__p, __allocation.count); @@ -2359,10 +2369,20 @@ size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap) __throw_length_error(); - pointer __old_p = __get_pointer(); - size_type __cap = __old_cap < __ms / 2 - __alignment ? - __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : - __ms - 1; + pointer __old_p; + size_type __cap; + if (__is_long()) { + __old_p = __get_long_pointer(); + __cap = __old_cap < __ms / 2 - __alignment + ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) + : __ms - 1; + } else { + // On first allocation SSO -> long, do not apply a minimum doubling + // of capacity/ This results in a minimum allocation size of 48 and we + // only need to guarantee amortized growth on subsequent growth. + __old_p = __get_short_pointer(); + __cap = __recommend(__old_cap + __delta_cap); + } auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); pointer __p = __allocation.ptr; __begin_lifetime(__p, __allocation.count); 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 --- 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 @@ -13,12 +13,9 @@ #include #include #include -#include -#include "test_macros.h" - -// alignment of the string heap buffer is hardcoded to 16 -static const std::size_t alignment = 16; +// alignment of the string heap buffer is hard coded to 8. +static const std::size_t alignment = 8; template TEST_CONSTEXPR_CXX20 void full_size() {