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