[libcxx-commits] [PATCH] D68623: Optimize and Fix move assignment operatorThis change optimizes the move assigment operator to more efficient / compact code, and fixes a bug.Move assignment optimization:- do not use the (epensive / branched) clear_and_shrink() method but...
Martijn Vels via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Oct 7 18:43:26 PDT 2019
mvels created this revision.
Herald added subscribers: libcxx-commits, christof.
Herald added a project: libc++.
...inline size = 0
- only zero existing instance in the presence of potential exceptrions
Result (std::string): more compact code, single branch
Bug fix:
- an exception thrown by the alloc move assigment would leave the current instance in a bad state with a non null pointer owned by the moved from instancem, not owned by the current alloc. Swap the alloc move and assignment of __r_r.first()
Given:
void MoveAssign(std::string* d, std::string* s) {
*d = std::move(*s);
}
Before:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
cmpb $0, 23(%rdi)
js .LBB2_2
movb $0, (%rbx)
movb $0, 23(%rbx)
jmp .LBB2_4
.LBB2_2:
movq (%rbx), %rax
movb $0, (%rax)
movq $0, 8(%rbx)
cmpb $0, 23(%rbx)
jns .LBB2_4
movq (%rbx), %rdi
callq operator delete(void*)
movq $0, 16(%rbx)
.LBB2_4:
movq 16(%r14), %rax
movq %rax, 16(%rbx)
movups (%r14), %xmm0
movups %xmm0, (%rbx)
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movq $0, 16(%r14)
addq $8, %rsp
popq %rbx
popq %r14
retq
After:
push r14
push rbx
push rax
mov rbx, rsi
mov r14, rdi
cmp byte ptr [rdi + 23], 0
jns .LBB2_2
mov rdi, qword ptr [r14]
call operator delete(void*)
.LBB2_2:
mov rax, qword ptr [rbx + 16]
mov qword ptr [r14 + 16], rax
movups xmm0, xmmword ptr [rbx]
movups xmmword ptr [r14], xmm0
mov byte ptr [rbx], 0
mov byte ptr [rbx + 23], 0
add rsp, 8
pop rbx
pop r14
ret
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D68623
Files:
libcxx/include/string
Index: libcxx/include/string
===================================================================
--- libcxx/include/string
+++ libcxx/include/string
@@ -2289,10 +2289,20 @@
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
#endif
{
- __clear_and_shrink();
- __r_.first() = __str.__r_.first();
- __move_assign_alloc(__str);
- __str.__zero();
+ if (__is_long()) {
+ __alloc_traits::deallocate(__alloc(), __get_long_pointer(),
+ __get_long_cap());
+#if _LIBCPP_STD_VER <= 14
+ if (!is_nothrow_move_assignable<allocator_type>::value) {
+ __set_short_size(0);
+ traits_type::assign(__get_short_pointer()[0], value_type());
+ }
+#endif
+ }
+ __move_assign_alloc(__str);
+ __r_.first() = __str.__r_.first();
+ __str.__set_short_size(0);
+ traits_type::assign(__str.__get_short_pointer()[0], value_type());
}
template <class _CharT, class _Traits, class _Allocator>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D68623.223719.patch
Type: text/x-patch
Size: 948 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20191008/9f7d1c6d/attachment.bin>
More information about the libcxx-commits
mailing list