SkInstCnt.h revision b74af872cc1ce45768df3ae03fa86ad3ed76b582
1f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com/* 2f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * Copyright 2012 Google Inc. 3f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * 4f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 5f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * found in the LICENSE file. 6977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com */ 7977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 8977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 9977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#ifndef SkInstCnt_DEFINED 10977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#define SkInstCnt_DEFINED 11977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 12977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com/* 13977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com * The instance counting system consists of three macros that create the 14977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com * instance counting machinery. A class is added to the system by adding: 154d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * SK_DECLARE_INST_COUNT at the top of its declaration for derived classes 164d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class 174d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * SK_DEFINE_INST_COUNT at the top of its .cpp file (for both kinds). 184d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * At the end of an application a call to all the "root" objects' 194d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * CheckInstanceCount methods should be made 20977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com */ 21b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com#ifdef SK_ENABLE_INST_COUNT 224d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#include "SkTArray.h" 234d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com 24b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.comextern bool gPrintInstCount; 25b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com 264d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT(className) \ 274d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SK_DECLARE_INST_COUNT_INTERNAL(className, \ 284d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com INHERITED::AddInstChild(CheckInstanceCount);) 294d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com 304d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_ROOT(className) \ 314d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SK_DECLARE_INST_COUNT_INTERNAL(className, ;) 324d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com 334d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \ 344d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com class SkInstanceCountHelper { \ 354d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com public: \ 3673e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com typedef int (*PFCheckInstCnt)(int level); \ 374d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper() { \ 384d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com if (!gInited) { \ 394d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com initStep \ 404d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInited = true; \ 414d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 424d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInstanceCount++; \ 434d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 444d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 454d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper(const SkInstanceCountHelper& other) { \ 464d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInstanceCount++; \ 474d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 484d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 494d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com ~SkInstanceCountHelper() { \ 504d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInstanceCount--; \ 514d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 524d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 534d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com static int32_t gInstanceCount; \ 544d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com static bool gInited; \ 554d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com static SkTArray<PFCheckInstCnt> gChildren; \ 564d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } fInstanceCountHelper; \ 574d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 584da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com static int32_t GetInstanceCount() { \ 594da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com return SkInstanceCountHelper::gInstanceCount; \ 604da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com } \ 614da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com \ 6273e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com static int CheckInstanceCount(int level = 0) { \ 63b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com if (gPrintInstCount && 0 != SkInstanceCountHelper::gInstanceCount) {\ 6473e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com SkDebugf("%*c Leaked %s: %d\n", \ 6515e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 4*level, ' ', #className, \ 664d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper::gInstanceCount); \ 674d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 6873e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com int childCount = SkInstanceCountHelper::gChildren.count(); \ 6973e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com int count = SkInstanceCountHelper::gInstanceCount; \ 7073e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com for (int i = 0; i < childCount; ++i) { \ 7173e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com count -= (*SkInstanceCountHelper::gChildren[i])(level+1); \ 724d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 7373e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com SkASSERT(count >= 0); \ 74b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com if (gPrintInstCount && childCount > 0 && count > 0) { \ 7573e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \ 7673e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com } \ 7773e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com return SkInstanceCountHelper::gInstanceCount; \ 784d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 794d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 804d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com static void AddInstChild(SkInstanceCountHelper::PFCheckInstCnt \ 814d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com childCheckInstCnt) { \ 824d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com if (CheckInstanceCount != childCheckInstCnt) { \ 834d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper::gChildren.push_back(childCheckInstCnt); \ 844d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 85977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com } 86977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 874d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DEFINE_INST_COUNT(className) \ 884d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com int32_t className::SkInstanceCountHelper::gInstanceCount = 0; \ 894d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com bool className::SkInstanceCountHelper::gInited = false; \ 904d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt> \ 914d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com className::SkInstanceCountHelper::gChildren; 92977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 93977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#else 944d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT(className) 954d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_ROOT(className) 964d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DEFINE_INST_COUNT(className) 97977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#endif 98977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 99977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#endif // SkInstCnt_DEFINED 100