[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