]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - wtf/RefCounted.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / wtf / RefCounted.h
index ac8e167bf7488b808e6a06b0de6337ad4d9dd37e..12b670e07c1e5facd5df383ced67ac0e6d46cbf0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #ifndef RefCounted_h
 #define RefCounted_h
 
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
+#include "Assertions.h"
+#include "FastAllocBase.h"
+#include "Noncopyable.h"
 
 namespace WTF {
 
 // 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 {
+class RefCountedBase {
 public:
     void ref()
     {
         ASSERT(!m_deletionHasBegun);
+        ASSERT(!m_adoptionIsRequired);
         ++m_refCount;
     }
 
@@ -48,21 +50,43 @@ public:
         return m_refCount;
     }
 
+    void relaxAdoptionRequirement()
+    {
+#ifndef NDEBUG
+        ASSERT(!m_deletionHasBegun);
+        ASSERT(m_adoptionIsRequired);
+        m_adoptionIsRequired = false;
+#endif
+    }
+
+    // Helper for generating JIT code. Please do not use for non-JIT purposes.
+    const int* addressOfCount() const
+    {
+        return &m_refCount;
+    }
+
 protected:
-    RefCountedBase(int initialRefCount)
-        : m_refCount(initialRefCount)
+    RefCountedBase()
+        : m_refCount(1)
 #ifndef NDEBUG
         , m_deletionHasBegun(false)
+        , m_adoptionIsRequired(true)
 #endif
     {
     }
 
-    ~RefCountedBase() {}
+    ~RefCountedBase()
+    {
+        ASSERT(m_deletionHasBegun);
+        ASSERT(!m_adoptionIsRequired);
+    }
 
     // Returns whether the pointer should be freed or not.
     bool derefBase()
     {
         ASSERT(!m_deletionHasBegun);
+        ASSERT(!m_adoptionIsRequired);
+
         ASSERT(m_refCount > 0);
         if (m_refCount == 1) {
 #ifndef NDEBUG
@@ -75,21 +99,59 @@ protected:
         return false;
     }
 
-protected:
+#ifndef NDEBUG
+    bool deletionHasBegun() const
+    {
+        return m_deletionHasBegun;
+    }
+#endif
+
+private:
+    template<typename T> friend class CrossThreadRefCounted;
+
+#ifndef NDEBUG
+    friend void adopted(RefCountedBase*);
+#endif
+
     int m_refCount;
 #ifndef NDEBUG
     bool m_deletionHasBegun;
+    bool m_adoptionIsRequired;
 #endif
 };
 
+#ifndef NDEBUG
+
+inline void adopted(RefCountedBase* object)
+{
+    if (!object)
+        return;
+    ASSERT(!object->m_deletionHasBegun);
+    object->m_adoptionIsRequired = false;
+}
 
-template<class T> class RefCounted : public RefCountedBase {
+#endif
+
+template<typename T> class RefCounted : public RefCountedBase {
+    WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED;
 public:
-    RefCounted(int initialRefCount = 1)
-        : RefCountedBase(initialRefCount)
+    void deref()
     {
+        if (derefBase())
+            delete static_cast<T*>(this);
     }
 
+protected:
+    RefCounted() { }
+    ~RefCounted()
+    {
+    }
+};
+
+template<typename T> class RefCountedCustomAllocated : public RefCountedBase {
+    WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated);
+
+public:
     void deref()
     {
         if (derefBase())
@@ -97,11 +159,14 @@ public:
     }
 
 protected:
-    ~RefCounted() {}
+    ~RefCountedCustomAllocated()
+    {
+    }
 };
 
 } // namespace WTF
 
 using WTF::RefCounted;
+using WTF::RefCountedCustomAllocated;
 
 #endif // RefCounted_h