| Index: base/trace_event/sharded_allocation_register.cc
|
| diff --git a/base/trace_event/sharded_allocation_register.cc b/base/trace_event/sharded_allocation_register.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1b3eece3f60e727e59f8cd8735799042d592b49a
|
| --- /dev/null
|
| +++ b/base/trace_event/sharded_allocation_register.cc
|
| @@ -0,0 +1,92 @@
|
| +// Copyright 2017 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/trace_event/sharded_allocation_register.h"
|
| +
|
| +#include "base/trace_event/trace_event_memory_overhead.h"
|
| +#include "build/build_config.h"
|
| +
|
| +namespace base {
|
| +namespace trace_event {
|
| +
|
| +// This number affects the bucket and capacity counts of AllocationRegister at
|
| +// "base/trace_event/heap_profiler_allocation_register.h".
|
| +#if defined(OS_ANDROID) || defined(OS_IOS)
|
| +const size_t ShardCount = 1;
|
| +#else
|
| +const size_t ShardCount = 64;
|
| +#endif
|
| +
|
| +ShardedAllocationRegister::ShardedAllocationRegister() : enabled_(false) {}
|
| +
|
| +ShardedAllocationRegister::~ShardedAllocationRegister() = default;
|
| +
|
| +void ShardedAllocationRegister::SetEnabled() {
|
| + if (!allocation_registers_)
|
| + allocation_registers_.reset(new RegisterAndLock[ShardCount]);
|
| + base::subtle::Release_Store(&enabled_, 1);
|
| +}
|
| +
|
| +void ShardedAllocationRegister::SetDisabled() {
|
| + base::subtle::Release_Store(&enabled_, 0);
|
| +}
|
| +
|
| +bool ShardedAllocationRegister::Insert(const void* address,
|
| + size_t size,
|
| + const AllocationContext& context) {
|
| + AllocationRegister::AddressHasher hasher;
|
| + size_t index = hasher(address) % ShardCount;
|
| + RegisterAndLock& ral = allocation_registers_[index];
|
| + AutoLock lock(ral.lock);
|
| + return ral.allocation_register.Insert(address, size, context);
|
| +}
|
| +
|
| +void ShardedAllocationRegister::Remove(const void* address) {
|
| + AllocationRegister::AddressHasher hasher;
|
| + size_t index = hasher(address) % ShardCount;
|
| + RegisterAndLock& ral = allocation_registers_[index];
|
| + AutoLock lock(ral.lock);
|
| + return ral.allocation_register.Remove(address);
|
| +}
|
| +
|
| +void ShardedAllocationRegister::EstimateTraceMemoryOverhead(
|
| + TraceEventMemoryOverhead* overhead) const {
|
| + size_t allocated = 0;
|
| + size_t resident = 0;
|
| + for (size_t i = 0; i < ShardCount; ++i) {
|
| + RegisterAndLock& ral = allocation_registers_[i];
|
| + AutoLock lock(ral.lock);
|
| + allocated += ral.allocation_register.EstimateAllocatedMemory();
|
| + resident += ral.allocation_register.EstimateResidentMemory();
|
| + }
|
| +
|
| + overhead->Add(TraceEventMemoryOverhead::kHeapProfilerAllocationRegister,
|
| + allocated, resident);
|
| +}
|
| +
|
| +ShardedAllocationRegister::OutputMetrics
|
| +ShardedAllocationRegister::UpdateAndReturnsMetrics(MetricsMap& map) const {
|
| + OutputMetrics output_metrics;
|
| + output_metrics.size = 0;
|
| + output_metrics.count = 0;
|
| + for (size_t i = 0; i < ShardCount; ++i) {
|
| + RegisterAndLock& ral = allocation_registers_[i];
|
| + AutoLock lock(ral.lock);
|
| + for (const auto& alloc_size : ral.allocation_register) {
|
| + AllocationMetrics& metrics = map[alloc_size.context];
|
| + metrics.size += alloc_size.size;
|
| + metrics.count++;
|
| +
|
| + output_metrics.size += alloc_size.size;
|
| + output_metrics.count++;
|
| + }
|
| + }
|
| + return output_metrics;
|
| +}
|
| +
|
| +ShardedAllocationRegister::RegisterAndLock::RegisterAndLock() = default;
|
| +ShardedAllocationRegister::RegisterAndLock::~RegisterAndLock() = default;
|
| +
|
| +} // namespace trace_event
|
| +} // namespace base
|
|
|