[libcxx-commits] [libcxx] [libc++] Add randomize unspecified stability in `__hash_table` (PR #105982)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 30 08:20:34 PDT 2024
================
@@ -1741,6 +1757,70 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) {
}
}
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <bool _UniqueKeys>
+void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__debug_randomize_order() {
+#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+
+ struct __nh_vec {
+ using __nh_allocator = __rebind_alloc<__node_traits, __node_holder>;
+ using __pointer = typename allocator_traits<__nh_allocator>::pointer;
+ __nh_allocator __nh_alloc;
+ __pointer __p = __pointer();
+ size_type __total_nodes = 0;
+ size_type __initialized_nodes = 0;
+ __nh_vec(size_type __n) : __nh_alloc(), __p(__nh_alloc.allocate(__n)), __total_nodes(__n) {}
+ ~__nh_vec() {
+ if (__p) {
+ std::__destroy(__p, __p + __initialized_nodes);
+ __nh_alloc.deallocate(__p, __total_nodes);
+ }
+ }
+ };
+
+ struct __index_vec {
+ using __index_allocator = __rebind_alloc<__node_traits, size_type>;
+ using __pointer = typename allocator_traits<__index_allocator>::pointer;
+ __index_allocator __index_alloc;
+ __pointer __p = __pointer();
+ size_type __total_indices = 0;
+ size_type __initialized_indices = 0;
+ __index_vec(size_type __n) : __index_alloc(), __p(__index_alloc.allocate(__n)), __total_indices(__n) {}
+ ~__index_vec() {
+ if (__p) {
+ std::__destroy(__p, __p + __initialized_indices);
+ __index_alloc.deallocate(__p, __total_indices);
+ }
+ }
+ };
+
+ __nh_vec __nhv(size());
+ __index_vec __iv(size());
+
+ // Move nodes into temporary storage.
+ for (; __nhv.__initialized_nodes < __nhv.__total_nodes; ++__nhv.__initialized_nodes)
+ std::__construct_at(std::addressof(__nhv.__p[__nhv.__initialized_nodes]), remove(begin()));
+
+ // Randomize the order of indices.
+ for (; __iv.__initialized_indices < __nhv.__initialized_nodes; ++__iv.__initialized_indices)
+ std::__construct_at(std::addressof(__iv.__p[__iv.__initialized_indices]), __iv.__initialized_indices);
+ __debug_randomize_range<_ClassicAlgPolicy>(__iv.__p, __iv.__p + __iv.__initialized_indices);
+
+ // Reinsert nodes into the hash table in randomized order.
+ for (size_type __i = 0; __i < __iv.__initialized_indices; ++__i) {
+ __node_holder& __nh = __nhv.__p[__iv.__p[__i]];
+ __node_pointer __np = __nh->__upcast();
+ if _LIBCPP_CONSTEXPR_SINCE_CXX17 (_UniqueKeys) {
+ __node_insert_unique_perform(__np);
+ } else {
+ __next_pointer __pn = __node_insert_multi_find_insertion_point(__np->__hash(), __np->__get_value());
+ __node_insert_multi_perform(__np, __pn);
+ }
+ __nh.release();
+ }
+#endif
----------------
ldionne wrote:
```suggestion
#endif // defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
```
https://github.com/llvm/llvm-project/pull/105982
More information about the libcxx-commits
mailing list