REGRESSION r119802: Remove unnecessary ASSERT(!m_deletionHasBegun) from Document.h
[WebKit-https.git] / Source / WebCore / platform / TreeShared.h
1 /*
2  * Copyright (C) 2006, 2007, 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 TreeShared_h
22 #define TreeShared_h
23
24 #include <wtf/Assertions.h>
25 #include <wtf/MainThread.h>
26 #include <wtf/Noncopyable.h>
27
28 namespace WebCore {
29
30 #ifndef NDEBUG
31 template<typename T> class TreeShared;
32 template<typename T> void adopted(TreeShared<T>*);
33 #endif
34
35 class ContainerNode;
36 class SVGElementInstance;
37 template<typename T> class TreeShared;
38
39 // All classes that inherit TreeShared need to define
40 // callRemovedLastRef(TreeShared<T>*). This is necessary
41 // to kill all virtual methods from TreeShared, by which
42 // we can save 8 byte for a virtual method table pointer.
43 void callRemovedLastRef(TreeShared<ContainerNode>*);
44 void callRemovedLastRef(TreeShared<SVGElementInstance>*);
45
46 template<typename T> class TreeShared {
47     WTF_MAKE_NONCOPYABLE(TreeShared);
48 public:
49     TreeShared()
50         : m_parent(0)
51         , m_refCount(1)
52 #ifndef NDEBUG
53         , m_adoptionIsRequired(true)
54 #endif
55     {
56         ASSERT(isMainThread());
57 #ifndef NDEBUG
58         m_deletionHasBegun = false;
59         m_inRemovedLastRefFunction = false;
60 #endif
61     }
62
63 #ifndef NDEBUG
64     virtual ~TreeShared()
65     {
66         ASSERT(isMainThread());
67         ASSERT(!m_refCount);
68         ASSERT(m_deletionHasBegun);
69         ASSERT(!m_adoptionIsRequired);
70     }
71 #endif
72
73     void ref()
74     {
75         ASSERT(isMainThread());
76         ASSERT(!m_deletionHasBegun);
77         ASSERT(!m_inRemovedLastRefFunction);
78         ASSERT(!m_adoptionIsRequired);
79         ++m_refCount;
80     }
81
82     void deref()
83     {
84         ASSERT(isMainThread());
85         ASSERT(m_refCount >= 0);
86         ASSERT(!m_deletionHasBegun);
87         ASSERT(!m_inRemovedLastRefFunction);
88         ASSERT(!m_adoptionIsRequired);
89         if (--m_refCount <= 0 && !m_parent) {
90 #ifndef NDEBUG
91             m_inRemovedLastRefFunction = true;
92 #endif
93             callRemovedLastRef(this);
94         }
95     }
96
97     bool hasOneRef() const
98     {
99         ASSERT(!m_deletionHasBegun);
100         ASSERT(!m_inRemovedLastRefFunction);
101         return m_refCount == 1;
102     }
103
104     int refCount() const
105     {
106         return m_refCount;
107     }
108
109     void setParent(T* parent)
110     { 
111         ASSERT(isMainThread());
112         m_parent = parent; 
113     }
114
115     T* parent() const
116     {
117         ASSERT(isMainThreadOrGCThread());
118         return m_parent;
119     }
120
121 #ifndef NDEBUG
122     bool m_deletionHasBegun;
123     bool m_inRemovedLastRefFunction;
124 #endif
125
126 private:
127     // Never called. removedLastRef() must be implemented in all the classes
128     // that inherit TreeShared.
129     void removedLastRef() { ASSERT(0); }
130
131 #ifndef NDEBUG
132     friend void adopted<>(TreeShared<T>*);
133 #endif
134
135     T* m_parent;
136     int m_refCount;
137
138 #ifndef NDEBUG
139     bool m_adoptionIsRequired;
140 #endif
141 };
142
143 #ifndef NDEBUG
144
145 template<typename T> inline void adopted(TreeShared<T>* object)
146 {
147     if (!object)
148         return;
149     ASSERT(!object->m_deletionHasBegun);
150     ASSERT(!object->m_inRemovedLastRefFunction);
151     object->m_adoptionIsRequired = false;
152 }
153
154 #endif
155
156 }
157
158 #endif // TreeShared.h