Bug 978472 - Add support for leak checking in GenericRefCounted classes; r=bjacob
authorEhsan Akhgari <ehsan@mozilla.com>
Sun, 09 Mar 2014 14:40:49 -0400
changeset 189868 9cfebec86c16c1f84cc3667bde8dd87eec0fd71f
parent 189867 6ece485bb7223d6a6b48e117669e9f6cb0e8e603
child 189869 1cee27f0547d7929e93d31fb844959b765f4408d
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs978472
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 978472 - Add support for leak checking in GenericRefCounted classes; r=bjacob
gfx/2d/GenericRefCounted.h
gfx/gl/GLContextCGL.h
gfx/gl/GLContextEGL.h
gfx/gl/GLContextGLX.h
gfx/gl/GLContextWGL.h
gfx/gl/SkiaGLGlue.h
gfx/gl/SurfaceStream.h
--- a/gfx/2d/GenericRefCounted.h
+++ b/gfx/2d/GenericRefCounted.h
@@ -32,16 +32,21 @@ class GenericRefCountedBase
 
     virtual void Release() = 0;
 
     // ref() and deref() method names are for compatibility with wtf::RefPtr.
     // No virtual keywords here: if a subclass wants to override the refcounting
     // mechanism, it is welcome to do so by overriding AddRef() and Release().
     void ref() { AddRef(); }
     void deref() { Release(); }
+
+#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
+    virtual const char* typeName() const = 0;
+    virtual size_t typeSize() const = 0;
+#endif
 };
 
 namespace detail {
 
 template<RefCountAtomicity Atomicity>
 class GenericRefCounted : public GenericRefCountedBase
 {
   protected:
@@ -50,21 +55,28 @@ class GenericRefCounted : public Generic
     virtual ~GenericRefCounted() {
       MOZ_ASSERT(refCnt == detail::DEAD);
     }
 
   public:
     virtual void AddRef() {
       MOZ_ASSERT(int32_t(refCnt) >= 0);
       ++refCnt;
+#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
+      detail::RefCountLogger::logAddRef(this, refCnt, typeName(), typeSize());
+#endif
     }
 
     virtual void Release() {
       MOZ_ASSERT(int32_t(refCnt) > 0);
-      if (0 == --refCnt) {
+      --refCnt;
+#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
+      detail::RefCountLogger::logRelease(this, refCnt, typeName());
+#endif
+      if (0 == refCnt) {
 #ifdef DEBUG
         refCnt = detail::DEAD;
 #endif
         delete this;
       }
     }
 
     MozRefCountType refCount() const { return refCnt; }
--- a/gfx/gl/GLContextCGL.h
+++ b/gfx/gl/GLContextCGL.h
@@ -22,16 +22,17 @@ namespace gl {
 
 class GLContextCGL : public GLContext
 {
     friend class GLContextProviderCGL;
 
     NSOpenGLContext *mContext;
 
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL)
     GLContextCGL(const SurfaceCaps& caps,
                  GLContext *shareContext,
                  NSOpenGLContext *context,
                  bool isOffscreen = false);
 
     ~GLContextCGL();
 
     virtual GLContextType GetContextType() const MOZ_OVERRIDE { return GLContextType::CGL; }
--- a/gfx/gl/GLContextEGL.h
+++ b/gfx/gl/GLContextEGL.h
@@ -24,16 +24,17 @@ class GLContextEGL : public GLContext
     static already_AddRefed<GLContextEGL>
     CreateGLContext(const SurfaceCaps& caps,
                     GLContextEGL *shareContext,
                     bool isOffscreen,
                     EGLConfig config,
                     EGLSurface surface);
 
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL)
     GLContextEGL(const SurfaceCaps& caps,
                  GLContext* shareContext,
                  bool isOffscreen,
                  EGLConfig config,
                  EGLSurface surface,
                  EGLContext context);
 
     ~GLContextEGL();
--- a/gfx/gl/GLContextGLX.h
+++ b/gfx/gl/GLContextGLX.h
@@ -11,16 +11,17 @@
 #include "GLXLibrary.h"
 
 namespace mozilla {
 namespace gl {
 
 class GLContextGLX : public GLContext
 {
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextGLX)
     static already_AddRefed<GLContextGLX>
     CreateGLContext(const SurfaceCaps& caps,
                     GLContextGLX* shareContext,
                     bool isOffscreen,
                     Display* display,
                     GLXDrawable drawable,
                     GLXFBConfig cfg,
                     bool deleteDrawable,
--- a/gfx/gl/GLContextWGL.h
+++ b/gfx/gl/GLContextWGL.h
@@ -11,16 +11,17 @@
 #include "WGLLibrary.h"
 
 namespace mozilla {
 namespace gl {
 
 class GLContextWGL : public GLContext
 {
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextWGL)
     // From Window: (possibly for offscreen!)
     GLContextWGL(const SurfaceCaps& caps,
                  GLContext* sharedContext,
                  bool isOffscreen,
                  HDC aDC,
                  HGLRC aContext,
                  HWND aWindow = nullptr);
 
--- a/gfx/gl/SkiaGLGlue.h
+++ b/gfx/gl/SkiaGLGlue.h
@@ -12,16 +12,17 @@
 #include "skia/GrContext.h"
 
 namespace mozilla {
 namespace gl {
 
 class SkiaGLGlue : public GenericAtomicRefCounted
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SkiaGLGlue)
   SkiaGLGlue(GLContext* context);
   GLContext* GetGLContext() const { return mGLContext.get(); }
   GrContext* GetGrContext() const { return mGrContext.get(); }
 
 protected:
   virtual ~SkiaGLGlue() {
     /*
      * These members have inter-dependencies, but do not keep each other alive, so
--- a/gfx/gl/SurfaceStream.h
+++ b/gfx/gl/SurfaceStream.h
@@ -23,16 +23,17 @@ class GLContext;
 namespace gfx {
 class SharedSurface;
 class SurfaceFactory;
 
 // Owned by: ScreenBuffer
 class SurfaceStream : public GenericAtomicRefCounted
 {
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream)
     typedef enum {
         MainThread,
         OffMainThread
     } OMTC;
 
     static SurfaceStreamType ChooseGLStreamType(OMTC omtc,
                                                 bool preserveBuffer);
 
@@ -140,16 +141,17 @@ public:
 // Not thread-safe. Don't use cross-threads.
 class SurfaceStream_SingleBuffer
     : public SurfaceStream
 {
 protected:
     SharedSurface* mConsumer; // Only present after resize-swap.
 
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer)
     SurfaceStream_SingleBuffer(SurfaceStream* prevStream);
     virtual ~SurfaceStream_SingleBuffer();
 
     /* Since we're non-OMTC, we know the order of execution here:
      * SwapProd gets called in UpdateSurface, followed by
      * SwapCons being called in Render.
      */
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
@@ -164,16 +166,17 @@ public:
 class SurfaceStream_TripleBuffer_Copy
     : public SurfaceStream
 {
 protected:
     SharedSurface* mStaging;
     SharedSurface* mConsumer;
 
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy)
     SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer_Copy();
 
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
                                         const gfx::IntSize& size);
 
     virtual SharedSurface* SwapConsumer_NoWait();
 
@@ -187,16 +190,17 @@ class SurfaceStream_TripleBuffer
 protected:
     SharedSurface* mStaging;
     SharedSurface* mConsumer;
 
     // To support subclasses initializing the mType.
     SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream);
 
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer)
     SurfaceStream_TripleBuffer(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer();
     virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory);
 
 private:
     // Common constructor code.
     void Init(SurfaceStream* prevStream);