diff --git a/libcxx/include/__string b/libcxx/include/__string --- a/libcxx/include/__string +++ b/libcxx/include/__string @@ -140,15 +140,14 @@ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ - _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ - _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, std::allocator<_CharType> const&)) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \ _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1549,9 +1549,14 @@ inline void __init(size_type __n, value_type __c); - // Slow path for the (inlined) copy constructor. + // Slow path for the (inlined) copy constructor for 'long' strings. // Always externally instantiated and not inlined. // Asserts that __s is zero terminated. + // The main reason for this function to exist is because for unstable, we + // want to allow inlining of the copy constructor. However, we don't want + // to call the __init() functions as those are marked as inline which may + // result in over-aggressive inlining by the compiler, where our aim is + // to only inline the fast path code directly in the ctor. void __init_copy_ctor_external(const value_type* __s, size_type __sz); template @@ -1902,7 +1907,10 @@ void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( const value_type* __s, size_type __sz) { pointer __p; - if (__sz >= __min_cap) { + if (__sz < __min_cap) { + __p = __get_short_pointer(); + __set_short_size(__sz); + } else { if (__sz > max_size()) this->__throw_length_error(); size_t __cap = __recommend(__sz); @@ -1910,9 +1918,6 @@ __set_long_pointer(__p); __set_long_cap(__cap + 1); __set_long_size(__sz); - } else { - __p = __get_short_pointer(); - __set_short_size(__sz); } traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1); }