diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/include/core/SkInstCnt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/include/core/SkInstCnt.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,142 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef SkInstCnt_DEFINED +#define SkInstCnt_DEFINED + +/* + * The instance counting system consists of three macros that create the + * instance counting machinery. A class is added to the system by adding: + * 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 + * At the end of an application a call to all the "root" objects' + * CheckInstanceCount methods should be made + */ +#include "SkTypes.h" + +#if SK_ENABLE_INST_COUNT +// Static variables inside member functions below may be defined multiple times +// if Skia is being used as a dynamic library. Instance counting should be on +// only for static builds. See bug skia:2058. +#if defined(SKIA_DLL) +#error Instance counting works only when Skia is built as a static library. +#endif + +#include "SkOnce.h" +#include "SkTArray.h" +#include "SkThread.h" +extern bool gPrintInstCount; + +// The non-root classes just register themselves with their parent +#define SK_DECLARE_INST_COUNT(className) \ + SK_DECLARE_INST_COUNT_INTERNAL(className, \ + INHERITED::AddInstChild(CheckInstanceCount);) + +// The root classes registers a function to print out the memory stats when +// the app ends +#define SK_DECLARE_INST_COUNT_ROOT(className) \ + SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);) + +#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \ + class SkInstanceCountHelper { \ + public: \ + SkInstanceCountHelper() { \ + SK_DECLARE_STATIC_ONCE(once); \ + SkOnce(&once, init, 0); \ + sk_atomic_inc(GetInstanceCountPtr()); \ + } \ + \ + static void init(int) { \ + initStep \ + } \ + \ + SkInstanceCountHelper(const SkInstanceCountHelper&) { \ + sk_atomic_inc(GetInstanceCountPtr()); \ + } \ + \ + ~SkInstanceCountHelper() { \ + sk_atomic_dec(GetInstanceCountPtr()); \ + } \ + \ + static int32_t* GetInstanceCountPtr() { \ + static int32_t gInstanceCount; \ + return &gInstanceCount; \ + } \ + \ + static SkTArray*& GetChildren() { \ + static SkTArray* gChildren; \ + return gChildren; \ + } \ + \ + static SkBaseMutex& GetChildrenMutex() { \ + SK_DECLARE_STATIC_MUTEX(childrenMutex); \ + return childrenMutex; \ + } \ + \ + } fInstanceCountHelper; \ + \ + static int32_t GetInstanceCount() { \ + return *SkInstanceCountHelper::GetInstanceCountPtr(); \ + } \ + \ + static void exitPrint() { \ + CheckInstanceCount(0, true); \ + } \ + \ + static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \ + if (gPrintInstCount && 0 != GetInstanceCount()) { \ + SkDebugf("%*c Leaked %s: %d\n", \ + 4*level, ' ', #className, \ + GetInstanceCount()); \ + } \ + if (NULL == SkInstanceCountHelper::GetChildren()) { \ + return GetInstanceCount(); \ + } \ + SkTArray* children = \ + SkInstanceCountHelper::GetChildren(); \ + int childCount = children->count(); \ + int count = GetInstanceCount(); \ + for (int i = 0; i < childCount; ++i) { \ + count -= (*(*children)[i])(level+1, cleanUp); \ + } \ + SkASSERT(count >= 0); \ + if (gPrintInstCount && childCount > 0 && count > 0) { \ + SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \ + } \ + if (cleanUp) { \ + delete children; \ + SkInstanceCountHelper::GetChildren() = NULL; \ + } \ + return GetInstanceCount(); \ + } \ + \ + static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \ + if (CheckInstanceCount != childCheckInstCnt) { \ + SkAutoMutexAcquire ama(SkInstanceCountHelper::GetChildrenMutex()); \ + if (NULL == SkInstanceCountHelper::GetChildren()) { \ + SkInstanceCountHelper::GetChildren() = \ + new SkTArray; \ + } \ + SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \ + } \ + } + +#else +// Typically SK_ENABLE_INST_COUNT=0. Make sure the class declares public typedef INHERITED by +// causing a compile-time error if the typedef is missing. This way SK_ENABLE_INST_COUNT=1 stays +// compiling. +#define SK_DECLARE_INST_COUNT(className) static void AddInstChild() { INHERITED::AddInstChild(); } +#define SK_DECLARE_INST_COUNT_ROOT(className) static void AddInstChild() { } +#endif + +// Following are deprecated. They are defined only for backwards API compatibility. +#define SK_DECLARE_INST_COUNT_TEMPLATE(className) SK_DECLARE_INST_COUNT(className) +#define SK_DEFINE_INST_COUNT(className) +#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) + +#endif // SkInstCnt_DEFINED