JavaScriptCore/wtf/RefCounted.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
       
     3  *
       
     4  * This library is free software; you can redistribute it and/or
       
     5  * modify it under the terms of the GNU Library General Public
       
     6  * License as published by the Free Software Foundation; either
       
     7  * version 2 of the License, or (at your option) any later version.
       
     8  *
       
     9  * This library is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12  * Library General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU Library General Public License
       
    15  * along with this library; see the file COPYING.LIB.  If not, write to
       
    16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    17  * Boston, MA 02110-1301, USA.
       
    18  *
       
    19  */
       
    20 
       
    21 #ifndef RefCounted_h
       
    22 #define RefCounted_h
       
    23 
       
    24 #include "Assertions.h"
       
    25 #include "Noncopyable.h"
       
    26 
       
    27 namespace WTF {
       
    28 
       
    29 // This base class holds the non-template methods and attributes.
       
    30 // The RefCounted class inherits from it reducing the template bloat
       
    31 // generated by the compiler (technique called template hoisting).
       
    32 class RefCountedBase {
       
    33 public:
       
    34     void ref()
       
    35     {
       
    36         ASSERT(!m_deletionHasBegun);
       
    37         ASSERT(!m_adoptionIsRequired);
       
    38         ++m_refCount;
       
    39     }
       
    40 
       
    41     bool hasOneRef() const
       
    42     {
       
    43         ASSERT(!m_deletionHasBegun);
       
    44         return m_refCount == 1;
       
    45     }
       
    46 
       
    47     int refCount() const
       
    48     {
       
    49         return m_refCount;
       
    50     }
       
    51 
       
    52     void relaxAdoptionRequirement()
       
    53     {
       
    54 #ifndef NDEBUG
       
    55         ASSERT(!m_deletionHasBegun);
       
    56         ASSERT(m_adoptionIsRequired);
       
    57         m_adoptionIsRequired = false;
       
    58 #endif
       
    59     }
       
    60 
       
    61 protected:
       
    62     RefCountedBase()
       
    63         : m_refCount(1)
       
    64 #ifndef NDEBUG
       
    65         , m_deletionHasBegun(false)
       
    66         , m_adoptionIsRequired(true)
       
    67 #endif
       
    68     {
       
    69     }
       
    70 
       
    71     ~RefCountedBase()
       
    72     {
       
    73         ASSERT(m_deletionHasBegun);
       
    74         ASSERT(!m_adoptionIsRequired);
       
    75     }
       
    76 
       
    77     // Returns whether the pointer should be freed or not.
       
    78     bool derefBase()
       
    79     {
       
    80         ASSERT(!m_deletionHasBegun);
       
    81         ASSERT(!m_adoptionIsRequired);
       
    82 
       
    83         ASSERT(m_refCount > 0);
       
    84         if (m_refCount == 1) {
       
    85 #ifndef NDEBUG
       
    86             m_deletionHasBegun = true;
       
    87 #endif
       
    88             return true;
       
    89         }
       
    90 
       
    91         --m_refCount;
       
    92         return false;
       
    93     }
       
    94 
       
    95     // Helper for generating JIT code. Please do not use for non-JIT purposes.
       
    96     int* addressOfCount()
       
    97     {
       
    98         return &m_refCount;
       
    99     }
       
   100 
       
   101 #ifndef NDEBUG
       
   102     bool deletionHasBegun() const
       
   103     {
       
   104         return m_deletionHasBegun;
       
   105     }
       
   106 #endif
       
   107 
       
   108 private:
       
   109     template<typename T> friend class CrossThreadRefCounted;
       
   110 
       
   111 #ifndef NDEBUG
       
   112     friend void adopted(RefCountedBase*);
       
   113 #endif
       
   114 
       
   115     int m_refCount;
       
   116 #ifndef NDEBUG
       
   117     bool m_deletionHasBegun;
       
   118     bool m_adoptionIsRequired;
       
   119 #endif
       
   120 };
       
   121 
       
   122 #ifndef NDEBUG
       
   123 
       
   124 inline void adopted(RefCountedBase* object)
       
   125 {
       
   126     if (!object)
       
   127         return;
       
   128     ASSERT(!object->m_deletionHasBegun);
       
   129     object->m_adoptionIsRequired = false;
       
   130 }
       
   131 
       
   132 #endif
       
   133 
       
   134 template<typename T> class RefCounted : public RefCountedBase, public Noncopyable {
       
   135 public:
       
   136     void deref()
       
   137     {
       
   138         if (derefBase())
       
   139             delete static_cast<T*>(this);
       
   140     }
       
   141 
       
   142 protected:
       
   143     ~RefCounted()
       
   144     {
       
   145     }
       
   146 };
       
   147 
       
   148 template<typename T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated {
       
   149 public:
       
   150     void deref()
       
   151     {
       
   152         if (derefBase())
       
   153             delete static_cast<T*>(this);
       
   154     }
       
   155 
       
   156 protected:
       
   157     ~RefCountedCustomAllocated()
       
   158     {
       
   159     }
       
   160 };
       
   161 
       
   162 } // namespace WTF
       
   163 
       
   164 using WTF::RefCounted;
       
   165 using WTF::RefCountedCustomAllocated;
       
   166 
       
   167 #endif // RefCounted_h