forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess_memory_dump.h
275 lines (223 loc) · 11.8 KB
/
process_memory_dump.h
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
#define BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
#include <stddef.h>
#include <map>
#include <unordered_map>
#include <vector>
#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/trace_event/heap_profiler_serialization_state.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_allocator_dump_guid.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/process_memory_maps.h"
#include "base/trace_event/process_memory_totals.h"
#include "build/build_config.h"
// Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the
// resident memory.
#if (defined(OS_POSIX) && !defined(OS_NACL)) || defined(OS_WIN)
#define COUNT_RESIDENT_BYTES_SUPPORTED
#endif
namespace base {
class UnguessableToken;
namespace trace_event {
class HeapProfilerSerializationState;
class TracedValue;
// ProcessMemoryDump is as a strongly typed container which holds the dumps
// produced by the MemoryDumpProvider(s) for a specific process.
class BASE_EXPORT ProcessMemoryDump {
public:
struct MemoryAllocatorDumpEdge {
MemoryAllocatorDumpGuid source;
MemoryAllocatorDumpGuid target;
int importance;
const char* type;
bool overridable;
};
// Maps allocator dumps absolute names (allocator_name/heap/subheap) to
// MemoryAllocatorDump instances.
using AllocatorDumpsMap =
std::unordered_map<std::string, std::unique_ptr<MemoryAllocatorDump>>;
using HeapDumpsMap =
std::unordered_map<std::string, std::unique_ptr<TracedValue>>;
// Stores allocator dump edges indexed by source allocator dump GUID.
using AllocatorDumpEdgesMap =
std::map<MemoryAllocatorDumpGuid, MemoryAllocatorDumpEdge>;
#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
// Returns the number of bytes in a kernel memory page. Some platforms may
// have a different value for kernel page sizes from user page sizes. It is
// important to use kernel memory page sizes for resident bytes calculation.
// In most cases, the two are the same.
static size_t GetSystemPageSize();
// Returns the total bytes resident for a virtual address range, with given
// |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The
// value returned is valid only if the given range is currently mmapped by the
// process. The |start_address| must be page-aligned.
static size_t CountResidentBytes(void* start_address, size_t mapped_size);
#endif
ProcessMemoryDump(scoped_refptr<HeapProfilerSerializationState>
heap_profiler_serialization_state,
const MemoryDumpArgs& dump_args);
~ProcessMemoryDump();
// Creates a new MemoryAllocatorDump with the given name and returns the
// empty object back to the caller.
// Arguments:
// absolute_name: a name that uniquely identifies allocator dumps produced
// by this provider. It is possible to specify nesting by using a
// path-like string (e.g., v8/isolate1/heap1, v8/isolate1/heap2).
// Leading or trailing slashes are not allowed.
// guid: an optional identifier, unique among all processes within the
// scope of a global dump. This is only relevant when using
// AddOwnershipEdge() to express memory sharing. If omitted,
// it will be automatically generated.
// ProcessMemoryDump handles the memory ownership of its MemoryAllocatorDumps.
MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name);
MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name,
const MemoryAllocatorDumpGuid& guid);
// Looks up a MemoryAllocatorDump given its allocator and heap names, or
// nullptr if not found.
MemoryAllocatorDump* GetAllocatorDump(const std::string& absolute_name) const;
MemoryAllocatorDump* GetOrCreateAllocatorDump(
const std::string& absolute_name);
// Creates a shared MemoryAllocatorDump, to express cross-process sharing.
// Shared allocator dumps are allowed to have duplicate guids within the
// global scope, in order to reference the same dump from multiple processes.
// See the design doc goo.gl/keU6Bf for reference usage patterns.
MemoryAllocatorDump* CreateSharedGlobalAllocatorDump(
const MemoryAllocatorDumpGuid& guid);
// Creates a shared MemoryAllocatorDump as CreateSharedGlobalAllocatorDump,
// but with a WEAK flag. A weak dump will be discarded unless a non-weak dump
// is created using CreateSharedGlobalAllocatorDump by at least one process.
// The WEAK flag does not apply if a non-weak dump with the same GUID already
// exists or is created later. All owners and children of the discarded dump
// will also be discarded transitively.
MemoryAllocatorDump* CreateWeakSharedGlobalAllocatorDump(
const MemoryAllocatorDumpGuid& guid);
// Looks up a shared MemoryAllocatorDump given its guid.
MemoryAllocatorDump* GetSharedGlobalAllocatorDump(
const MemoryAllocatorDumpGuid& guid) const;
// Returns the map of the MemoryAllocatorDumps added to this dump.
const AllocatorDumpsMap& allocator_dumps() const { return allocator_dumps_; }
// Dumps heap usage with |allocator_name|.
void DumpHeapUsage(
const std::unordered_map<base::trace_event::AllocationContext,
base::trace_event::AllocationMetrics>&
metrics_by_context,
base::trace_event::TraceEventMemoryOverhead& overhead,
const char* allocator_name);
// Adds an ownership relationship between two MemoryAllocatorDump(s) with the
// semantics: |source| owns |target|, and has the effect of attributing
// the memory usage of |target| to |source|. |importance| is optional and
// relevant only for the cases of co-ownership, where it acts as a z-index:
// the owner with the highest importance will be attributed |target|'s memory.
void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
const MemoryAllocatorDumpGuid& target,
int importance);
void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
const MemoryAllocatorDumpGuid& target);
// Adds edges that can be overriden by a later or earlier call to
// AddOwnershipEdge() with the same source and target with a different
// |importance| value.
void AddOverridableOwnershipEdge(const MemoryAllocatorDumpGuid& source,
const MemoryAllocatorDumpGuid& target,
int importance);
// Creates ownership edges for memory backed by base::SharedMemory. Handles
// the case of cross process sharing and importnace of ownership for the case
// with and without the base::SharedMemory dump provider. The new version
// should just use global dumps created by SharedMemoryTracker and this
// function handles the transition until we get SharedMemory IDs through mojo
// channel crbug.com/713763. The weak version creates a weak global dump.
// |client_local_dump_guid| The guid of the local dump created by the client
// of base::SharedMemory.
// |client_global_dump_guid| The global guid given by the clients to create
// ownership edges of their own. These global dumps will no longer be required
// after the transition.
// |shared_memory_guid| The ID of the base::SharedMemory that is assigned
// globally, used to create global dump edges in the new model.
// |importance| Importance of the global dump edges to say if the current
// process owns the memory segment.
void CreateSharedMemoryOwnershipEdge(
const MemoryAllocatorDumpGuid& client_local_dump_guid,
const MemoryAllocatorDumpGuid& client_global_dump_guid,
const UnguessableToken& shared_memory_guid,
int importance);
void CreateWeakSharedMemoryOwnershipEdge(
const MemoryAllocatorDumpGuid& client_local_dump_guid,
const MemoryAllocatorDumpGuid& client_global_dump_guid,
const UnguessableToken& shared_memory_guid,
int importance);
const AllocatorDumpEdgesMap& allocator_dumps_edges_for_testing() const {
return allocator_dumps_edges_;
}
// Utility method to add a suballocation relationship with the following
// semantics: |source| is suballocated from |target_node_name|.
// This creates a child node of |target_node_name| and adds an ownership edge
// between |source| and the new child node. As a result, the UI will not
// account the memory of |source| in the target node.
void AddSuballocation(const MemoryAllocatorDumpGuid& source,
const std::string& target_node_name);
const scoped_refptr<HeapProfilerSerializationState>&
heap_profiler_serialization_state() const {
return heap_profiler_serialization_state_;
}
// Removes all the MemoryAllocatorDump(s) contained in this instance. This
// ProcessMemoryDump can be safely reused as if it was new once this returns.
void Clear();
// Merges all MemoryAllocatorDump(s) contained in |other| inside this
// ProcessMemoryDump, transferring their ownership to this instance.
// |other| will be an empty ProcessMemoryDump after this method returns.
// This is to allow dump providers to pre-populate ProcessMemoryDump instances
// and later move their contents into the ProcessMemoryDump passed as argument
// of the MemoryDumpProvider::OnMemoryDump(ProcessMemoryDump*) callback.
void TakeAllDumpsFrom(ProcessMemoryDump* other);
// Called at trace generation time to populate the TracedValue.
void AsValueInto(TracedValue* value) const;
ProcessMemoryTotals* process_totals() { return &process_totals_; }
const ProcessMemoryTotals* process_totals() const { return &process_totals_; }
bool has_process_totals() const { return has_process_totals_; }
void set_has_process_totals() { has_process_totals_ = true; }
ProcessMemoryMaps* process_mmaps() { return &process_mmaps_; }
bool has_process_mmaps() const { return has_process_mmaps_; }
void set_has_process_mmaps() { has_process_mmaps_ = true; }
const HeapDumpsMap& heap_dumps() const { return heap_dumps_; }
const MemoryDumpArgs& dump_args() const { return dump_args_; }
private:
FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, BackgroundModeTest);
MemoryAllocatorDump* AddAllocatorDumpInternal(
std::unique_ptr<MemoryAllocatorDump> mad);
void CreateSharedMemoryOwnershipEdgeInternal(
const MemoryAllocatorDumpGuid& client_local_dump_guid,
const MemoryAllocatorDumpGuid& client_global_dump_guid,
const UnguessableToken& shared_memory_guid,
int importance,
bool is_weak);
MemoryAllocatorDump* GetBlackHoleMad();
ProcessMemoryTotals process_totals_;
bool has_process_totals_;
ProcessMemoryMaps process_mmaps_;
bool has_process_mmaps_;
AllocatorDumpsMap allocator_dumps_;
HeapDumpsMap heap_dumps_;
// State shared among all PMDs instances created in a given trace session.
scoped_refptr<HeapProfilerSerializationState>
heap_profiler_serialization_state_;
// Keeps track of relationships between MemoryAllocatorDump(s).
AllocatorDumpEdgesMap allocator_dumps_edges_;
// Level of detail of the current dump.
const MemoryDumpArgs dump_args_;
// This allocator dump is returned when an invalid dump is created in
// background mode. The attributes of the dump are ignored and not added to
// the trace.
std::unique_ptr<MemoryAllocatorDump> black_hole_mad_;
// When set to true, the DCHECK(s) for invalid dump creations on the
// background mode are disabled for testing.
static bool is_black_hole_non_fatal_for_testing_;
DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDump);
};
} // namespace trace_event
} // namespace base
#endif // BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_