gfx/skia/trunk/include/core/SkInstCnt.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:2638cb4b70a3
1 /*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9 #ifndef SkInstCnt_DEFINED
10 #define SkInstCnt_DEFINED
11
12 /*
13 * The instance counting system consists of three macros that create the
14 * instance counting machinery. A class is added to the system by adding:
15 * SK_DECLARE_INST_COUNT at the top of its declaration for derived classes
16 * SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class
17 * At the end of an application a call to all the "root" objects'
18 * CheckInstanceCount methods should be made
19 */
20 #include "SkTypes.h"
21
22 #if SK_ENABLE_INST_COUNT
23 // Static variables inside member functions below may be defined multiple times
24 // if Skia is being used as a dynamic library. Instance counting should be on
25 // only for static builds. See bug skia:2058.
26 #if defined(SKIA_DLL)
27 #error Instance counting works only when Skia is built as a static library.
28 #endif
29
30 #include "SkOnce.h"
31 #include "SkTArray.h"
32 #include "SkThread.h"
33 extern bool gPrintInstCount;
34
35 // The non-root classes just register themselves with their parent
36 #define SK_DECLARE_INST_COUNT(className) \
37 SK_DECLARE_INST_COUNT_INTERNAL(className, \
38 INHERITED::AddInstChild(CheckInstanceCount);)
39
40 // The root classes registers a function to print out the memory stats when
41 // the app ends
42 #define SK_DECLARE_INST_COUNT_ROOT(className) \
43 SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);)
44
45 #define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \
46 class SkInstanceCountHelper { \
47 public: \
48 SkInstanceCountHelper() { \
49 SK_DECLARE_STATIC_ONCE(once); \
50 SkOnce(&once, init, 0); \
51 sk_atomic_inc(GetInstanceCountPtr()); \
52 } \
53 \
54 static void init(int) { \
55 initStep \
56 } \
57 \
58 SkInstanceCountHelper(const SkInstanceCountHelper&) { \
59 sk_atomic_inc(GetInstanceCountPtr()); \
60 } \
61 \
62 ~SkInstanceCountHelper() { \
63 sk_atomic_dec(GetInstanceCountPtr()); \
64 } \
65 \
66 static int32_t* GetInstanceCountPtr() { \
67 static int32_t gInstanceCount; \
68 return &gInstanceCount; \
69 } \
70 \
71 static SkTArray<int (*)(int, bool)>*& GetChildren() { \
72 static SkTArray<int (*)(int, bool)>* gChildren; \
73 return gChildren; \
74 } \
75 \
76 static SkBaseMutex& GetChildrenMutex() { \
77 SK_DECLARE_STATIC_MUTEX(childrenMutex); \
78 return childrenMutex; \
79 } \
80 \
81 } fInstanceCountHelper; \
82 \
83 static int32_t GetInstanceCount() { \
84 return *SkInstanceCountHelper::GetInstanceCountPtr(); \
85 } \
86 \
87 static void exitPrint() { \
88 CheckInstanceCount(0, true); \
89 } \
90 \
91 static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \
92 if (gPrintInstCount && 0 != GetInstanceCount()) { \
93 SkDebugf("%*c Leaked %s: %d\n", \
94 4*level, ' ', #className, \
95 GetInstanceCount()); \
96 } \
97 if (NULL == SkInstanceCountHelper::GetChildren()) { \
98 return GetInstanceCount(); \
99 } \
100 SkTArray<int (*)(int, bool)>* children = \
101 SkInstanceCountHelper::GetChildren(); \
102 int childCount = children->count(); \
103 int count = GetInstanceCount(); \
104 for (int i = 0; i < childCount; ++i) { \
105 count -= (*(*children)[i])(level+1, cleanUp); \
106 } \
107 SkASSERT(count >= 0); \
108 if (gPrintInstCount && childCount > 0 && count > 0) { \
109 SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \
110 } \
111 if (cleanUp) { \
112 delete children; \
113 SkInstanceCountHelper::GetChildren() = NULL; \
114 } \
115 return GetInstanceCount(); \
116 } \
117 \
118 static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \
119 if (CheckInstanceCount != childCheckInstCnt) { \
120 SkAutoMutexAcquire ama(SkInstanceCountHelper::GetChildrenMutex()); \
121 if (NULL == SkInstanceCountHelper::GetChildren()) { \
122 SkInstanceCountHelper::GetChildren() = \
123 new SkTArray<int (*)(int, bool)>; \
124 } \
125 SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \
126 } \
127 }
128
129 #else
130 // Typically SK_ENABLE_INST_COUNT=0. Make sure the class declares public typedef INHERITED by
131 // causing a compile-time error if the typedef is missing. This way SK_ENABLE_INST_COUNT=1 stays
132 // compiling.
133 #define SK_DECLARE_INST_COUNT(className) static void AddInstChild() { INHERITED::AddInstChild(); }
134 #define SK_DECLARE_INST_COUNT_ROOT(className) static void AddInstChild() { }
135 #endif
136
137 // Following are deprecated. They are defined only for backwards API compatibility.
138 #define SK_DECLARE_INST_COUNT_TEMPLATE(className) SK_DECLARE_INST_COUNT(className)
139 #define SK_DEFINE_INST_COUNT(className)
140 #define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className)
141
142 #endif // SkInstCnt_DEFINED

mercurial