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

Side by Side Diff: Source/WTF/wtf/MemoryInstrumentation.h

Issue 14238015: Move Source/WTF/wtf to Source/wtf (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef MemoryInstrumentation_h
32 #define MemoryInstrumentation_h
33
34 #include <wtf/OwnPtr.h>
35 #include <wtf/PassOwnPtr.h>
36 #include <wtf/RefPtr.h>
37
38 #define DEBUG_POINTER_INSTRUMENTATION 0
39
40 namespace WTF {
41
42 class MemoryClassInfo;
43 class MemoryObjectInfo;
44 class MemoryInstrumentation;
45
46 typedef const char* MemoryObjectType;
47
48 enum MemberType {
49 PointerMember,
50 ReferenceMember,
51 RetainingPointer,
52 LastMemberTypeEntry
53 };
54
55 template<typename T> void reportMemoryUsage(const T*, MemoryObjectInfo*);
56
57 class MemoryInstrumentationClient {
58 public:
59 virtual ~MemoryInstrumentationClient() { }
60 virtual void countObjectSize(const void*, MemoryObjectType, size_t) = 0;
61 virtual bool visited(const void*) = 0;
62 virtual bool checkCountedObject(const void*) = 0;
63
64 virtual void reportNode(const MemoryObjectInfo&) = 0;
65 virtual void reportEdge(const void* target, const char* edgeName, MemberType ) = 0;
66 virtual void reportLeaf(const MemoryObjectInfo&, const char* edgeName) = 0;
67 virtual void reportBaseAddress(const void* base, const void* real) = 0;
68 virtual int registerString(const char*) = 0;
69 };
70
71 class MemoryInstrumentation {
72 public:
73 WTF_EXPORT_PRIVATE explicit MemoryInstrumentation(MemoryInstrumentationClien t*);
74 WTF_EXPORT_PRIVATE virtual ~MemoryInstrumentation();
75
76 template <typename T> void addRootObject(const T& t, MemoryObjectType object Type = 0)
77 {
78 MemberTypeTraits<T>::addRootObject(this, t, objectType);
79 processDeferredObjects();
80 }
81
82 template <typename T> void addRootObject(const OwnPtr<T>&, MemoryObjectType = 0); // Link time guard.
83 template <typename T> void addRootObject(const RefPtr<T>&, MemoryObjectType = 0); // Link time guard.
84
85 protected:
86 class WrapperBase {
87 public:
88 WTF_EXPORT_PRIVATE WrapperBase(MemoryObjectType, const void* pointer);
89 virtual ~WrapperBase() { }
90 WTF_EXPORT_PRIVATE void process(MemoryInstrumentation*);
91 WTF_EXPORT_PRIVATE void processPointer(MemoryInstrumentation*, bool isRo ot);
92 WTF_EXPORT_PRIVATE void processRootObjectRef(MemoryInstrumentation*);
93
94 protected:
95 virtual void callReportMemoryUsage(MemoryObjectInfo*) = 0;
96 const void* m_pointer;
97 const MemoryObjectType m_ownerObjectType;
98
99 private:
100 #if DEBUG_POINTER_INSTRUMENTATION
101 static const int s_maxCallStackSize = 32;
102 void* m_callStack[s_maxCallStackSize];
103 int m_callStackSize;
104 #endif
105 };
106
107 private:
108 void countObjectSize(const void* object, MemoryObjectType objectType, size_t size) { m_client->countObjectSize(object, objectType, size); }
109 bool visited(const void* pointer) { return m_client->visited(pointer); }
110 bool checkCountedObject(const void* pointer) { return m_client->checkCounted Object(pointer); }
111
112 WTF_EXPORT_PRIVATE void reportEdge(const void* target, const char* edgeName, MemberType);
113
114 virtual void deferObject(PassOwnPtr<WrapperBase>) = 0;
115 virtual void processDeferredObjects() = 0;
116
117 WTF_EXPORT_PRIVATE static MemoryObjectType getObjectType(MemoryObjectInfo*);
118
119 friend class MemoryObjectInfo;
120 friend class MemoryClassInfo;
121 template<typename T> friend void reportMemoryUsage(const T*, MemoryObjectInf o*);
122
123 template <typename Type>
124 class IsInstrumented {
125 class yes {
126 char m;
127 };
128
129 class no {
130 yes m[2];
131 };
132
133 struct BaseMixin {
134 void reportMemoryUsage(MemoryObjectInfo*) const { }
135 };
136
137 #if COMPILER(MSVC)
138 #pragma warning(push)
139 #pragma warning(disable: 4624) // Disable warning: destructor could not be gener ated because a base class destructor is inaccessible.
140 #endif
141 struct Base : public Type, public BaseMixin { };
142 #if COMPILER(MSVC)
143 #pragma warning(pop)
144 #endif
145
146 template <typename T, T t> class Helper { };
147
148 template <typename U> static no deduce(U*, Helper<void (BaseMixin::*)(Me moryObjectInfo*) const, &U::reportMemoryUsage>* = 0);
149 static yes deduce(...);
150
151 public:
152 static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
153
154 };
155
156 template <int>
157 struct InstrumentationSelector {
158 template <typename T> static void reportObjectMemoryUsage(const T*, Memo ryObjectInfo*);
159 };
160
161 template<typename T> class Wrapper : public WrapperBase {
162 public:
163 Wrapper(const T* pointer, MemoryObjectType);
164
165 protected:
166 virtual void callReportMemoryUsage(MemoryObjectInfo*) OVERRIDE;
167 };
168
169 template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjec tInfo, const char* edgeName, MemberType memberType)
170 {
171 MemberTypeTraits<T>::addObject(this, t, ownerObjectInfo, edgeName, membe rType);
172 }
173 void addRawBuffer(const void* buffer, MemoryObjectType ownerObjectType, size _t size, const char* className = 0, const char* edgeName = 0)
174 {
175 if (!buffer || visited(buffer))
176 return;
177 countObjectSize(buffer, ownerObjectType, size);
178 reportLinkToBuffer(buffer, ownerObjectType, size, className, edgeName);
179 }
180 WTF_EXPORT_PRIVATE void reportLinkToBuffer(const void* buffer, MemoryObjectT ype ownerObjectType, size_t, const char* nodeName, const char* edgeName);
181
182 template<typename T>
183 struct MemberTypeTraits { // Default ReferenceMember implementation.
184 static void addObject(MemoryInstrumentation* instrumentation, const T& t , MemoryObjectInfo* ownerObjectInfo, const char* edgeName, MemberType)
185 {
186 instrumentation->addObjectImpl(&t, ownerObjectInfo, ReferenceMember, edgeName);
187 }
188
189 static void addRootObject(MemoryInstrumentation* instrumentation, const T& t, MemoryObjectType objectType)
190 {
191 Wrapper<T>(&t, objectType).processRootObjectRef(instrumentation);
192 }
193 };
194
195 template<typename T>
196 struct MemberTypeTraits<T*> { // Custom PointerMember implementation.
197 static void addObject(MemoryInstrumentation* instrumentation, const T* c onst& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName, MemberType mem berType)
198 {
199 instrumentation->addObjectImpl(t, ownerObjectInfo, memberType != Las tMemberTypeEntry ? memberType : PointerMember, edgeName);
200 }
201
202 static void addRootObject(MemoryInstrumentation* instrumentation, const T* const& t, MemoryObjectType objectType)
203 {
204 if (t && !instrumentation->visited(t))
205 Wrapper<T>(t, objectType).processPointer(instrumentation, true);
206 }
207 };
208
209 template<typename T> void addObjectImpl(const T*, MemoryObjectInfo*, MemberT ype, const char* edgeName);
210 template<typename T> void addObjectImpl(const OwnPtr<T>*, MemoryObjectInfo*, MemberType, const char* edgeName);
211 template<typename T> void addObjectImpl(const RefPtr<T>*, MemoryObjectInfo*, MemberType, const char* edgeName);
212
213 MemoryInstrumentationClient* m_client;
214 };
215
216 // We are trying to keep the signature of the function as small as possible
217 // because it significantly affects the binary size.
218 // We caluclates class name for 624 classes at the moment.
219 // So one extra byte of the function signature increases the binary size to 624 extra bytes.
220 #if COMPILER(MSVC)
221 template <typename T> struct FN {
222 static char* fn() { return const_cast<char*>(__FUNCTION__); }
223 };
224
225 template <typename T> char* fn() { return FN<T>::fn(); }
226 #else
227 template <typename T> char* fn() { return const_cast<char*>(__PRETTY_FUNCTION__) ; }
228 #endif
229
230 class MemoryClassInfo {
231 public:
232 template<typename T>
233 MemoryClassInfo(MemoryObjectInfo* memoryObjectInfo, const T* pointer, Memory ObjectType objectType = 0, size_t actualSize = sizeof(T))
234 : m_memoryObjectInfo(memoryObjectInfo)
235 , m_memoryInstrumentation(0)
236 , m_objectType(0)
237 , m_skipMembers(false)
238 {
239 init(pointer, fn<T>(), objectType, actualSize);
240 }
241
242 template<typename M> void addMember(const M& member, const char* edgeName = 0, MemberType memberType = LastMemberTypeEntry)
243 {
244 if (!m_skipMembers)
245 m_memoryInstrumentation->addObject(member, m_memoryObjectInfo, edgeN ame, memberType);
246 }
247
248 WTF_EXPORT_PRIVATE void addRawBuffer(const void* buffer, size_t, const char* className = 0, const char* edgeName = 0);
249 WTF_EXPORT_PRIVATE void addPrivateBuffer(size_t, MemoryObjectType ownerObjec tType = 0, const char* className = 0, const char* edgeName = 0);
250 WTF_EXPORT_PRIVATE void setCustomAllocation(bool);
251
252 void addWeakPointer(void*) { }
253 template<typename M> void ignoreMember(const M&) { }
254
255 WTF_EXPORT_PRIVATE static void callReportObjectInfo(MemoryObjectInfo*, const void* pointer, const char* stringWithClassName, MemoryObjectType, size_t actual Size);
256
257 private:
258 WTF_EXPORT_PRIVATE void init(const void* pointer, const char* stringWithClas sName, MemoryObjectType, size_t actualSize);
259
260 MemoryObjectInfo* m_memoryObjectInfo;
261 MemoryInstrumentation* m_memoryInstrumentation;
262 MemoryObjectType m_objectType;
263 bool m_skipMembers;
264 };
265
266 template <>
267 template <typename T>
268 void MemoryInstrumentation::InstrumentationSelector<true>::reportObjectMemoryUsa ge(const T* object, MemoryObjectInfo* memoryObjectInfo)
269 {
270 object->reportMemoryUsage(memoryObjectInfo);
271 }
272
273 template <>
274 template <typename T>
275 void MemoryInstrumentation::InstrumentationSelector<false>::reportObjectMemoryUs age(const T* object, MemoryObjectInfo* memoryObjectInfo)
276 {
277 MemoryClassInfo::callReportObjectInfo(memoryObjectInfo, object, fn<T>(), 0, sizeof(T));
278 }
279
280 template<typename T>
281 void reportMemoryUsage(const T* object, MemoryObjectInfo* memoryObjectInfo)
282 {
283 MemoryInstrumentation::InstrumentationSelector<MemoryInstrumentation::IsInst rumented<T>::result>::reportObjectMemoryUsage(object, memoryObjectInfo);
284 }
285
286 template<typename T>
287 void MemoryInstrumentation::addObjectImpl(const T* object, MemoryObjectInfo* own erObjectInfo, MemberType memberType, const char* edgeName)
288 {
289 if (memberType == PointerMember)
290 return;
291 if (memberType == ReferenceMember)
292 reportMemoryUsage(object, ownerObjectInfo);
293 else {
294 if (!object)
295 return;
296 reportEdge(object, edgeName, memberType);
297 if (visited(object))
298 return;
299 deferObject(adoptPtr(new Wrapper<T>(object, getObjectType(ownerObjectInf o))));
300 }
301 }
302
303 template<typename T>
304 void MemoryInstrumentation::addObjectImpl(const OwnPtr<T>* object, MemoryObjectI nfo* ownerObjectInfo, MemberType memberType, const char* edgeName)
305 {
306 if (memberType == PointerMember && !visited(object))
307 countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object)) ;
308 addObjectImpl(object->get(), ownerObjectInfo, RetainingPointer, edgeName);
309 }
310
311 template<typename T>
312 void MemoryInstrumentation::addObjectImpl(const RefPtr<T>* object, MemoryObjectI nfo* ownerObjectInfo, MemberType memberType, const char* edgeName)
313 {
314 if (memberType == PointerMember && !visited(object))
315 countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object)) ;
316 addObjectImpl(object->get(), ownerObjectInfo, RetainingPointer, edgeName);
317 }
318
319 template<typename T>
320 MemoryInstrumentation::Wrapper<T>::Wrapper(const T* pointer, MemoryObjectType ow nerObjectType)
321 : WrapperBase(ownerObjectType, pointer)
322 {
323 }
324
325 template<typename T>
326 void MemoryInstrumentation::Wrapper<T>::callReportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
327 {
328 reportMemoryUsage(static_cast<const T*>(m_pointer), memoryObjectInfo);
329 }
330
331 // Link time guard for classes with external memory instrumentation.
332 template<typename T, size_t inlineCapacity> class Vector;
333 template<typename T, size_t inlineCapacity> void reportMemoryUsage(const Vector< T, inlineCapacity>*, MemoryObjectInfo*);
334
335 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTrai tsArg, typename MappedTraitsArg> class HashMap;
336 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTrai tsArg, typename MappedTraitsArg> void reportMemoryUsage(const HashMap<KeyArg, Ma ppedArg, HashArg, KeyTraitsArg, MappedTraitsArg>*, MemoryObjectInfo*);
337
338 template<typename ValueArg, typename HashArg, typename TraitsArg> class HashCoun tedSet;
339 template<typename ValueArg, typename HashArg, typename TraitsArg> void reportMem oryUsage(const HashCountedSet<ValueArg, HashArg, TraitsArg>*, MemoryObjectInfo*) ;
340
341 template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListH ashSet;
342 template<typename ValueArg, size_t inlineCapacity, typename HashArg> void report MemoryUsage(const ListHashSet<ValueArg, inlineCapacity, HashArg>*, MemoryObjectI nfo*);
343
344 class String;
345 void reportMemoryUsage(const String*, MemoryObjectInfo*);
346
347 class StringImpl;
348 void reportMemoryUsage(const StringImpl*, MemoryObjectInfo*);
349
350 class AtomicString;
351 void reportMemoryUsage(const AtomicString*, MemoryObjectInfo*);
352
353 class CString;
354 void reportMemoryUsage(const CString*, MemoryObjectInfo*);
355
356 class CStringBuffer;
357 void reportMemoryUsage(const CStringBuffer*, MemoryObjectInfo*);
358
359 class ParsedURL;
360 void reportMemoryUsage(const ParsedURL*, MemoryObjectInfo*);
361
362 class URLString;
363 void reportMemoryUsage(const URLString*, MemoryObjectInfo*);
364
365 } // namespace WTF
366
367 #endif // !defined(MemoryInstrumentation_h)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698