SkInstCnt.h revision fbfcd5602128ec010c82cb733c9cdc0a3254f9f3
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/* 13fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@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 2297fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com#include <stdlib.h> 234d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#include "SkTArray.h" 244d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com 25b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.comextern bool gPrintInstCount; 26b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com 2797fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com// The non-root classes just register themselves with their parent 284d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT(className) \ 294d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SK_DECLARE_INST_COUNT_INTERNAL(className, \ 30a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com INHERITED::AddInstChild(CheckInstanceCount);,\ 31a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com /**/) 32a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com 33a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com#define SK_DECLARE_INST_COUNT_TEMPLATE(className) \ 34a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com SK_DECLARE_INST_COUNT_INTERNAL(className, \ 35a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com INHERITED::AddInstChild(CheckInstanceCount);, \ 36a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com typename) 374d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com 3897fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com// The root classes registers a function to print out the memory stats when 3997fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com// the app ends 404d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_ROOT(className) \ 41a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);, /**/) 424d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com 43a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep, templateType) \ 444d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com class SkInstanceCountHelper { \ 454d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com public: \ 4623579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com typedef int (*PFCheckInstCnt)(int level, bool cleanUp); \ 474d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper() { \ 484d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com if (!gInited) { \ 494d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com initStep \ 5023579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com gChildren = new SkTArray<PFCheckInstCnt>; \ 514d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInited = true; \ 524d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 534d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInstanceCount++; \ 544d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 554d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 564d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper(const SkInstanceCountHelper& other) { \ 574d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInstanceCount++; \ 584d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 594d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 604d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com ~SkInstanceCountHelper() { \ 614d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com gInstanceCount--; \ 624d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 634d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 644d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com static int32_t gInstanceCount; \ 654d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com static bool gInited; \ 6623579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com static SkTArray<PFCheckInstCnt>* gChildren; \ 674d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } fInstanceCountHelper; \ 684d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 694da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com static int32_t GetInstanceCount() { \ 704da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com return SkInstanceCountHelper::gInstanceCount; \ 714da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com } \ 724da34e36cb7a07c3a28ae2a135b1837c26fc7aeabsalomon@google.com \ 7397fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com static void exitPrint() { \ 7423579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com CheckInstanceCount(0, true); \ 7597fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com } \ 7697fafe1b5ec06b470d36ea5cd98fe7bf2c143491robertphillips@google.com \ 7723579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \ 78b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com if (gPrintInstCount && 0 != SkInstanceCountHelper::gInstanceCount) {\ 7973e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com SkDebugf("%*c Leaked %s: %d\n", \ 8015e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 4*level, ' ', #className, \ 814d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com SkInstanceCountHelper::gInstanceCount); \ 824d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 8323579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com if (NULL == SkInstanceCountHelper::gChildren) { \ 8423579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com return SkInstanceCountHelper::gInstanceCount; \ 8523579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com } \ 8623579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com int childCount = SkInstanceCountHelper::gChildren->count(); \ 8773e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com int count = SkInstanceCountHelper::gInstanceCount; \ 8873e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com for (int i = 0; i < childCount; ++i) { \ 8923579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com count -= (*(*SkInstanceCountHelper::gChildren)[i])(level+1, cleanUp); \ 904d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 9173e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com SkASSERT(count >= 0); \ 92b74af872cc1ce45768df3ae03fa86ad3ed76b582robertphillips@google.com if (gPrintInstCount && childCount > 0 && count > 0) { \ 9373e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \ 9473e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com } \ 9523579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com if (cleanUp) { \ 9623579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com delete SkInstanceCountHelper::gChildren; \ 9723579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com SkInstanceCountHelper::gChildren = NULL; \ 9823579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com } \ 9973e19fb1ba2562048c6987272c8d73eee6a44242reed@google.com return SkInstanceCountHelper::gInstanceCount; \ 1004d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 1014d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com \ 102a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com static void AddInstChild(templateType SkInstanceCountHelper::PFCheckInstCnt \ 1034d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com childCheckInstCnt) { \ 10423579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com if (CheckInstanceCount != childCheckInstCnt && \ 10523579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com NULL != SkInstanceCountHelper::gChildren) { \ 10623579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com SkInstanceCountHelper::gChildren->push_back(childCheckInstCnt); \ 1074d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com } \ 108977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com } 109977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 1104d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DEFINE_INST_COUNT(className) \ 1114d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com int32_t className::SkInstanceCountHelper::gInstanceCount = 0; \ 1124d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com bool className::SkInstanceCountHelper::gInited = false; \ 11323579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt>* \ 11423579275c7f544763d074d90563c4b1e567ab041robertphillips@google.com className::SkInstanceCountHelper::gChildren = NULL; 115977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 1164fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) \ 1174fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com templateInfo int32_t className::SkInstanceCountHelper::gInstanceCount = 0;\ 1184fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com templateInfo bool className::SkInstanceCountHelper::gInited = false; \ 1194fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com templateInfo \ 1204fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com SkTArray<typename className::SkInstanceCountHelper::PFCheckInstCnt>*\ 1214fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com className::SkInstanceCountHelper::gChildren = NULL; 1224fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com 123977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#else 1244d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT(className) 125a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com#define SK_DECLARE_INST_COUNT_TEMPLATE(className) 1264d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_ROOT(className) 1274d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DEFINE_INST_COUNT(className) 1284fa9c9f9b42c22bffff3b2eb3fcf7f16a2ab2948robertphillips@google.com#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) 129977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#endif 130977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com 131977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#endif // SkInstCnt_DEFINED 132