| Index: base/memory/shared_memory_tracker.cc
|
| diff --git a/base/memory/shared_memory_tracker.cc b/base/memory/shared_memory_tracker.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..323c8e775a3fb90d4ff77e637182a13ece8d4ecd
|
| --- /dev/null
|
| +++ b/base/memory/shared_memory_tracker.cc
|
| @@ -0,0 +1,109 @@
|
| +// 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/memory/shared_memory_tracker.h"
|
| +
|
| +#include "base/memory/shared_memory.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/trace_event/memory_dump_manager.h"
|
| +#include "base/trace_event/process_memory_dump.h"
|
| +
|
| +namespace base {
|
| +
|
| +const char* kSharedMemoryDumpName = "sharedmemory";
|
| +
|
| +SharedMemoryTracker* SharedMemoryTracker::GetInstance() {
|
| + return base::Singleton<SharedMemoryTracker, base::LeakySingletonTraits<
|
| + SharedMemoryTracker>>::get();
|
| +}
|
| +
|
| +bool SharedMemoryTracker::AddOwnershipEdgeToSharedGlobalDump(
|
| + trace_event::ProcessMemoryDump* pmd,
|
| + const trace_event::MemoryAllocatorDumpGuid& source,
|
| + const SharedMemoryHandle& shared_memory_handle,
|
| + size_t mapped_size) {
|
| + SharedMemoryHandleID id;
|
| + if (!GetIDFromSharedMemoryHandle(shared_memory_handle, &id)) {
|
| + return false;
|
| + }
|
| + std::string id_str = GetSharedMemoryHandleIDString(id);
|
| + std::string dump_name =
|
| + base::StringPrintf("%s/%s", kSharedMemoryDumpName, id_str.c_str());
|
| + auto global_dump = pmd->CreateSharedGlobalAllocatorDump(
|
| + base::trace_event::MemoryAllocatorDumpGuid(dump_name));
|
| + global_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
|
| + base::trace_event::MemoryAllocatorDump::kUnitsBytes,
|
| + mapped_size);
|
| + pmd->AddOwnershipEdge(source, global_dump->guid());
|
| + return true;
|
| +}
|
| +
|
| +bool SharedMemoryTracker::OnMemoryDump(
|
| + const base::trace_event::MemoryDumpArgs& args,
|
| + base::trace_event::ProcessMemoryDump* pmd) {
|
| + for (auto& bucket : buckets_) {
|
| + base::AutoLock lock(bucket.lock);
|
| + for (const auto& usage_in_device : bucket.usage) {
|
| + for (const auto& usage : usage_in_device.second) {
|
| + SharedMemoryHandleID id;
|
| + id.device_id = usage_in_device.first;
|
| + id.file_id = usage.first;
|
| + std::string id_str = GetSharedMemoryHandleIDString(id);
|
| + std::string dump_name =
|
| + base::StringPrintf("%s/%s", kSharedMemoryDumpName, id_str.c_str());
|
| + auto guid = base::trace_event::MemoryAllocatorDumpGuid(dump_name);
|
| + base::trace_event::MemoryAllocatorDump* local_dump =
|
| + pmd->CreateAllocatorDump(dump_name);
|
| + local_dump->AddScalar(
|
| + base::trace_event::MemoryAllocatorDump::kNameSize,
|
| + base::trace_event::MemoryAllocatorDump::kUnitsBytes, usage.second);
|
| + base::trace_event::MemoryAllocatorDump* global_dump =
|
| + pmd->CreateSharedGlobalAllocatorDump(guid);
|
| + global_dump->AddScalar(
|
| + base::trace_event::MemoryAllocatorDump::kNameSize,
|
| + base::trace_event::MemoryAllocatorDump::kUnitsBytes, usage.second);
|
| + pmd->AddOwnershipEdge(local_dump->guid(), global_dump->guid());
|
| + }
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool SharedMemoryTracker::IncrementMemoryUsage(
|
| + const SharedMemory& shared_memory) {
|
| + SharedMemoryHandleID id;
|
| + if (!GetIDFromSharedMemoryHandle(shared_memory.handle(), &id)) {
|
| + return false;
|
| + }
|
| + int bucket = id.file_id % kTrackerBucketNum;
|
| + base::AutoLock lock(buckets_[bucket].lock);
|
| + buckets_[bucket].usage[id.device_id][id.file_id] =
|
| + shared_memory.mapped_size();
|
| + return true;
|
| +}
|
| +
|
| +bool SharedMemoryTracker::DecrementMemoryUsage(
|
| + const SharedMemory& shared_memory) {
|
| + SharedMemoryHandleID id;
|
| + if (!GetIDFromSharedMemoryHandle(shared_memory.handle(), &id)) {
|
| + return false;
|
| + }
|
| + int bucket = id.file_id % kTrackerBucketNum;
|
| + base::AutoLock lock(buckets_[bucket].lock);
|
| + buckets_[bucket].usage[id.device_id].erase(id.file_id);
|
| + return true;
|
| +}
|
| +
|
| +SharedMemoryTracker::SharedMemoryTracker() {
|
| + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
|
| + this, "SharedMemoryTracker", nullptr);
|
| +}
|
| +
|
| +SharedMemoryTracker::~SharedMemoryTracker() {}
|
| +
|
| +SharedMemoryTracker::TrackerBucket::TrackerBucket() {}
|
| +
|
| +SharedMemoryTracker::TrackerBucket::~TrackerBucket() {}
|
| +
|
| +} // namespace
|
|
|