Make PolicyTraits::transfer_uses_memcpy() true for node_hash_* tables. This should enable binary size savings for now and more efficiency improvements with small buffer optimization. PiperOrigin-RevId: 564741270 Change-Id: Icf204d88256243eb60464439a52dd589d7a559cb
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 208e78e..5131837 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel
@@ -499,6 +499,7 @@ linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":common_policy_traits", + "//absl/base:config", "@com_google_googletest//:gtest_main", ], ) @@ -582,6 +583,7 @@ deps = [ ":hash_policy_traits", ":node_slot_policy", + "//absl/base:config", "@com_google_googletest//:gtest_main", ], )
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 64f6965..f5ef0dd 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt
@@ -577,6 +577,7 @@ ${ABSL_TEST_COPTS} DEPS absl::common_policy_traits + absl::config GTest::gmock_main ) @@ -660,6 +661,7 @@ COPTS ${ABSL_TEST_COPTS} DEPS + absl::config absl::hash_policy_traits absl::node_slot_policy GTest::gmock_main
diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h index 3558a54..57eac67 100644 --- a/absl/container/internal/common_policy_traits.h +++ b/absl/container/internal/common_policy_traits.h
@@ -93,11 +93,13 @@ struct Rank0 : Rank1 {}; // Use auto -> decltype as an enabler. + // P::transfer returns std::true_type if transfer uses memcpy (e.g. in + // node_slot_policy). template <class Alloc, class P = Policy> static auto transfer_impl(Alloc* alloc, slot_type* new_slot, slot_type* old_slot, Rank0) - -> decltype((void)P::transfer(alloc, new_slot, old_slot)) { - P::transfer(alloc, new_slot, old_slot); + -> decltype(P::transfer(alloc, new_slot, old_slot)) { + return P::transfer(alloc, new_slot, old_slot); } #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 // This overload returns true_type for the trait below.
diff --git a/absl/container/internal/common_policy_traits_test.cc b/absl/container/internal/common_policy_traits_test.cc index 5eaa4aa..faee3e7 100644 --- a/absl/container/internal/common_policy_traits_test.cc +++ b/absl/container/internal/common_policy_traits_test.cc
@@ -16,10 +16,12 @@ #include <functional> #include <memory> -#include <new> +#include <type_traits> +#include <utility> #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/base/config.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -51,9 +53,14 @@ struct PolicyWithOptionalOps : PolicyWithoutOptionalOps { static std::function<void(void*, Slot*, Slot*)> transfer; }; - std::function<void(void*, Slot*, Slot*)> PolicyWithOptionalOps::transfer; +struct PolicyWithMemcpyTransfer : PolicyWithoutOptionalOps { + static std::function<std::true_type(void*, Slot*, Slot*)> transfer; +}; +std::function<std::true_type(void*, Slot*, Slot*)> + PolicyWithMemcpyTransfer::transfer; + struct Test : ::testing::Test { Test() { PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) { @@ -114,6 +121,13 @@ common_policy_traits<PolicyWithOptionalOps>::transfer(&alloc, &a, &b); } +TEST(TransferUsesMemcpy, Basic) { + EXPECT_FALSE( + common_policy_traits<PolicyWithOptionalOps>::transfer_uses_memcpy()); + EXPECT_TRUE( + common_policy_traits<PolicyWithMemcpyTransfer>::transfer_uses_memcpy()); +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END
diff --git a/absl/container/internal/node_slot_policy.h b/absl/container/internal/node_slot_policy.h index baba574..3f1874d 100644 --- a/absl/container/internal/node_slot_policy.h +++ b/absl/container/internal/node_slot_policy.h
@@ -62,9 +62,12 @@ Policy::delete_element(alloc, *slot); } + // Returns true_type to indicate that transfer can use memcpy. template <class Alloc> - static void transfer(Alloc*, slot_type* new_slot, slot_type* old_slot) { + static std::true_type transfer(Alloc*, slot_type* new_slot, + slot_type* old_slot) { *new_slot = *old_slot; + return {}; } static size_t space_used(const slot_type* slot) {
diff --git a/absl/container/internal/node_slot_policy_test.cc b/absl/container/internal/node_slot_policy_test.cc index 51b7467..d4ea919 100644 --- a/absl/container/internal/node_slot_policy_test.cc +++ b/absl/container/internal/node_slot_policy_test.cc
@@ -18,6 +18,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/base/config.h" #include "absl/container/internal/hash_policy_traits.h" namespace absl { @@ -61,6 +62,7 @@ int* b = &s; NodePolicy::transfer(&alloc, &a, &b); EXPECT_EQ(&s, a); + EXPECT_TRUE(NodePolicy::transfer_uses_memcpy()); } } // namespace