Index: base/debug/scoped_thread_heap_usage.cc |
diff --git a/base/debug/scoped_thread_heap_usage.cc b/base/debug/scoped_thread_heap_usage.cc |
deleted file mode 100644 |
index 2f5ed8c267e0a59a30d1735f9116bee115fbd831..0000000000000000000000000000000000000000 |
--- a/base/debug/scoped_thread_heap_usage.cc |
+++ /dev/null |
@@ -1,234 +0,0 @@ |
-// Copyright 2016 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "base/debug/scoped_thread_heap_usage.h" |
- |
-#include <stdint.h> |
-#include <algorithm> |
-#include <type_traits> |
- |
-#include "base/allocator/allocator_shim.h" |
-#include "base/allocator/features.h" |
-#include "base/logging.h" |
-#include "base/threading/thread_local_storage.h" |
-#include "build/build_config.h" |
- |
-#if defined(OS_MACOSX) || defined(OS_IOS) |
-#include <malloc/malloc.h> |
-#else |
-#include <malloc.h> |
-#endif |
- |
-namespace base { |
-namespace debug { |
- |
-namespace { |
- |
-using base::allocator::AllocatorDispatch; |
- |
-ThreadLocalStorage::StaticSlot g_thread_allocator_usage = TLS_INITIALIZER; |
- |
-ScopedThreadHeapUsage::ThreadAllocatorUsage* const kInitializingSentinel = |
- reinterpret_cast<ScopedThreadHeapUsage::ThreadAllocatorUsage*>(-1); |
- |
-bool g_heap_tracking_enabled = false; |
- |
-// Forward declared as it needs to delegate memory allocation to the next |
-// lower shim. |
-ScopedThreadHeapUsage::ThreadAllocatorUsage* GetOrCreateThreadUsage(); |
- |
-size_t GetAllocSizeEstimate(const AllocatorDispatch* next, void* ptr) { |
- if (ptr == nullptr) |
- return 0U; |
- |
- return next->get_size_estimate_function(next, ptr); |
-} |
- |
-void RecordAlloc(const AllocatorDispatch* next, void* ptr, size_t size) { |
- ScopedThreadHeapUsage::ThreadAllocatorUsage* usage = GetOrCreateThreadUsage(); |
- if (usage == nullptr) |
- return; |
- |
- usage->alloc_ops++; |
- size_t estimate = GetAllocSizeEstimate(next, ptr); |
- if (size && estimate) { |
- usage->alloc_bytes += estimate; |
- usage->alloc_overhead_bytes += estimate - size; |
- |
- // Only keep track of the net number of bytes allocated in the scope if the |
- // size estimate function returns sane values, e.g. non-zero. |
- uint64_t allocated_bytes = usage->alloc_bytes - usage->free_bytes; |
- if (allocated_bytes > usage->max_allocated_bytes) |
- usage->max_allocated_bytes = allocated_bytes; |
- } else { |
- usage->alloc_bytes += size; |
- } |
-} |
- |
-void RecordFree(const AllocatorDispatch* next, void* ptr) { |
- ScopedThreadHeapUsage::ThreadAllocatorUsage* usage = GetOrCreateThreadUsage(); |
- if (usage == nullptr) |
- return; |
- |
- size_t estimate = GetAllocSizeEstimate(next, ptr); |
- usage->free_ops++; |
- usage->free_bytes += estimate; |
-} |
- |
-void* AllocFn(const AllocatorDispatch* self, size_t size) { |
- void* ret = self->next->alloc_function(self->next, size); |
- if (ret != nullptr) |
- RecordAlloc(self->next, ret, size); |
- |
- return ret; |
-} |
- |
-void* AllocZeroInitializedFn(const AllocatorDispatch* self, |
- size_t n, |
- size_t size) { |
- void* ret = self->next->alloc_zero_initialized_function(self->next, n, size); |
- if (ret != nullptr) |
- RecordAlloc(self->next, ret, size); |
- |
- return ret; |
-} |
- |
-void* AllocAlignedFn(const AllocatorDispatch* self, |
- size_t alignment, |
- size_t size) { |
- void* ret = self->next->alloc_aligned_function(self->next, alignment, size); |
- if (ret != nullptr) |
- RecordAlloc(self->next, ret, size); |
- |
- return ret; |
-} |
- |
-void* ReallocFn(const AllocatorDispatch* self, void* address, size_t size) { |
- if (address != nullptr) |
- RecordFree(self->next, address); |
- |
- void* ret = self->next->realloc_function(self->next, address, size); |
- if (ret != nullptr && size != 0) |
- RecordAlloc(self->next, ret, size); |
- |
- return ret; |
-} |
- |
-void FreeFn(const AllocatorDispatch* self, void* address) { |
- if (address != nullptr) |
- RecordFree(self->next, address); |
- self->next->free_function(self->next, address); |
-} |
- |
-size_t GetSizeEstimateFn(const AllocatorDispatch* self, void* address) { |
- return self->next->get_size_estimate_function(self->next, address); |
-} |
- |
-// The allocator dispatch used to intercept heap operations. |
-AllocatorDispatch allocator_dispatch = { |
- &AllocFn, &AllocZeroInitializedFn, &AllocAlignedFn, &ReallocFn, |
- &FreeFn, &GetSizeEstimateFn, nullptr}; |
- |
-ScopedThreadHeapUsage::ThreadAllocatorUsage* GetOrCreateThreadUsage() { |
- ScopedThreadHeapUsage::ThreadAllocatorUsage* allocator_usage = |
- static_cast<ScopedThreadHeapUsage::ThreadAllocatorUsage*>( |
- g_thread_allocator_usage.Get()); |
- if (allocator_usage == kInitializingSentinel) |
- return nullptr; // Re-entrancy case. |
- |
- if (allocator_usage == nullptr) { |
- // Prevent reentrancy due to the allocation below. |
- g_thread_allocator_usage.Set(kInitializingSentinel); |
- |
- allocator_usage = new ScopedThreadHeapUsage::ThreadAllocatorUsage; |
- memset(allocator_usage, 0, sizeof(*allocator_usage)); |
- g_thread_allocator_usage.Set(allocator_usage); |
- } |
- |
- return allocator_usage; |
-} |
- |
-} // namespace |
- |
-ScopedThreadHeapUsage::ScopedThreadHeapUsage() { |
- // Initialize must be called before creating instances of this class. |
- CHECK(g_thread_allocator_usage.initialized()); |
- |
- ThreadAllocatorUsage* usage = GetOrCreateThreadUsage(); |
- usage_at_creation_ = *usage; |
- |
- // Reset the stats for our current scope. |
- // The per-thread usage instance now tracks this scope's usage, while this |
- // instance persists the outer scope's usage stats. On destruction, this |
- // instance will restore the outer scope's usage stats with this scope's usage |
- // added. |
- memset(usage, 0, sizeof(*usage)); |
- |
- static_assert(std::is_pod<ThreadAllocatorUsage>::value, "Must be POD."); |
-} |
- |
-ScopedThreadHeapUsage::~ScopedThreadHeapUsage() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- ThreadAllocatorUsage* usage = GetOrCreateThreadUsage(); |
- |
- // Update the outer max. |
- if (usage->max_allocated_bytes) { |
- uint64_t outer_net_alloc_bytes = |
- usage_at_creation_.alloc_bytes - usage_at_creation_.free_bytes; |
- |
- usage->max_allocated_bytes = |
- std::max(usage_at_creation_.max_allocated_bytes, |
- outer_net_alloc_bytes + usage->max_allocated_bytes); |
- } |
- |
- usage->alloc_ops += usage_at_creation_.alloc_ops; |
- usage->alloc_bytes += usage_at_creation_.alloc_bytes; |
- usage->alloc_overhead_bytes += usage_at_creation_.alloc_overhead_bytes; |
- usage->free_ops += usage_at_creation_.free_ops; |
- usage->free_bytes += usage_at_creation_.free_bytes; |
-} |
- |
-ScopedThreadHeapUsage::ThreadAllocatorUsage |
-ScopedThreadHeapUsage::CurrentUsage() { |
- ThreadAllocatorUsage* usage = GetOrCreateThreadUsage(); |
- return *usage; |
-} |
- |
-void ScopedThreadHeapUsage::Initialize() { |
- if (!g_thread_allocator_usage.initialized()) { |
- g_thread_allocator_usage.Initialize([](void* allocator_usage) { |
- delete static_cast<ScopedThreadHeapUsage::ThreadAllocatorUsage*>( |
- allocator_usage); |
- }); |
- } |
-} |
- |
-void ScopedThreadHeapUsage::EnableHeapTracking() { |
- CHECK_EQ(false, g_heap_tracking_enabled) << "No double-enabling."; |
- g_heap_tracking_enabled = true; |
-#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) |
- base::allocator::InsertAllocatorDispatch(&allocator_dispatch); |
-#else |
- CHECK(false) << "Can't enable heap tracking without the shim."; |
-#endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) |
-} |
- |
-void ScopedThreadHeapUsage::DisableHeapTrackingForTesting() { |
-#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) |
- base::allocator::RemoveAllocatorDispatchForTesting(&allocator_dispatch); |
-#else |
- CHECK(false) << "Can't disable heap tracking without the shim."; |
-#endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) |
- DCHECK_EQ(true, g_heap_tracking_enabled) << "Heap tracking not enabled."; |
- g_heap_tracking_enabled = false; |
-} |
- |
-base::allocator::AllocatorDispatch* |
-ScopedThreadHeapUsage::GetDispatchForTesting() { |
- return &allocator_dispatch; |
-} |
- |
-} // namespace debug |
-} // namespace base |