1 // Copyright 2015 The Chromium Authors 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_MEMORY_ALLOCATOR_DUMP_H_ 6 #define BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_ 7 8 #include <stdint.h> 9 10 #include <iosfwd> 11 #include <memory> 12 #include <string> 13 #include <vector> 14 15 #include "base/base_export.h" 16 #include "base/trace_event/memory_allocator_dump_guid.h" 17 #include "base/trace_event/memory_dump_request_args.h" 18 #include "base/unguessable_token.h" 19 #include "third_party/abseil-cpp/absl/types/optional.h" 20 21 namespace perfetto { 22 namespace protos { 23 namespace pbzero { 24 class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode; 25 } 26 } // namespace protos 27 } // namespace perfetto 28 29 namespace base { 30 namespace trace_event { 31 32 class ProcessMemoryDump; 33 class TracedValue; 34 35 // Data model for user-land memory allocator dumps. 36 class BASE_EXPORT MemoryAllocatorDump { 37 public: 38 enum Flags { 39 DEFAULT = 0, 40 41 // A dump marked weak will be discarded by TraceViewer. 42 WEAK = 1 << 0, 43 }; 44 45 // In the TraceViewer UI table each MemoryAllocatorDump becomes 46 // a row and each Entry generates a column (if it doesn't already 47 // exist). 48 struct BASE_EXPORT Entry { 49 enum EntryType { 50 kUint64, 51 kString, 52 }; 53 54 // By design name, units and value_string are always coming from 55 // indefinitely lived const char* strings, the only reason we copy 56 // them into a std::string is to handle Mojo (de)serialization. 57 // TODO(hjd): Investigate optimization (e.g. using StringPiece). 58 Entry(); // Only for deserialization. 59 Entry(std::string name, std::string units, uint64_t value); 60 Entry(std::string name, std::string units, std::string value); 61 Entry(Entry&& other) noexcept; 62 Entry(const Entry&) = delete; 63 Entry& operator=(const Entry&) = delete; 64 Entry& operator=(Entry&& other); 65 bool operator==(const Entry& rhs) const; 66 67 std::string name; 68 std::string units; 69 70 EntryType entry_type; 71 72 uint64_t value_uint64; 73 std::string value_string; 74 }; 75 76 MemoryAllocatorDump(const std::string& absolute_name, 77 MemoryDumpLevelOfDetail, 78 const MemoryAllocatorDumpGuid&); 79 MemoryAllocatorDump(const MemoryAllocatorDump&) = delete; 80 MemoryAllocatorDump& operator=(const MemoryAllocatorDump&) = delete; 81 ~MemoryAllocatorDump(); 82 83 // Standard attribute |name|s for the AddScalar and AddString() methods. 84 static const char kNameSize[]; // To represent allocated space. 85 static const char kNameObjectCount[]; // To represent number of objects. 86 87 // Standard attribute |unit|s for the AddScalar and AddString() methods. 88 static const char kUnitsBytes[]; // Unit name to represent bytes. 89 static const char kUnitsObjects[]; // Unit name to represent #objects. 90 91 // Constants used only internally and by tests. 92 static const char kTypeScalar[]; // Type name for scalar attributes. 93 static const char kTypeString[]; // Type name for string attributes. 94 95 // Setters for scalar attributes. Some examples: 96 // - "size" column (all dumps are expected to have at least this one): 97 // AddScalar(kNameSize, kUnitsBytes, 1234); 98 // - Some extra-column reporting internal details of the subsystem: 99 // AddScalar("number_of_freelist_entries", kUnitsObjects, 42) 100 // - Other informational column: 101 // AddString("kitten", "name", "shadow"); 102 void AddScalar(const char* name, const char* units, uint64_t value); 103 void AddString(const char* name, const char* units, const std::string& value); 104 105 // Absolute name, unique within the scope of an entire ProcessMemoryDump. absolute_name()106 const std::string& absolute_name() const { return absolute_name_; } 107 108 // Called at trace generation time to populate the TracedValue. 109 void AsValueInto(TracedValue* value) const; 110 111 void AsProtoInto( 112 perfetto::protos::pbzero:: 113 MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode* memory_node) const; 114 115 // Get the size for this dump. 116 // The size is the value set with AddScalar(kNameSize, kUnitsBytes, size); 117 // TODO(hjd): this should return an optional<uint64_t>. 118 uint64_t GetSizeInternal() const; 119 level_of_detail()120 MemoryDumpLevelOfDetail level_of_detail() const { return level_of_detail_; } 121 122 // Use enum Flags to set values. set_flags(int flags)123 void set_flags(int flags) { flags_ |= flags; } clear_flags(int flags)124 void clear_flags(int flags) { flags_ &= ~flags; } flags()125 int flags() const { return flags_; } 126 127 // |guid| is an optional global dump identifier, unique across all processes 128 // within the scope of a global dump. It is only required when using the 129 // graph APIs (see TODO_method_name) to express retention / suballocation or 130 // cross process sharing. See crbug.com/492102 for design docs. 131 // Subsequent MemoryAllocatorDump(s) with the same |absolute_name| are 132 // expected to have the same guid. guid()133 const MemoryAllocatorDumpGuid& guid() const { return guid_; } 134 entries()135 const std::vector<Entry>& entries() const { return entries_; } 136 137 // Only for mojo serialization, which can mutate the collection. mutable_entries_for_serialization()138 std::vector<Entry>* mutable_entries_for_serialization() const { 139 cached_size_.reset(); // The caller can mutate the collection. 140 141 // Mojo takes a const input argument even for move-only types that can be 142 // mutate while serializing (like this one). Hence the const_cast. 143 return const_cast<std::vector<Entry>*>(&entries_); 144 } 145 146 private: 147 const std::string absolute_name_; 148 MemoryAllocatorDumpGuid guid_; 149 MemoryDumpLevelOfDetail level_of_detail_; 150 int flags_; // See enum Flags. 151 mutable absl::optional<uint64_t> 152 cached_size_; // Lazy, for GetSizeInternal(). 153 std::vector<Entry> entries_; 154 }; 155 156 // This is required by gtest to print a readable output on test failures. 157 void BASE_EXPORT PrintTo(const MemoryAllocatorDump::Entry&, std::ostream*); 158 159 } // namespace trace_event 160 } // namespace base 161 162 #endif // BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_ 163