Avoid referencing `PolicyFunctions` in raw_hash_set move operations unless generations are enabled. `common().annotate_for_bug_detection_on_move(that.common(), GetPolicyFunctions())` evaluates `GetPolicyFunctions()` as an argument even though the callee only uses it when `SwisstableGenerationsEnabled()`. This keeps the per-table `PolicyFunctions` instance referenced from every move constructor/assignment. Wrap the call in a member `annotate_for_bug_detection_on_move(that)` that only references `GetPolicyFunctions()` under `if constexpr (SwisstableGenerationsEnabled())`. PiperOrigin-RevId: 1009575588
diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 9e9a47c..628acf6 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h
@@ -247,9 +247,11 @@ // It is useful to avoid sampling attempts and sampling delays in tests. void TestOnlyRefreshSamplingStateForCurrentThread(); -// Returns a sampling handle. -inline HashtablezInfoHandle Sample(size_t inline_element_size, size_t key_size, - size_t value_size, uint16_t soo_capacity) { +// Returns a sampling handle. For use in tests only: `raw_hash_set` calls +// `ShouldSampleNextTable()` and `ForcedTrySample()` directly. +inline HashtablezInfoHandle SampleForTesting(size_t inline_element_size, + size_t key_size, size_t value_size, + uint16_t soo_capacity) { if (ABSL_PREDICT_TRUE(!ShouldSampleNextTable())) { return HashtablezInfoHandle(nullptr); }
diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 0d863a8..b61976d 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc
@@ -332,10 +332,10 @@ double sample_rate = 0.0; for (int i = 0; i < 1000000; ++i) { HashtablezInfoHandle h = - Sample(test_element_size, - /*key_size=*/test_key_size, /*value_size=*/test_value_size, - - /*soo_capacity=*/0); + SampleForTesting(test_element_size, + /*key_size=*/test_key_size, + /*value_size=*/test_value_size, + /*soo_capacity=*/0); ++total; if (h.IsSampled()) {
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index b7fb4d1..658c828 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -2897,8 +2897,7 @@ } } that.common() = CommonFields::CreateDefault<SooEnabled()>(); - common().annotate_for_bug_detection_on_move(that.common(), - GetPolicyFunctions()); + annotate_for_bug_detection_on_move(that); } raw_hash_set(raw_hash_set&& that, const allocator_type& a) @@ -2908,8 +2907,7 @@ alloc_(a) { if (CharAlloc(a) == that.char_alloc_ref()) { swap_common(that); - common().annotate_for_bug_detection_on_move(that.common(), - GetPolicyFunctions()); + annotate_for_bug_detection_on_move(that); } else { move_elements_allocs_unequal(std::move(that)); } @@ -3761,6 +3759,15 @@ std::move(tmp)); } + // Only references `GetPolicyFunctions()` when generations are enabled, so + // that the `PolicyFunctions` instance is not kept alive otherwise. + void annotate_for_bug_detection_on_move(raw_hash_set& that) { + if constexpr (SwisstableGenerationsEnabled()) { + common().annotate_for_bug_detection_on_move(that.common(), + GetPolicyFunctions()); + } + } + template <bool propagate_alloc> raw_hash_set& assign_impl(raw_hash_set&& that) { // We don't bother checking for this/that aliasing. We just need to avoid @@ -3773,8 +3780,7 @@ CopyAlloc(char_alloc_ref(), that.char_alloc_ref(), std::bool_constant<propagate_alloc>()); that.common() = CommonFields::CreateDefault<SooEnabled()>(); - common().annotate_for_bug_detection_on_move(that.common(), - GetPolicyFunctions()); + annotate_for_bug_detection_on_move(that); return *this; } @@ -3792,8 +3798,7 @@ &that.char_alloc_ref()); } that.common() = CommonFields::CreateDefault<SooEnabled()>(); - common().annotate_for_bug_detection_on_move(that.common(), - GetPolicyFunctions()); + annotate_for_bug_detection_on_move(that); return *this; }