| Index: services/resource_coordinator/memory/coordinator/coordinator_impl.cc
|
| diff --git a/services/resource_coordinator/memory/coordinator/coordinator_impl.cc b/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
|
| index 4cc1840ba72ab45b937cd767787ea13942f9bf9a..d57f4ae5addef6f7dd837324b9ad9b23e51f6b55 100644
|
| --- a/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
|
| +++ b/services/resource_coordinator/memory/coordinator/coordinator_impl.cc
|
| @@ -17,10 +17,38 @@
|
| #include "services/resource_coordinator/public/interfaces/memory/constants.mojom.h"
|
| #include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
|
|
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| +#include "base/mac/mac_util.h"
|
| +#endif
|
| +
|
| namespace {
|
|
|
| memory_instrumentation::CoordinatorImpl* g_coordinator_impl;
|
|
|
| +uint32_t CalculatePrivateFootprintKb(
|
| + base::trace_event::MemoryDumpCallbackResult::OSMemDump& os_dump) {
|
| +#if defined(OS_LINUX) || defined(OS_ANDROID)
|
| + uint64_t rss_anon_bytes = os_dump.platform_private_footprint.rss_anon_bytes;
|
| + uint64_t vm_swap_bytes = os_dump.platform_private_footprint.vm_swap_bytes;
|
| + return (rss_anon_bytes + vm_swap_bytes) / 1024;
|
| +#elif defined(OS_MACOSX)
|
| + // TODO(erikchen): This calculation is close, but not fully accurate. It
|
| + // overcounts by anonymous shared memory.
|
| + if (base::mac::IsAtLeastOS10_12()) {
|
| + uint64_t phys_footprint_bytes =
|
| + os_dump.platform_private_footprint.phys_footprint_bytes;
|
| + return phys_footprint_bytes / 1024;
|
| + } else {
|
| + uint64_t internal_bytes = os_dump.platform_private_footprint.internal_bytes;
|
| + uint64_t compressed_bytes =
|
| + os_dump.platform_private_footprint.compressed_bytes;
|
| + return (internal_bytes + compressed_bytes) / 1024;
|
| + }
|
| +#else
|
| + return 0;
|
| +#endif
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace memory_instrumentation {
|
| @@ -187,15 +215,49 @@ void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() {
|
| return;
|
| }
|
|
|
| - // TODO(hjd,fmeawad): At this point the |process_memory_dumps| accumulated in
|
| - // queued_memory_dump_requests_.front() should be normalized (merge
|
| - // |extra_process_dump|, compute CMM) into a GlobalMemoryDumpPtr and passed
|
| - // below.
|
| + std::map<base::ProcessId, mojom::ProcessMemoryDumpPtr> finalized_pmds;
|
| + for (auto& result :
|
| + queued_memory_dump_requests_.front().process_memory_dumps) {
|
| + // TODO(fmeawad): Write into correct map entry instead of always
|
| + // to pid = 0.
|
| + mojom::ProcessMemoryDumpPtr& pmd = finalized_pmds[0];
|
| + if (!pmd)
|
| + pmd = mojom::ProcessMemoryDump::New();
|
| + pmd->chrome_dump = std::move(result->chrome_dump);
|
| +
|
| + // TODO(hjd): We should have a better way to tell if os_dump is filled.
|
| + if (result->os_dump.resident_set_kb > 0) {
|
| + pmd->os_dump = std::move(result->os_dump);
|
| + }
|
| +
|
| + for (auto& pair : result->extra_processes_dump) {
|
| + base::ProcessId pid = pair.first;
|
| + mojom::ProcessMemoryDumpPtr& pmd = finalized_pmds[pid];
|
| + if (!pmd)
|
| + pmd = mojom::ProcessMemoryDump::New();
|
| + pmd->os_dump = std::move(result->extra_processes_dump[pid]);
|
| + }
|
| + }
|
| +
|
| + mojom::GlobalMemoryDumpPtr global_dump(mojom::GlobalMemoryDump::New());
|
| + for (auto& pair : finalized_pmds) {
|
| + // It's possible that the renderer has died but we still have an os_dump,
|
| + // because those were comptued from the browser proces before the renderer
|
| + // died. We should skip these.
|
| + // TODO(hjd): We should have a better way to tell if a chrome_dump is
|
| + // filled.
|
| + if (!pair.second->chrome_dump.malloc_total_kb)
|
| + continue;
|
| + base::ProcessId pid = pair.first;
|
| + mojom::ProcessMemoryDumpPtr pmd = std::move(finalized_pmds[pid]);
|
| + pmd->private_footprint = CalculatePrivateFootprintKb(pmd->os_dump);
|
| + global_dump->process_dumps.push_back(std::move(pmd));
|
| + }
|
|
|
| const auto& callback = queued_memory_dump_requests_.front().callback;
|
| const bool global_success = failed_memory_dump_count_ == 0;
|
| callback.Run(queued_memory_dump_requests_.front().args.dump_guid,
|
| - global_success, nullptr /* global_memory_dump */);
|
| + global_success, std::move(global_dump));
|
| queued_memory_dump_requests_.pop_front();
|
|
|
| // Schedule the next queued dump (if applicable).
|
|
|