8fe7214fe2
-- 406622c43f296eeedf00e0e9246acfb4ea6ecd5e by Abseil Team <absl-team@google.com>: Avoid the compiler reloading __is_long() on string_view(const string&) The underlying cause is that the compiler assume a scenario where string_view is created with placement new into memory occupied by the input, so the store to 'ptr' can affect the value / result of size(); i.e., __is_long() reloads the __size value). Example code: string_view1 demonstrates the problem, string_view2 DTRT. === string_view1 struct string_view1 { string_view1(const char* ptr, size_t n) : ptr(ptr), n(n) {} string_view1(const std::string& s) : ptr(s.data()), n(s.length()) {} const char* ptr; size_t n; }; struct S1 { S1(const std::string& s); string_view1 sv; }; S1::S1(const std::string& s) : sv(s) {} S1::S1 test byte ptr [rsi], 1 je .LBB0_1 mov rax, qword ptr [rsi + 16] mov qword ptr [rdi], rax movzx eax, byte ptr [rsi] test al, 1 jne .LBB0_5 .LBB0_4: shr rax mov qword ptr [rdi + 8], rax ret .LBB0_1: lea rax, [rsi + 1] mov qword ptr [rdi], rax movzx eax, byte ptr [rsi] test al, 1 je .LBB0_4 .LBB0_5: mov rax, qword ptr [rsi + 8] mov qword ptr [rdi + 8], rax ret === string_view2 struct string_view2 { string_view2(const char* ptr, size_t n) : ptr(ptr), n(n) {} string_view2(const std::string& s) : string_view2(s.data(), s.size()) {} const char* ptr; size_t n; }; struct S2 { S2(const std::string& s); string_view2 sv; }; S2::S2(const std::string& s) : sv(s) {} S2::S2 movzx eax, byte ptr [rsi] test al, 1 je .LBB1_1 mov rax, qword ptr [rsi + 8] mov rsi, qword ptr [rsi + 16] mov qword ptr [rdi], rsi mov qword ptr [rdi + 8], rax ret .LBB1_1: add rsi, 1 shr rax mov qword ptr [rdi], rsi mov qword ptr [rdi + 8], rax ret PiperOrigin-RevId: 272096771 GitOrigin-RevId: 406622c43f296eeedf00e0e9246acfb4ea6ecd5e Change-Id: I70173a2db68cd9b597fff1c09e00198c632cfe95 |
||
---|---|---|
.. | ||
internal | ||
testdata | ||
ascii.cc | ||
ascii.h | ||
ascii_benchmark.cc | ||
ascii_test.cc | ||
BUILD.bazel | ||
charconv.cc | ||
charconv.h | ||
charconv_benchmark.cc | ||
charconv_test.cc | ||
CMakeLists.txt | ||
escaping.cc | ||
escaping.h | ||
escaping_benchmark.cc | ||
escaping_test.cc | ||
match.cc | ||
match.h | ||
match_test.cc | ||
numbers.cc | ||
numbers.h | ||
numbers_benchmark.cc | ||
numbers_test.cc | ||
str_cat.cc | ||
str_cat.h | ||
str_cat_benchmark.cc | ||
str_cat_test.cc | ||
str_format.h | ||
str_format_test.cc | ||
str_join.h | ||
str_join_benchmark.cc | ||
str_join_test.cc | ||
str_replace.cc | ||
str_replace.h | ||
str_replace_benchmark.cc | ||
str_replace_test.cc | ||
str_split.cc | ||
str_split.h | ||
str_split_benchmark.cc | ||
str_split_test.cc | ||
string_view.cc | ||
string_view.h | ||
string_view_benchmark.cc | ||
string_view_test.cc | ||
strip.h | ||
strip_test.cc | ||
substitute.cc | ||
substitute.h | ||
substitute_test.cc |