[libcxx-commits] [libcxx] [libc++] Optimize vector::emplace_back slow path (PR #222016)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 9 04:52:03 PDT 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/222016
>From 0856c6f49325d7c2b31bbeb0a508c0ce58e8ee5c Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 8 Sep 2026 16:42:49 +0200
Subject: [PATCH] [libc++] Optimize vector::emplace_back slow path
---
libcxx/include/__vector/vector.h | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index d37a0c21ebcd5..0838729033613 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -41,6 +41,7 @@
#include <__memory/swap_allocator.h>
#include <__memory/temp_value.h>
#include <__memory/uninitialized_algorithms.h>
+#include <__numeric/saturation_arithmetic.h>
#include <__ranges/access.h>
#include <__ranges/as_rvalue_view.h>
#include <__ranges/concepts.h>
@@ -1068,13 +1069,23 @@ vector<_Tp, _Alloc>::emplace_back(_Args&&... __args) {
__self.__emplace_back_assume_capacity(std::forward<_Args>(__largs)...);
},
[](vector& __self, _Args&&... __largs) static {
- _SplitBuffer __v(__self.__recommend(__self.size() + 1), __self.size(), __self.__layout_.__alloc());
- // __v.emplace_back(std::forward<_Args>(__args)...);
- pointer __end = __v.end();
- __alloc_traits::construct(
- __self.__layout_.__alloc(), std::__to_address(__end), std::forward<_Args>(__largs)...);
- __v.__set_sentinel(++__end);
- __self.__layout_.__relocate(__v);
+ auto& __alloc = __self.__layout_.__alloc();
+ auto __size = __self.size();
+ auto __allocation = std::__allocate_at_least(__alloc, __self.__recommend(__size + 1));
+ auto __ptr = std::__to_address(__allocation.ptr);
+ auto __old_begin = __self.__layout_.__begin_ptr();
+ __alloc_traits::construct(__alloc, __ptr + __size, std::forward<_Args>(__largs)...);
+ auto __guard = std::__make_exception_guard([&] { __alloc_traits::destroy(__alloc, __ptr + __size); });
+ std::__uninitialized_allocator_relocate(
+ __alloc,
+ std::__to_address(__old_begin),
+ std::__to_address(__self.__layout_.__end_ptr()),
+ __ptr);
+ __guard.__complete();
+ auto __old_cap = __self.capacity();
+ __self.__layout_.__set_layout(__allocation.ptr, __size + 1, __allocation.count);
+ if ((__is_std_allocator_v<allocator_type> && !__libcpp_is_constant_evaluated()) || __old_begin)
+ __alloc_traits::deallocate(__alloc, __old_begin, __old_cap);
},
*this,
std::forward<_Args>(__args)...);
More information about the libcxx-commits
mailing list