| // Copyright 2015 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 "content/child/web_process_memory_dump_impl.h" |
| |
| #include "base/memory/discardable_memory.h" |
| #include "base/trace_event/process_memory_dump.h" |
| #include "content/child/web_memory_allocator_dump_impl.h" |
| #include "skia/ext/skia_trace_memory_dump_impl.h" |
| |
| namespace content { |
| |
| WebProcessMemoryDumpImpl::WebProcessMemoryDumpImpl() |
| : owned_process_memory_dump_( |
| new base::trace_event::ProcessMemoryDump(nullptr)), |
| process_memory_dump_(owned_process_memory_dump_.get()), |
| level_of_detail_(base::trace_event::MemoryDumpLevelOfDetail::DETAILED) {} |
| |
| WebProcessMemoryDumpImpl::WebProcessMemoryDumpImpl( |
| base::trace_event::MemoryDumpLevelOfDetail level_of_detail, |
| base::trace_event::ProcessMemoryDump* process_memory_dump) |
| : process_memory_dump_(process_memory_dump), |
| level_of_detail_(level_of_detail) {} |
| |
| WebProcessMemoryDumpImpl::~WebProcessMemoryDumpImpl() { |
| } |
| |
| blink::WebMemoryAllocatorDump* |
| WebProcessMemoryDumpImpl::createMemoryAllocatorDump( |
| const blink::WebString& absolute_name) { |
| // Get a MemoryAllocatorDump from the base/ object. |
| base::trace_event::MemoryAllocatorDump* memory_allocator_dump = |
| process_memory_dump_->CreateAllocatorDump(absolute_name.utf8()); |
| |
| return createWebMemoryAllocatorDump(memory_allocator_dump); |
| } |
| |
| blink::WebMemoryAllocatorDump* |
| WebProcessMemoryDumpImpl::createMemoryAllocatorDump( |
| const blink::WebString& absolute_name, |
| blink::WebMemoryAllocatorDumpGuid guid) { |
| // Get a MemoryAllocatorDump from the base/ object with given guid. |
| base::trace_event::MemoryAllocatorDump* memory_allocator_dump = |
| process_memory_dump_->CreateAllocatorDump( |
| absolute_name.utf8(), |
| base::trace_event::MemoryAllocatorDumpGuid(guid)); |
| return createWebMemoryAllocatorDump(memory_allocator_dump); |
| } |
| |
| blink::WebMemoryAllocatorDump* |
| WebProcessMemoryDumpImpl::createWebMemoryAllocatorDump( |
| base::trace_event::MemoryAllocatorDump* memory_allocator_dump) { |
| if (!memory_allocator_dump) |
| return nullptr; |
| |
| // Wrap it and return to blink. |
| WebMemoryAllocatorDumpImpl* web_memory_allocator_dump_impl = |
| new WebMemoryAllocatorDumpImpl(memory_allocator_dump); |
| |
| // memory_allocator_dumps_ will take ownership of |
| // |web_memory_allocator_dumpd_impl|. |
| memory_allocator_dumps_.set(memory_allocator_dump, |
| make_scoped_ptr(web_memory_allocator_dump_impl)); |
| return web_memory_allocator_dump_impl; |
| } |
| |
| blink::WebMemoryAllocatorDump* WebProcessMemoryDumpImpl::getMemoryAllocatorDump( |
| const blink::WebString& absolute_name) const { |
| // Retrieve the base MemoryAllocatorDump object and then reverse lookup |
| // its wrapper. |
| base::trace_event::MemoryAllocatorDump* memory_allocator_dump = |
| process_memory_dump_->GetAllocatorDump(absolute_name.utf8()); |
| if (!memory_allocator_dump) |
| return nullptr; |
| |
| // The only case of (memory_allocator_dump && !web_memory_allocator_dump) |
| // is something from blink trying to get a MAD that was created from chromium, |
| // which is an odd use case. |
| blink::WebMemoryAllocatorDump* web_memory_allocator_dump = |
| memory_allocator_dumps_.get(memory_allocator_dump); |
| DCHECK(web_memory_allocator_dump); |
| return web_memory_allocator_dump; |
| } |
| |
| void WebProcessMemoryDumpImpl::clear() { |
| // Clear all the WebMemoryAllocatorDump wrappers. |
| memory_allocator_dumps_.clear(); |
| |
| // Clear the actual MemoryAllocatorDump objects from the underlying PMD. |
| process_memory_dump_->Clear(); |
| } |
| |
| void WebProcessMemoryDumpImpl::takeAllDumpsFrom( |
| blink::WebProcessMemoryDump* other) { |
| auto other_impl = static_cast<WebProcessMemoryDumpImpl*>(other); |
| // WebProcessMemoryDumpImpl is a container of WebMemoryAllocatorDump(s) which |
| // in turn are wrappers of base::trace_event::MemoryAllocatorDump(s). |
| // In order to expose the move and ownership transfer semantics of the |
| // underlying ProcessMemoryDump, we need to: |
| |
| // 1) Move and transfer the ownership of the wrapped |
| // base::trace_event::MemoryAllocatorDump(s) instances. |
| process_memory_dump_->TakeAllDumpsFrom(other_impl->process_memory_dump_); |
| |
| // 2) Move and transfer the ownership of the WebMemoryAllocatorDump wrappers. |
| const size_t expected_final_size = memory_allocator_dumps_.size() + |
| other_impl->memory_allocator_dumps_.size(); |
| while (!other_impl->memory_allocator_dumps_.empty()) { |
| auto first_entry = other_impl->memory_allocator_dumps_.begin(); |
| base::trace_event::MemoryAllocatorDump* memory_allocator_dump = |
| first_entry->first; |
| memory_allocator_dumps_.set( |
| memory_allocator_dump, |
| other_impl->memory_allocator_dumps_.take_and_erase(first_entry).Pass()); |
| } |
| DCHECK_EQ(expected_final_size, memory_allocator_dumps_.size()); |
| DCHECK(other_impl->memory_allocator_dumps_.empty()); |
| } |
| |
| void WebProcessMemoryDumpImpl::AddOwnershipEdge( |
| blink::WebMemoryAllocatorDumpGuid source, |
| blink::WebMemoryAllocatorDumpGuid target, |
| int importance) { |
| process_memory_dump_->AddOwnershipEdge( |
| base::trace_event::MemoryAllocatorDumpGuid(source), |
| base::trace_event::MemoryAllocatorDumpGuid(target), importance); |
| } |
| |
| void WebProcessMemoryDumpImpl::AddOwnershipEdge( |
| blink::WebMemoryAllocatorDumpGuid source, |
| blink::WebMemoryAllocatorDumpGuid target) { |
| process_memory_dump_->AddOwnershipEdge( |
| base::trace_event::MemoryAllocatorDumpGuid(source), |
| base::trace_event::MemoryAllocatorDumpGuid(target)); |
| } |
| |
| void WebProcessMemoryDumpImpl::AddSuballocation( |
| blink::WebMemoryAllocatorDumpGuid source, |
| const blink::WebString& targetNodeName) { |
| process_memory_dump_->AddSuballocation( |
| base::trace_event::MemoryAllocatorDumpGuid(source), |
| targetNodeName.utf8()); |
| } |
| |
| SkTraceMemoryDump* WebProcessMemoryDumpImpl::CreateDumpAdapterForSkia( |
| const blink::WebString& dumpNamePrefix) { |
| sk_trace_dump_list_.push_back(new skia::SkiaTraceMemoryDumpImpl( |
| dumpNamePrefix.utf8(), level_of_detail_, process_memory_dump_)); |
| return sk_trace_dump_list_.back(); |
| } |
| |
| blink::WebMemoryAllocatorDump* |
| WebProcessMemoryDumpImpl::CreateDiscardableMemoryAllocatorDump( |
| const std::string& name, |
| base::DiscardableMemory* discardable) { |
| base::trace_event::MemoryAllocatorDump* dump = |
| discardable->CreateMemoryAllocatorDump(name.c_str(), |
| process_memory_dump_); |
| return createWebMemoryAllocatorDump(dump); |
| } |
| |
| } // namespace content |