2012-06-12 00:32:28 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2012-06-05 19:35:09 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef SkInstCnt_DEFINED
|
|
|
|
#define SkInstCnt_DEFINED
|
|
|
|
|
|
|
|
/*
|
2012-08-23 18:09:54 +00:00
|
|
|
* The instance counting system consists of three macros that create the
|
2012-06-05 19:35:09 +00:00
|
|
|
* instance counting machinery. A class is added to the system by adding:
|
2012-06-13 18:54:08 +00:00
|
|
|
* SK_DECLARE_INST_COUNT at the top of its declaration for derived classes
|
|
|
|
* SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class
|
|
|
|
* SK_DEFINE_INST_COUNT at the top of its .cpp file (for both kinds).
|
|
|
|
* At the end of an application a call to all the "root" objects'
|
|
|
|
* CheckInstanceCount methods should be made
|
2012-06-05 19:35:09 +00:00
|
|
|
*/
|
2012-09-24 19:33:57 +00:00
|
|
|
#if defined SK_DEBUG && !defined SK_ENABLE_INST_COUNT
|
|
|
|
#define SK_ENABLE_INST_COUNT
|
|
|
|
#endif
|
|
|
|
|
2012-06-27 19:41:42 +00:00
|
|
|
#ifdef SK_ENABLE_INST_COUNT
|
2012-06-27 19:52:20 +00:00
|
|
|
#include <stdlib.h>
|
2012-06-13 18:54:08 +00:00
|
|
|
#include "SkTArray.h"
|
2012-08-29 18:52:07 +00:00
|
|
|
#include "SkThread_platform.h"
|
2012-06-13 18:54:08 +00:00
|
|
|
|
2012-06-27 19:41:42 +00:00
|
|
|
extern bool gPrintInstCount;
|
|
|
|
|
2012-06-27 19:52:20 +00:00
|
|
|
// The non-root classes just register themselves with their parent
|
2012-06-13 18:54:08 +00:00
|
|
|
#define SK_DECLARE_INST_COUNT(className) \
|
|
|
|
SK_DECLARE_INST_COUNT_INTERNAL(className, \
|
2012-08-16 14:58:06 +00:00
|
|
|
INHERITED::AddInstChild(CheckInstanceCount);,\
|
|
|
|
/**/)
|
|
|
|
|
|
|
|
#define SK_DECLARE_INST_COUNT_TEMPLATE(className) \
|
|
|
|
SK_DECLARE_INST_COUNT_INTERNAL(className, \
|
|
|
|
INHERITED::AddInstChild(CheckInstanceCount);, \
|
|
|
|
typename)
|
2012-06-13 18:54:08 +00:00
|
|
|
|
2012-06-27 19:52:20 +00:00
|
|
|
// The root classes registers a function to print out the memory stats when
|
|
|
|
// the app ends
|
2012-06-13 18:54:08 +00:00
|
|
|
#define SK_DECLARE_INST_COUNT_ROOT(className) \
|
2012-08-16 14:58:06 +00:00
|
|
|
SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);, /**/)
|
2012-06-13 18:54:08 +00:00
|
|
|
|
2012-08-16 14:58:06 +00:00
|
|
|
#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep, templateType) \
|
2012-06-13 18:54:08 +00:00
|
|
|
class SkInstanceCountHelper { \
|
|
|
|
public: \
|
2012-06-28 21:30:45 +00:00
|
|
|
typedef int (*PFCheckInstCnt)(int level, bool cleanUp); \
|
2012-06-13 18:54:08 +00:00
|
|
|
SkInstanceCountHelper() { \
|
|
|
|
if (!gInited) { \
|
|
|
|
initStep \
|
2012-06-28 21:30:45 +00:00
|
|
|
gChildren = new SkTArray<PFCheckInstCnt>; \
|
2012-06-13 18:54:08 +00:00
|
|
|
gInited = true; \
|
|
|
|
} \
|
2012-08-29 18:52:07 +00:00
|
|
|
sk_atomic_inc(&gInstanceCount); \
|
2012-06-13 18:54:08 +00:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
SkInstanceCountHelper(const SkInstanceCountHelper& other) { \
|
2012-08-29 18:52:07 +00:00
|
|
|
sk_atomic_inc(&gInstanceCount); \
|
2012-06-13 18:54:08 +00:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
~SkInstanceCountHelper() { \
|
2012-08-29 18:52:07 +00:00
|
|
|
sk_atomic_dec(&gInstanceCount); \
|
2012-06-13 18:54:08 +00:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
static int32_t gInstanceCount; \
|
|
|
|
static bool gInited; \
|
2012-06-28 21:30:45 +00:00
|
|
|
static SkTArray<PFCheckInstCnt>* gChildren; \
|
2012-06-13 18:54:08 +00:00
|
|
|
} fInstanceCountHelper; \
|
|
|
|
\
|
2012-06-19 15:40:27 +00:00
|
|
|
static int32_t GetInstanceCount() { \
|
|
|
|
return SkInstanceCountHelper::gInstanceCount; \
|
|
|
|
} \
|
|
|
|
\
|
2012-06-27 19:52:20 +00:00
|
|
|
static void exitPrint() { \
|
2012-06-28 21:30:45 +00:00
|
|
|
CheckInstanceCount(0, true); \
|
2012-06-27 19:52:20 +00:00
|
|
|
} \
|
|
|
|
\
|
2012-06-28 21:30:45 +00:00
|
|
|
static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \
|
2012-06-27 19:41:42 +00:00
|
|
|
if (gPrintInstCount && 0 != SkInstanceCountHelper::gInstanceCount) {\
|
2012-06-26 18:58:03 +00:00
|
|
|
SkDebugf("%*c Leaked %s: %d\n", \
|
2012-06-21 20:25:03 +00:00
|
|
|
4*level, ' ', #className, \
|
2012-06-13 18:54:08 +00:00
|
|
|
SkInstanceCountHelper::gInstanceCount); \
|
|
|
|
} \
|
2012-06-28 21:30:45 +00:00
|
|
|
if (NULL == SkInstanceCountHelper::gChildren) { \
|
|
|
|
return SkInstanceCountHelper::gInstanceCount; \
|
|
|
|
} \
|
|
|
|
int childCount = SkInstanceCountHelper::gChildren->count(); \
|
2012-06-26 18:58:03 +00:00
|
|
|
int count = SkInstanceCountHelper::gInstanceCount; \
|
|
|
|
for (int i = 0; i < childCount; ++i) { \
|
2012-06-28 21:30:45 +00:00
|
|
|
count -= (*(*SkInstanceCountHelper::gChildren)[i])(level+1, cleanUp); \
|
2012-06-13 18:54:08 +00:00
|
|
|
} \
|
2012-06-26 18:58:03 +00:00
|
|
|
SkASSERT(count >= 0); \
|
2012-06-27 19:41:42 +00:00
|
|
|
if (gPrintInstCount && childCount > 0 && count > 0) { \
|
2012-06-26 18:58:03 +00:00
|
|
|
SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \
|
|
|
|
} \
|
2012-06-28 21:30:45 +00:00
|
|
|
if (cleanUp) { \
|
|
|
|
delete SkInstanceCountHelper::gChildren; \
|
|
|
|
SkInstanceCountHelper::gChildren = NULL; \
|
|
|
|
} \
|
2012-06-26 18:58:03 +00:00
|
|
|
return SkInstanceCountHelper::gInstanceCount; \
|
2012-06-13 18:54:08 +00:00
|
|
|
} \
|
|
|
|
\
|
2012-08-16 14:58:06 +00:00
|
|
|
static void AddInstChild(templateType SkInstanceCountHelper::PFCheckInstCnt \
|
2012-06-13 18:54:08 +00:00
|
|
|
childCheckInstCnt) { \
|
2012-06-28 21:30:45 +00:00
|
|
|
if (CheckInstanceCount != childCheckInstCnt && \
|
|
|
|
NULL != SkInstanceCountHelper::gChildren) { \
|
|
|
|
SkInstanceCountHelper::gChildren->push_back(childCheckInstCnt); \
|
2012-06-13 18:54:08 +00:00
|
|
|
} \
|
2012-06-05 19:35:09 +00:00
|
|
|
}
|
|
|
|
|
2012-06-13 18:54:08 +00:00
|
|
|
#define SK_DEFINE_INST_COUNT(className) \
|
|
|
|
int32_t className::SkInstanceCountHelper::gInstanceCount = 0; \
|
|
|
|
bool className::SkInstanceCountHelper::gInited = false; \
|
2012-06-28 21:30:45 +00:00
|
|
|
SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt>* \
|
|
|
|
className::SkInstanceCountHelper::gChildren = NULL;
|
2012-06-05 19:35:09 +00:00
|
|
|
|
2012-08-22 17:31:22 +00:00
|
|
|
#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) \
|
|
|
|
templateInfo int32_t className::SkInstanceCountHelper::gInstanceCount = 0;\
|
|
|
|
templateInfo bool className::SkInstanceCountHelper::gInited = false; \
|
|
|
|
templateInfo \
|
|
|
|
SkTArray<typename className::SkInstanceCountHelper::PFCheckInstCnt>*\
|
|
|
|
className::SkInstanceCountHelper::gChildren = NULL;
|
|
|
|
|
2012-06-05 19:35:09 +00:00
|
|
|
#else
|
2012-06-13 18:54:08 +00:00
|
|
|
#define SK_DECLARE_INST_COUNT(className)
|
2012-08-16 14:58:06 +00:00
|
|
|
#define SK_DECLARE_INST_COUNT_TEMPLATE(className)
|
2012-06-13 18:54:08 +00:00
|
|
|
#define SK_DECLARE_INST_COUNT_ROOT(className)
|
|
|
|
#define SK_DEFINE_INST_COUNT(className)
|
2012-08-22 17:31:22 +00:00
|
|
|
#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className)
|
2012-06-05 19:35:09 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif // SkInstCnt_DEFINED
|