Commit 8f241e77 by Evan Brown Committed by Copybara-Service

Store infoz on the heap instead of inline and store it only when we are sampling…

Store infoz on the heap instead of inline and store it only when we are sampling the current allocation.

PiperOrigin-RevId: 553847957
Change-Id: Idd131d0362bf36bd22d9bd20df54bd9ae50f0e28
parent 039d70f6
......@@ -137,18 +137,7 @@ class HashtablezInfoHandle {
UnsampleSlow(info_);
}
HashtablezInfoHandle(const HashtablezInfoHandle&) = delete;
HashtablezInfoHandle& operator=(const HashtablezInfoHandle&) = delete;
HashtablezInfoHandle(HashtablezInfoHandle&& o) noexcept
: info_(absl::exchange(o.info_, nullptr)) {}
HashtablezInfoHandle& operator=(HashtablezInfoHandle&& o) noexcept {
if (ABSL_PREDICT_FALSE(info_ != nullptr)) {
UnsampleSlow(info_);
}
info_ = absl::exchange(o.info_, nullptr);
return *this;
}
inline bool IsSampled() const { return ABSL_PREDICT_FALSE(info_ != nullptr); }
inline void RecordStorageChanged(size_t size, size_t capacity) {
if (ABSL_PREDICT_TRUE(info_ == nullptr)) return;
......@@ -198,6 +187,7 @@ class HashtablezInfoHandle {
explicit HashtablezInfoHandle(std::nullptr_t) {}
inline void Unregister() {}
inline bool IsSampled() const { return false; }
inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {}
inline void RecordRehash(size_t /*total_probe_length*/) {}
inline void RecordReservation(size_t /*target_capacity*/) {}
......
......@@ -42,16 +42,11 @@ namespace container_internal {
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
class HashtablezInfoHandlePeer {
public:
static bool IsSampled(const HashtablezInfoHandle& h) {
return h.info_ != nullptr;
}
static HashtablezInfo* GetInfo(HashtablezInfoHandle* h) { return h->info_; }
};
#else
class HashtablezInfoHandlePeer {
public:
static bool IsSampled(const HashtablezInfoHandle&) { return false; }
static HashtablezInfo* GetInfo(HashtablezInfoHandle*) { return nullptr; }
};
#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
......@@ -267,7 +262,7 @@ TEST(HashtablezSamplerTest, Sample) {
for (int i = 0; i < 1000000; ++i) {
HashtablezInfoHandle h = Sample(test_element_size);
++total;
if (HashtablezInfoHandlePeer::IsSampled(h)) {
if (h.IsSampled()) {
++num_sampled;
}
sample_rate = static_cast<double>(num_sampled) / total;
......@@ -294,6 +289,7 @@ TEST(HashtablezSamplerTest, Handle) {
});
EXPECT_TRUE(found);
h.Unregister();
h = HashtablezInfoHandle();
found = false;
sampler.Iterate([&](const HashtablezInfo& h) {
......
......@@ -220,7 +220,7 @@ void DropDeletesWithoutResize(CommonFields& common,
void EraseMetaOnly(CommonFields& c, ctrl_t* it, size_t slot_size) {
assert(IsFull(*it) && "erasing a dangling iterator");
c.set_size(c.size() - 1);
c.decrement_size();
const auto index = static_cast<size_t>(it - c.control());
const size_t index_before = (index - Group::kWidth) & c.capacity();
const auto empty_after = Group(it).MaskEmpty();
......@@ -247,14 +247,15 @@ void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
ResetCtrl(c, policy.slot_size);
c.infoz().RecordStorageChanged(0, c.capacity());
} else {
// We need to record infoz before calling dealloc, which will unregister
// infoz.
c.infoz().RecordClearedReservation();
c.infoz().RecordStorageChanged(0, 0);
(*policy.dealloc)(c, policy);
c.set_control(EmptyGroup());
c.set_generation_ptr(EmptyGeneration());
c.set_slots(nullptr);
c.set_capacity(0);
c.infoz().RecordClearedReservation();
assert(c.size() == 0);
c.infoz().RecordStorageChanged(0, 0);
}
}
......
......@@ -524,13 +524,6 @@ TEST(Table, EmptyFunctorOptimization) {
static_assert(std::is_empty<std::allocator<int>>::value, "");
struct MockTable {
void* infoz;
void* ctrl;
void* slots;
size_t size;
size_t capacity;
};
struct MockTableInfozDisabled {
void* ctrl;
void* slots;
size_t size;
......@@ -555,9 +548,7 @@ TEST(Table, EmptyFunctorOptimization) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#endif
constexpr size_t mock_size = std::is_empty<HashtablezInfoHandle>()
? sizeof(MockTableInfozDisabled)
: sizeof(MockTable);
constexpr size_t mock_size = sizeof(MockTable);
constexpr size_t generation_size =
SwisstableGenerationsEnabled() ? sizeof(GenerationData) : 0;
#if defined(__clang__)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment