Skip to content

Conversation

cjdb
Copy link
Contributor

@cjdb cjdb commented Aug 23, 2024

basic_string frequently calls basic_string_view(data(), size()), which accounts for ~15% of the observed overhead when hardening is enabled. This commit removes unnecessary checks when basic_string is known to already have valid data, by bypassing the public constructor, so that we eliminate that overhead.

This was originally #105441, but I somehow messed up and rebased an older version of LLVM onto ToT.

cjdb added 2 commits August 23, 2024 17:29
`basic_string` frequently calls `basic_string_view(data(), size())`,
which accounts for ~15% of the observed overhead when hardening is
enabled. This commit removes unnecessary checks when `basic_string` is
known to already have valid data, by bypassing the public constructor,
so that we eliminate that overhead.
@cjdb cjdb requested a review from a team as a code owner August 23, 2024 17:32
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 23, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 23, 2024

@llvm/pr-subscribers-libcxx

Author: Christopher Di Bella (cjdb)

Changes

basic_string frequently calls basic_string_view(data(), size()), which accounts for ~15% of the observed overhead when hardening is enabled. This commit removes unnecessary checks when basic_string is known to already have valid data, by bypassing the public constructor, so that we eliminate that overhead.

This was originally #105441, but I somehow messed up and rebased an older version of LLVM onto ToT.


Full diff: https://github.com/llvm/llvm-project/pull/105863.diff

2 Files Affected:

  • (modified) libcxx/include/string (+6-6)
  • (modified) libcxx/include/string_view (+4)
diff --git a/libcxx/include/string b/libcxx/include/string
index 6e93a6230cc2c0..cdc1afedbdf52f 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1213,7 +1213,7 @@ public:
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator __self_view() const _NOEXCEPT {
-    return __self_view(data(), size());
+    return __self_view(typename __self_view::__assume_valid(), data(), size());
   }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS basic_string&
@@ -1822,7 +1822,7 @@ public:
 
 #if _LIBCPP_STD_VER >= 20
   constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(__self_view __sv) const noexcept {
-    return __self_view(data(), size()).starts_with(__sv);
+    return __self_view(typename __self_view::__assume_valid(), data(), size()).starts_with(__sv);
   }
 
   constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
@@ -1834,7 +1834,7 @@ public:
   }
 
   constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(__self_view __sv) const noexcept {
-    return __self_view(data(), size()).ends_with(__sv);
+    return __self_view(typename __self_view::__assume_valid(), data(), size()).ends_with(__sv);
   }
 
   constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
@@ -1848,15 +1848,15 @@ public:
 
 #if _LIBCPP_STD_VER >= 23
   constexpr _LIBCPP_HIDE_FROM_ABI bool contains(__self_view __sv) const noexcept {
-    return __self_view(data(), size()).contains(__sv);
+    return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__sv);
   }
 
   constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {
-    return __self_view(data(), size()).contains(__c);
+    return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__c);
   }
 
   constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const {
-    return __self_view(data(), size()).contains(__s);
+    return __self_view(typename __self_view::__assume_valid(), data(), size()).contains(__s);
   }
 #endif
 
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 2a03ee99e9ab52..c81dbc9873b128 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -212,6 +212,7 @@ namespace std {
 #include <__functional/unary_function.h>
 #include <__fwd/ostream.h>
 #include <__fwd/string_view.h>
+#include <__fwd/string.h>
 #include <__iterator/bounded_iter.h>
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
@@ -689,6 +690,9 @@ private:
 
   const value_type* __data_;
   size_type __size_;
+
+  template <class, class, class>
+  friend class basic_string;
 };
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);
 

Copy link

github-actions bot commented Aug 23, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@cjdb cjdb force-pushed the string-hardening branch from 4f6f58f to c9bd38e Compare August 23, 2024 17:40
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ldionne ldionne merged commit e04d124 into llvm:main Aug 26, 2024
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants