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