Added instance counting system for SkRefCnt-derived objects

http://codereview.appspot.com/6242070/



git-svn-id: http://skia.googlecode.com/svn/trunk@4162 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 6eb96fd..c6159e3 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -21,6 +21,7 @@
 #include "SkImageEncoder.h"
 #include "SkPicture.h"
 #include "SkStream.h"
+#include "SkRefCnt.h"
 
 static bool gForceBWtext;
 
@@ -804,7 +805,7 @@
 }
 
 int main(int argc, char * const argv[]) {
-    SkAutoGraphics ag;
+    SkGraphics::Init();
     // we don't need to see this during a run
     gSkSuppressFontCachePurgeSpew = true;
 
@@ -892,7 +893,7 @@
 
     GM::SetResourcePath(resourcePath);
 
-    GrContextFactory grFactory;
+    GrContextFactory* grFactory = new GrContextFactory;
 
     if (readPath) {
         fprintf(stderr, "reading from %s\n", readPath);
@@ -935,7 +936,7 @@
             SkAutoTUnref<GrRenderTarget> rt;
             AutoResetGr autogr;
             if (kGPU_Backend == gRec[i].fBackend) {
-                GrContext* gr = grFactory.get(gRec[i].fGLContextType);
+                GrContext* gr = grFactory->get(gRec[i].fGLContextType);
                 if (!gr) {
                     continue;
                 }
@@ -1036,5 +1037,11 @@
     printf("Ran %d tests: %d passed, %d failed, %d missing reference images\n",
            testsRun, testsPassed, testsFailed, testsMissingReferenceImages);
 
+    delete grFactory;
+    SkGraphics::Term();
+
+    PRINT_INST_COUNT(SkRefCnt);
+    PRINT_INST_COUNT(GrResource);
+
     return (0 == testsFailed) ? 0 : -1;
 }
diff --git a/gyp/core.gyp b/gyp/core.gyp
index aea2a73..f50d64a 100644
--- a/gyp/core.gyp
+++ b/gyp/core.gyp
@@ -112,6 +112,7 @@
         '../src/core/SkRasterClip.cpp',
         '../src/core/SkRasterizer.cpp',
         '../src/core/SkRect.cpp',
+        '../src/core/SkRefCnt.cpp',
         '../src/core/SkRefDict.cpp',
         '../src/core/SkRegion.cpp',
         '../src/core/SkRegionPriv.h',
@@ -185,6 +186,7 @@
         '../include/core/SkFontHost.h',
         '../include/core/SkGeometry.h',
         '../include/core/SkGraphics.h',
+        '../include/core/SkInstCnt.h',
         '../include/core/SkMallocPixelRef.h',
         '../include/core/SkMask.h',
         '../include/core/SkMaskFilter.h',
diff --git a/include/core/SkInstCnt.h b/include/core/SkInstCnt.h
new file mode 100644
index 0000000..889c098
--- /dev/null
+++ b/include/core/SkInstCnt.h
@@ -0,0 +1,51 @@
+/*

+ * 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:
+ *   DECLARE_INST_COUNT at the top of its declaration
+ *   DEFINE_INST_COUNT at the top of its .cpp file
+ *   and a PRINT_INST_COUNT line at the application's end point
+ */
+#ifdef SK_DEBUG
+#define DECLARE_INST_COUNT                  \
+    class SkInstanceCountHelper {           \
+    public:                                 \
+        SkInstanceCountHelper() {           \
+            gInstanceCount++;               \
+        }                                   \
+                                            \
+        ~SkInstanceCountHelper() {          \
+            gInstanceCount--;               \
+        }                                   \
+                                            \
+        static int32_t gInstanceCount;      \
+    } fInstanceCountHelper;                 \
+                                            \
+    static int32_t GetInstanceCount() {     \
+        return SkInstanceCountHelper::gInstanceCount;   \
+    }
+
+#define DEFINE_INST_COUNT(className)        \
+    int32_t className::SkInstanceCountHelper::gInstanceCount = 0;
+
+#define PRINT_INST_COUNT(className)         \
+    SkDebugf("Leaked %s objects: %d\n",     \
+                  #className,               \
+                  className::GetInstanceCount());
+#else
+#define DECLARE_INST_COUNT
+#define DEFINE_INST_COUNT(className)
+#define PRINT_INST_COUNT(className)
+#endif
+
+#endif // SkInstCnt_DEFINED
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index b847596..761546b 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -11,6 +11,7 @@
 #define SkRefCnt_DEFINED
 
 #include "SkThread.h"
+#include "SkInstCnt.h"
 
 /** \class SkRefCnt
 
@@ -24,6 +25,8 @@
 */
 class SK_API SkRefCnt : SkNoncopyable {
 public:
+    DECLARE_INST_COUNT
+
     /** Default construct, initializing the reference count to 1.
     */
     SkRefCnt() : fRefCnt(1) {}
diff --git a/include/gpu/GrResource.h b/include/gpu/GrResource.h
index 8008f29..4c491c7 100644
--- a/include/gpu/GrResource.h
+++ b/include/gpu/GrResource.h
@@ -20,6 +20,8 @@
  */
 class GrResource : public GrRefCnt {
 public:
+    DECLARE_INST_COUNT
+
     /**
      * Frees the resource in the underlying 3D API. It must be safe to call this
      * when the resource has been previously abandoned.
diff --git a/src/core/SkRefCnt.cpp b/src/core/SkRefCnt.cpp
new file mode 100644
index 0000000..111ecd8
--- /dev/null
+++ b/src/core/SkRefCnt.cpp
@@ -0,0 +1,12 @@
+/*

+ * Copyright 2012 Google Inc.

+ *

+ * Use of this source code is governed by a BSD-style license that can be

+ * found in the LICENSE file.

+ */
+
+
+#include "SkRefCnt.h"
+
+DEFINE_INST_COUNT(SkRefCnt)
+
diff --git a/src/gpu/GrResource.cpp b/src/gpu/GrResource.cpp
index 9efc838..a5168c8 100644
--- a/src/gpu/GrResource.cpp
+++ b/src/gpu/GrResource.cpp
@@ -10,6 +10,8 @@
 #include "GrResource.h"
 #include "GrGpu.h"
 
+DEFINE_INST_COUNT(GrResource)
+
 GrResource::GrResource(GrGpu* gpu) {
     fGpu        = gpu;
     fNext       = NULL;