--
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
| Name |
Last commit
|
Last Update |
|---|---|---|
| .. | ||
| internal | Loading commit data... | |
| testdata | Loading commit data... | |
| BUILD.bazel | Loading commit data... | |
| CMakeLists.txt | Loading commit data... | |
| ascii.cc | Loading commit data... | |
| ascii.h | Loading commit data... | |
| ascii_benchmark.cc | Loading commit data... | |
| ascii_test.cc | Loading commit data... | |
| charconv.cc | Loading commit data... | |
| charconv.h | Loading commit data... | |
| charconv_benchmark.cc | Loading commit data... | |
| charconv_test.cc | Loading commit data... | |
| escaping.cc | Loading commit data... | |
| escaping.h | Loading commit data... | |
| escaping_benchmark.cc | Loading commit data... | |
| escaping_test.cc | Loading commit data... | |
| match.cc | Loading commit data... | |
| match.h | Loading commit data... | |
| match_test.cc | Loading commit data... | |
| numbers.cc | Loading commit data... | |
| numbers.h | Loading commit data... | |
| numbers_benchmark.cc | Loading commit data... | |
| numbers_test.cc | Loading commit data... | |
| str_cat.cc | Loading commit data... | |
| str_cat.h | Loading commit data... | |
| str_cat_benchmark.cc | Loading commit data... | |
| str_cat_test.cc | Loading commit data... | |
| str_format.h | Loading commit data... | |
| str_format_test.cc | Loading commit data... | |
| str_join.h | Loading commit data... | |
| str_join_benchmark.cc | Loading commit data... | |
| str_join_test.cc | Loading commit data... | |
| str_replace.cc | Loading commit data... | |
| str_replace.h | Loading commit data... | |
| str_replace_benchmark.cc | Loading commit data... | |
| str_replace_test.cc | Loading commit data... | |
| str_split.cc | Loading commit data... | |
| str_split.h | Loading commit data... | |
| str_split_benchmark.cc | Loading commit data... | |
| str_split_test.cc | Loading commit data... | |
| string_view.cc | Loading commit data... | |
| string_view.h | Loading commit data... | |
| string_view_benchmark.cc | Loading commit data... | |
| string_view_test.cc | Loading commit data... | |
| strip.h | Loading commit data... | |
| strip_test.cc | Loading commit data... | |
| substitute.cc | Loading commit data... | |
| substitute.h | Loading commit data... | |
| substitute_test.cc | Loading commit data... |