SkInstCnt.h revision 73e19fb1ba2562048c6987272c8d73eee6a44242
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 * SK_DEFINE_INST_COUNT at the top of its .cpp file (for both kinds). 18 * At the end of an application a call to all the "root" objects' 19 * CheckInstanceCount methods should be made 20 */ 21#ifdef SK_DEBUG 22#include "SkTArray.h" 23 24#define SK_DECLARE_INST_COUNT(className) \ 25 SK_DECLARE_INST_COUNT_INTERNAL(className, \ 26 INHERITED::AddInstChild(CheckInstanceCount);) 27 28#define SK_DECLARE_INST_COUNT_ROOT(className) \ 29 SK_DECLARE_INST_COUNT_INTERNAL(className, ;) 30 31#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \ 32 class SkInstanceCountHelper { \ 33 public: \ 34 typedef int (*PFCheckInstCnt)(int level); \ 35 SkInstanceCountHelper() { \ 36 if (!gInited) { \ 37 initStep \ 38 gInited = true; \ 39 } \ 40 gInstanceCount++; \ 41 } \ 42 \ 43 SkInstanceCountHelper(const SkInstanceCountHelper& other) { \ 44 gInstanceCount++; \ 45 } \ 46 \ 47 ~SkInstanceCountHelper() { \ 48 gInstanceCount--; \ 49 } \ 50 \ 51 static int32_t gInstanceCount; \ 52 static bool gInited; \ 53 static SkTArray<PFCheckInstCnt> gChildren; \ 54 } fInstanceCountHelper; \ 55 \ 56 static int32_t GetInstanceCount() { \ 57 return SkInstanceCountHelper::gInstanceCount; \ 58 } \ 59 \ 60 static int CheckInstanceCount(int level = 0) { \ 61 if (0 != SkInstanceCountHelper::gInstanceCount) { \ 62 SkDebugf("%*c Leaked %s: %d\n", \ 63 4*level, ' ', #className, \ 64 SkInstanceCountHelper::gInstanceCount); \ 65 } \ 66 int childCount = SkInstanceCountHelper::gChildren.count(); \ 67 int count = SkInstanceCountHelper::gInstanceCount; \ 68 for (int i = 0; i < childCount; ++i) { \ 69 count -= (*SkInstanceCountHelper::gChildren[i])(level+1); \ 70 } \ 71 SkASSERT(count >= 0); \ 72 if (childCount > 0 && count > 0) { \ 73 SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \ 74 } \ 75 return SkInstanceCountHelper::gInstanceCount; \ 76 } \ 77 \ 78 static void AddInstChild(SkInstanceCountHelper::PFCheckInstCnt \ 79 childCheckInstCnt) { \ 80 if (CheckInstanceCount != childCheckInstCnt) { \ 81 SkInstanceCountHelper::gChildren.push_back(childCheckInstCnt); \ 82 } \ 83 } 84 85#define SK_DEFINE_INST_COUNT(className) \ 86 int32_t className::SkInstanceCountHelper::gInstanceCount = 0; \ 87 bool className::SkInstanceCountHelper::gInited = false; \ 88 SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt> \ 89 className::SkInstanceCountHelper::gChildren; 90 91#else 92#define SK_DECLARE_INST_COUNT(className) 93#define SK_DECLARE_INST_COUNT_ROOT(className) 94#define SK_DEFINE_INST_COUNT(className) 95#endif 96 97#endif // SkInstCnt_DEFINED 98