]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - wtf/RefCounted.h
JavaScriptCore-521.tar.gz
[apple/javascriptcore.git] / wtf / RefCounted.h
index dc93b118c5daaddb1eb39d984138d2b9e9c4e44f..ac8e167bf7488b808e6a06b0de6337ad4d9dd37e 100644 (file)
 
 namespace WTF {
 
-template<class T> class RefCounted : Noncopyable {
+// This base class holds the non-template methods and attributes.
+// The RefCounted class inherits from it reducing the template bloat
+// generated by the compiler (technique called template hoisting).
+class RefCountedBase : Noncopyable {
 public:
-    RefCounted(int initialRefCount = 0)
+    void ref()
+    {
+        ASSERT(!m_deletionHasBegun);
+        ++m_refCount;
+    }
+
+    bool hasOneRef() const
+    {
+        ASSERT(!m_deletionHasBegun);
+        return m_refCount == 1;
+    }
+
+    int refCount() const
+    {
+        return m_refCount;
+    }
+
+protected:
+    RefCountedBase(int initialRefCount)
         : m_refCount(initialRefCount)
 #ifndef NDEBUG
         , m_deletionHasBegun(false)
@@ -36,13 +57,10 @@ public:
     {
     }
 
-    void ref()
-    {
-        ASSERT(!m_deletionHasBegun);
-        ++m_refCount;
-    }
+    ~RefCountedBase() {}
 
-    void deref()
+    // Returns whether the pointer should be freed or not.
+    bool derefBase()
     {
         ASSERT(!m_deletionHasBegun);
         ASSERT(m_refCount > 0);
@@ -50,27 +68,36 @@ public:
 #ifndef NDEBUG
             m_deletionHasBegun = true;
 #endif
-            delete static_cast<T*>(this);
-        } else 
-            --m_refCount;
+            return true;
+        }
+
+        --m_refCount;
+        return false;
     }
 
-    bool hasOneRef()
+protected:
+    int m_refCount;
+#ifndef NDEBUG
+    bool m_deletionHasBegun;
+#endif
+};
+
+
+template<class T> class RefCounted : public RefCountedBase {
+public:
+    RefCounted(int initialRefCount = 1)
+        : RefCountedBase(initialRefCount)
     {
-        ASSERT(!m_deletionHasBegun);
-        return m_refCount == 1;
     }
 
-    int refCount() const
+    void deref()
     {
-        return m_refCount;
+        if (derefBase())
+            delete static_cast<T*>(this);
     }
 
-private:
-    int m_refCount;
-#ifndef NDEBUG
-    bool m_deletionHasBegun;
-#endif
+protected:
+    ~RefCounted() {}
 };
 
 } // namespace WTF