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