Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: base/trace_event/memory_usage_estimators.h

Issue 2382443006: Sync MDP: implement MemoryDumpProvider
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | components/sync/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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_USAGE_ESTIMATORS_H_
6 #define BASE_TRACE_EVENT_MEMORY_USAGE_ESTIMATORS_H_
7
8 #include <memory>
9 #include <set>
10 #include <string>
11 #include <type_traits>
12 #include <unordered_map>
13 #include <vector>
14
15 #include "base/strings/string16.h"
16
17 namespace base {
18 namespace trace_event {
19
20 inline size_t EstimateMemoryUsage(const std::string& string) {
21 #if defined(__GLIBCXX__) && _GLIBCXX_USE_CXX11_ABI == 0
22 // libstdc++ with COW std::string - each string allocates a header
23 // (see std::basic_string::_Rep_base). We don't take into account
24 // number of references, but we do handle 'empty string' case.
25 struct _Rep_base {
26 std::basic_string::size_type length;
27 std::basic_string::size_type capacity;
28 int refcount;
29 };
30 static const char* empty_cstr = nullptr;
31 if (!empty_cstr) empty_cstr = std::string().c_str();
32 return (string.c_str() == empty_cstr) ?
33 0 :
34 sizeof(_Rep_base) + (string.capacity() + 1);
35 #else
36 const char* cstr = string.c_str();
37 const char* inline_cstr = reinterpret_cast<const char*>(&string);
38 if (cstr >= inline_cstr && cstr < inline_cstr + sizeof(string)) {
39 // Inline string
40 return 0;
41 }
42 return string.capacity();
43 #endif
44 }
45
46 // TODO(dskiba): EstimateMemoryUsage(std::basic_string<T>)
47 inline size_t EstimateMemoryUsage(const base::string16& string) {
48 #if defined(__GLIBCXX__) && _GLIBCXX_USE_CXX11_ABI == 0
49 // See comment in EstimateMemoryUsage(std::string).
50 static const char16* empty_cstr = nullptr;
51 if (!empty_cstr) empty_cstr = base::string16().c_str();
52 return (string.c_str() == empty_cstr) ?
53 0 :
54 3 * sizeof(size_t) + (string.capacity() + 1) * sizeof(char16);
55 #else
56 const char* cstr = reinterpret_cast<const char*>(string.c_str());
57 const char* inline_cstr = reinterpret_cast<const char*>(&string);
58 if (cstr >= inline_cstr && cstr < inline_cstr + sizeof(string)) {
59 // Inline string
60 return 0;
61 }
62 return string.capacity() * sizeof(char16);
63 #endif
64 }
65
66 template <class T>
67 typename std::enable_if<
68 std::is_arithmetic<T>::value || std::is_enum<T>::value,
69 size_t>::type
70 EstimateMemoryUsage(T) { return 0; }
71
72 template <class T>
73 auto EstimateMemoryUsage(const T& object) ->
74 decltype(object.EstimateMemoryUsage()) {
75 static_assert(std::is_same<decltype(object.EstimateMemoryUsage()),
76 size_t>::value,
77 "EstimateMemoryUsage() must return size_t");
78 return object.EstimateMemoryUsage();
79 }
80
81 // Any template that recursively calls EstimateMemoryUsage() should be
82 // declared here first.
83
84 template <class T>
85 size_t EstimateMemoryUsage(const std::unique_ptr<T>& ptr);
86
87 template <class F, class S>
88 size_t EstimateMemoryUsage(const std::pair<F, S>& pair);
89
90 template <class T, size_t N>
91 size_t EstimateMemoryUsage(T (&array)[N]);
92
93 template <class T, class A>
94 size_t EstimateMemoryUsage(const std::vector<T, A>& vector);
95
96 template <class T, class C, class A>
97 size_t EstimateMemoryUsage(const std::set<T, C, A>& set);
98
99 template <class K, class V, class H, class KE, class A>
100 size_t EstimateMemoryUsage(
101 const std::unordered_map<K, V, H, KE, A>& map);
102
103 // Definitions
104
105 template <class T>
106 size_t InternalEstimateItemMemoryUsage(T* pointer) {
107 // By default pointers treated as not owning
108 return 0;
109 }
110
111 template <class T>
112 size_t InternalEstimateItemMemoryUsage(const T& value) {
113 return EstimateMemoryUsage(value);
114 }
115
116 template <class T>
117 size_t EstimateMemoryUsage(const std::unique_ptr<T>& ptr) {
118 return ptr ? (sizeof(T) + EstimateMemoryUsage(*ptr)) : 0;
119 }
120
121 template <class F, class S>
122 size_t EstimateMemoryUsage(const std::pair<F, S>& pair) {
123 return EstimateMemoryUsage(pair.first) +
124 EstimateMemoryUsage(pair.second);
125 }
126
127 template <class T, size_t N>
128 size_t EstimateMemoryUsage(T (&array)[N]) {
129 size_t memory_usage = 0;
130 for (const auto& item: array) {
131 memory_usage += EstimateMemoryUsage(item);
132 }
133 return memory_usage;
134 }
135
136 template <class T, class A>
137 size_t EstimateMemoryUsage(const std::vector<T, A>& vector) {
138 size_t memory_usage = vector.capacity() * sizeof(T);
139 for (const auto& element: vector) {
140 memory_usage += EstimateMemoryUsage(element);
141 }
142 return memory_usage;
143 }
144
145 template <class T, class C, class A>
146 size_t EstimateMemoryUsage(const std::set<T, C, A>& set) {
147 // TODO(dskiba): revisit, likely not accurate enough
148 size_t memory_usage = set.size() * sizeof(T);
149 for (const auto& element: set) {
150 memory_usage += EstimateMemoryUsage(element);
151 }
152 return memory_usage;
153 }
154
155 template <class K, class V, class H, class KE, class A>
156 size_t InternalEstimateShallowMemoryUsage(
157 const std::unordered_map<K, V, H, KE, A>& map) {
158 struct Node {
159 typename std::unordered_map<K, V, H, KE, A>::value_type value;
160 Node* next;
161 Node* prev;
162 };
163 using Bucket = Node*;
164 return map.bucket_count() * sizeof(Bucket) + map.size() * sizeof(Node);
165 }
166
167 template <class K, class V, class H, class KE, class A>
168 size_t EstimateMemoryUsage(
169 const std::unordered_map<K, V, H, KE, A>& map) {
170 size_t memory_usage = InternalEstimateShallowMemoryUsage(map);
171 for (const auto& item: map) {
172 memory_usage += InternalEstimateItemMemoryUsage(item.first) +
173 InternalEstimateItemMemoryUsage(item.second);
174 }
175 return memory_usage;
176 }
177
178 template <class K, class V, class H, class KE, class A, class Estimator>
179 size_t EstimateMemoryUsage(
180 const std::unordered_map<K, V, H, KE, A>& map,
181 Estimator estimator) {
182 size_t memory_usage = InternalEstimateShallowMemoryUsage(map);
183 for (const auto& item: map) {
184 memory_usage += estimator(item.first) +
185 estimator(item.second);
186 }
187 return memory_usage;
188 }
189
190 } // namespace trace_event
191 } // namespace base
192
193 #endif // BASE_TRACE_EVENT_MEMORY_USAGE_ESTIMATORS_H_
OLDNEW
« no previous file with comments | « no previous file | components/sync/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698