diff --git a/tcmalloc/metadata_object_allocator.h b/tcmalloc/metadata_object_allocator.h index 9b7f982db..cfd394cc1 100644 --- a/tcmalloc/metadata_object_allocator.h +++ b/tcmalloc/metadata_object_allocator.h @@ -23,8 +23,10 @@ #include "absl/base/const_init.h" #include "absl/base/dynamic_annotations.h" #include "absl/base/internal/spinlock.h" +#include "absl/base/nullability.h" #include "absl/base/optimization.h" #include "absl/base/thread_annotations.h" +#include "absl/functional/function_ref.h" #include "absl/types/span.h" #include "tcmalloc/arena.h" #include "tcmalloc/common.h" @@ -88,6 +90,14 @@ class MetadataObjectAllocator { } } + void Delete(absl::FunctionRef callback) { + AllocationGuardSpinLockHolder l(metadata_lock_); + while (T* p = callback()) { + p->~T(); + DeleteMemory(p); + } + } + [[nodiscard]] AllocatorStats stats() const { AllocationGuardSpinLockHolder l(metadata_lock_); diff --git a/tcmalloc/stack_trace_table.cc b/tcmalloc/stack_trace_table.cc index 6afbfcf0f..d96ec66f2 100644 --- a/tcmalloc/stack_trace_table.cc +++ b/tcmalloc/stack_trace_table.cc @@ -40,11 +40,16 @@ StackTraceTable::StackTraceTable(ProfileType type) StackTraceTable::~StackTraceTable() { LinkedSample* cur = all_; - while (cur != nullptr) { - LinkedSample* next = cur->next; - tc_globals.linked_sample_allocator().Delete(cur); - cur = next; + if (cur == nullptr) { + return; } + tc_globals.linked_sample_allocator().Delete([&]() -> LinkedSample* { + LinkedSample* s = cur; + if (s != nullptr) { + cur = s->next; + } + return s; + }); all_ = nullptr; }