1// Copyright 2015 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_ 6#define BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_ 7 8#include <stddef.h> 9 10#include <vector> 11 12#include "base/base_export.h" 13#include "base/containers/hash_tables.h" 14#include "base/containers/small_map.h" 15#include "base/macros.h" 16#include "base/memory/ref_counted.h" 17#include "base/memory/scoped_vector.h" 18#include "base/trace_event/memory_allocator_dump.h" 19#include "base/trace_event/memory_allocator_dump_guid.h" 20#include "base/trace_event/memory_dump_session_state.h" 21#include "base/trace_event/process_memory_maps.h" 22#include "base/trace_event/process_memory_totals.h" 23#include "build/build_config.h" 24 25// Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the 26// resident memory. 27// TODO(crbug.com/542671): COUNT_RESIDENT_BYTES_SUPPORTED is disabled on iOS 28// as it cause memory corruption on iOS 9.0+ devices. 29#if defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_IOS) 30#define COUNT_RESIDENT_BYTES_SUPPORTED 31#endif 32 33namespace base { 34namespace trace_event { 35 36class ConvertableToTraceFormat; 37class MemoryDumpManager; 38class MemoryDumpSessionState; 39class TracedValue; 40 41// ProcessMemoryDump is as a strongly typed container which holds the dumps 42// produced by the MemoryDumpProvider(s) for a specific process. 43class BASE_EXPORT ProcessMemoryDump { 44 public: 45 struct MemoryAllocatorDumpEdge { 46 MemoryAllocatorDumpGuid source; 47 MemoryAllocatorDumpGuid target; 48 int importance; 49 const char* type; 50 }; 51 52 // Maps allocator dumps absolute names (allocator_name/heap/subheap) to 53 // MemoryAllocatorDump instances. 54 using AllocatorDumpsMap = 55 SmallMap<hash_map<std::string, MemoryAllocatorDump*>>; 56 57 using HeapDumpsMap = 58 SmallMap<hash_map<std::string, scoped_refptr<TracedValue>>>; 59 60#if defined(COUNT_RESIDENT_BYTES_SUPPORTED) 61 // Returns the total bytes resident for a virtual address range, with given 62 // |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The 63 // value returned is valid only if the given range is currently mmapped by the 64 // process. The |start_address| must be page-aligned. 65 static size_t CountResidentBytes(void* start_address, size_t mapped_size); 66#endif 67 68 ProcessMemoryDump(const scoped_refptr<MemoryDumpSessionState>& session_state); 69 ~ProcessMemoryDump(); 70 71 // Creates a new MemoryAllocatorDump with the given name and returns the 72 // empty object back to the caller. 73 // Arguments: 74 // absolute_name: a name that uniquely identifies allocator dumps produced 75 // by this provider. It is possible to specify nesting by using a 76 // path-like string (e.g., v8/isolate1/heap1, v8/isolate1/heap2). 77 // Leading or trailing slashes are not allowed. 78 // guid: an optional identifier, unique among all processes within the 79 // scope of a global dump. This is only relevant when using 80 // AddOwnershipEdge() to express memory sharing. If omitted, 81 // it will be automatically generated. 82 // ProcessMemoryDump handles the memory ownership of its MemoryAllocatorDumps. 83 MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name); 84 MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name, 85 const MemoryAllocatorDumpGuid& guid); 86 87 // Looks up a MemoryAllocatorDump given its allocator and heap names, or 88 // nullptr if not found. 89 MemoryAllocatorDump* GetAllocatorDump(const std::string& absolute_name) const; 90 91 MemoryAllocatorDump* GetOrCreateAllocatorDump( 92 const std::string& absolute_name); 93 94 // Creates a shared MemoryAllocatorDump, to express cross-process sharing. 95 // Shared allocator dumps are allowed to have duplicate guids within the 96 // global scope, in order to reference the same dump from multiple processes. 97 // See the design doc goo.gl/keU6Bf for reference usage patterns. 98 MemoryAllocatorDump* CreateSharedGlobalAllocatorDump( 99 const MemoryAllocatorDumpGuid& guid); 100 101 // Looks up a shared MemoryAllocatorDump given its guid. 102 MemoryAllocatorDump* GetSharedGlobalAllocatorDump( 103 const MemoryAllocatorDumpGuid& guid) const; 104 105 // Returns the map of the MemoryAllocatorDumps added to this dump. 106 const AllocatorDumpsMap& allocator_dumps() const { return allocator_dumps_; } 107 108 // Adds a heap dump for the allocator with |absolute_name|. The |TracedValue| 109 // must have the correct format. |trace_event::HeapDumper| will generate such 110 // a value from a |trace_event::AllocationRegister|. 111 void AddHeapDump(const std::string& absolute_name, 112 scoped_refptr<TracedValue> heap_dump); 113 114 // Adds an ownership relationship between two MemoryAllocatorDump(s) with the 115 // semantics: |source| owns |target|, and has the effect of attributing 116 // the memory usage of |target| to |source|. |importance| is optional and 117 // relevant only for the cases of co-ownership, where it acts as a z-index: 118 // the owner with the highest importance will be attributed |target|'s memory. 119 void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source, 120 const MemoryAllocatorDumpGuid& target, 121 int importance); 122 void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source, 123 const MemoryAllocatorDumpGuid& target); 124 125 const std::vector<MemoryAllocatorDumpEdge>& allocator_dumps_edges() const { 126 return allocator_dumps_edges_; 127 } 128 129 // Utility method to add a suballocation relationship with the following 130 // semantics: |source| is suballocated from |target_node_name|. 131 // This creates a child node of |target_node_name| and adds an ownership edge 132 // between |source| and the new child node. As a result, the UI will not 133 // account the memory of |source| in the target node. 134 void AddSuballocation(const MemoryAllocatorDumpGuid& source, 135 const std::string& target_node_name); 136 137 const scoped_refptr<MemoryDumpSessionState>& session_state() const { 138 return session_state_; 139 } 140 141 // Removes all the MemoryAllocatorDump(s) contained in this instance. This 142 // ProcessMemoryDump can be safely reused as if it was new once this returns. 143 void Clear(); 144 145 // Merges all MemoryAllocatorDump(s) contained in |other| inside this 146 // ProcessMemoryDump, transferring their ownership to this instance. 147 // |other| will be an empty ProcessMemoryDump after this method returns. 148 // This is to allow dump providers to pre-populate ProcessMemoryDump instances 149 // and later move their contents into the ProcessMemoryDump passed as argument 150 // of the MemoryDumpProvider::OnMemoryDump(ProcessMemoryDump*) callback. 151 void TakeAllDumpsFrom(ProcessMemoryDump* other); 152 153 // Called at trace generation time to populate the TracedValue. 154 void AsValueInto(TracedValue* value) const; 155 156 ProcessMemoryTotals* process_totals() { return &process_totals_; } 157 bool has_process_totals() const { return has_process_totals_; } 158 void set_has_process_totals() { has_process_totals_ = true; } 159 160 ProcessMemoryMaps* process_mmaps() { return &process_mmaps_; } 161 bool has_process_mmaps() const { return has_process_mmaps_; } 162 void set_has_process_mmaps() { has_process_mmaps_ = true; } 163 164 private: 165 void AddAllocatorDumpInternal(MemoryAllocatorDump* mad); 166 167 ProcessMemoryTotals process_totals_; 168 bool has_process_totals_; 169 170 ProcessMemoryMaps process_mmaps_; 171 bool has_process_mmaps_; 172 173 AllocatorDumpsMap allocator_dumps_; 174 HeapDumpsMap heap_dumps_; 175 176 // ProcessMemoryDump handles the memory ownership of all its belongings. 177 ScopedVector<MemoryAllocatorDump> allocator_dumps_storage_; 178 179 // State shared among all PMDs instances created in a given trace session. 180 scoped_refptr<MemoryDumpSessionState> session_state_; 181 182 // Keeps track of relationships between MemoryAllocatorDump(s). 183 std::vector<MemoryAllocatorDumpEdge> allocator_dumps_edges_; 184 185 DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDump); 186}; 187 188} // namespace trace_event 189} // namespace base 190 191#endif // BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_ 192