Bug 1248784 - Extract the AddRef/Release calls into a non-inner helper trait. r=froydnj
authorBobby Holley <bobbyholley@gmail.com>
Mon, 15 Feb 2016 15:13:00 -0800
changeset 320944 5039eb1fa76cc1872f7c1372b5d8569188d36998
parent 320943 c9431b91f57091c24cbcef01eed66d5fbc76f1ec
child 320945 b8231765b22c6b62b31fa7e11706daae2b4cb086
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1248784
milestone47.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 1248784 - Extract the AddRef/Release calls into a non-inner helper trait. r=froydnj
gfx/layers/AtomicRefCountedWithFinalize.h
mfbt/RefPtr.h
--- a/gfx/layers/AtomicRefCountedWithFinalize.h
+++ b/gfx/layers/AtomicRefCountedWithFinalize.h
@@ -61,17 +61,17 @@ protected:
     }
 
 public:
     // Mark user classes that are considered flawless.
     template<class U>
     friend class ::mozilla::StaticRefPtr;
 
     template<class U>
-    friend class ::RefPtr;
+    friend struct mozilla::RefPtrTraits;
 
     template<class U>
     friend struct ::RunnableMethodTraits;
 
     template<typename U>
     friend class ::mozilla::gl::RefSet;
 
     template<typename U>
--- a/mfbt/RefPtr.h
+++ b/mfbt/RefPtr.h
@@ -14,16 +14,34 @@
 /*****************************************************************************/
 
 // template <class T> class RefPtrGetterAddRefs;
 
 class nsCOMPtr_helper;
 
 namespace mozilla {
 template<class T> class OwningNonNull;
+
+// Traditionally, RefPtr supports automatic refcounting of any pointer type
+// with AddRef() and Release() methods that follow the traditional semantics.
+//
+// This traits class can be specialized to operate on other pointer types. For
+// example, we specialize this trait for opaque FFI types that represent
+// refcounted objects in Rust.
+template<class U>
+struct RefPtrTraits
+{
+  static void AddRef(U* aPtr) {
+    aPtr->AddRef();
+  }
+  static void Release(U* aPtr) {
+    aPtr->Release();
+  }
+};
+
 } // namespace mozilla
 
 template <class T>
 class RefPtr
 {
 private:
   void
   assign_with_AddRef(T* aRawPtr)
@@ -331,59 +349,44 @@ public:
 
   T**
   StartAssignment()
   {
     assign_assuming_AddRef(0);
     return reinterpret_cast<T**>(&mRawPtr);
   }
 private:
-  // Because some classes make their AddRef/Release implementations private
-  // and then friend RefPtr to make them visible, we redirect AddRefTraits's
-  // calls to static helper functions in RefPtr so we don't have to figure
-  // out how to make AddRefTraits visible to *those* classes.
-  static MOZ_ALWAYS_INLINE void
-  AddRefTraitsAddRefHelper(typename mozilla::RemoveConst<T>::Type* aPtr)
-  {
-    aPtr->AddRef();
-  }
-  static MOZ_ALWAYS_INLINE void
-  AddRefTraitsReleaseHelper(typename mozilla::RemoveConst<T>::Type* aPtr)
-  {
-    aPtr->Release();
-  }
-
   // This helper class makes |RefPtr<const T>| possible by casting away
   // the constness from the pointer when calling AddRef() and Release().
   //
   // This is necessary because AddRef() and Release() implementations can't
   // generally expected to be const themselves (without heavy use of |mutable|
   // and |const_cast| in their own implementations).
   //
   // This should be sound because while |RefPtr<const T>| provides a
   // const view of an object, the object itself should not be const (it
   // would have to be allocated as |new const T| or similar to be const).
   template<class U>
   struct ConstRemovingRefPtrTraits
   {
     static void AddRef(U* aPtr) {
-      RefPtr<T>::AddRefTraitsAddRefHelper(aPtr);
+      mozilla::RefPtrTraits<U>::AddRef(aPtr);
     }
     static void Release(U* aPtr) {
-      RefPtr<T>::AddRefTraitsReleaseHelper(aPtr);
+      mozilla::RefPtrTraits<U>::Release(aPtr);
     }
   };
   template<class U>
   struct ConstRemovingRefPtrTraits<const U>
   {
     static void AddRef(const U* aPtr) {
-      RefPtr<T>::AddRefTraitsAddRefHelper(const_cast<U*>(aPtr));
+      mozilla::RefPtrTraits<typename mozilla::RemoveConst<U>::Type>::AddRef(const_cast<U*>(aPtr));
     }
     static void Release(const U* aPtr) {
-      RefPtr<T>::AddRefTraitsReleaseHelper(const_cast<U*>(aPtr));
+      mozilla::RefPtrTraits<typename mozilla::RemoveConst<U>::Type>::Release(const_cast<U*>(aPtr));
     }
   };
 };
 
 class nsCycleCollectionTraversalCallback;
 template <typename T>
 void
 CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback,