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/traced_value.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