OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 if (weaknessConfiguration == WeakPersistentConfiguration) { | 130 if (weaknessConfiguration == WeakPersistentConfiguration) { |
131 visitor->registerWeakCell(&m_raw); | 131 visitor->registerWeakCell(&m_raw); |
132 } else { | 132 } else { |
133 visitor->mark(m_raw); | 133 visitor->mark(m_raw); |
134 } | 134 } |
135 } | 135 } |
136 | 136 |
137 RawPtr<T> release() | 137 RawPtr<T> release() |
138 { | 138 { |
139 RawPtr<T> result = m_raw; | 139 RawPtr<T> result = m_raw; |
140 m_raw = nullptr; | 140 assign(nullptr); |
141 return result; | 141 return result; |
142 } | 142 } |
143 | 143 |
144 void clear() { m_raw = nullptr; } | 144 void clear() { assign(nullptr); } |
145 T& operator*() const { return *m_raw; } | 145 T& operator*() const { return *m_raw; } |
146 bool operator!() const { return !m_raw; } | 146 bool operator!() const { return !m_raw; } |
147 operator T*() const { return m_raw; } | 147 operator T*() const { return m_raw; } |
148 operator RawPtr<T>() const { return m_raw; } | 148 operator RawPtr<T>() const { return m_raw; } |
149 T* operator->() const { return *this; } | 149 T* operator->() const { return *this; } |
150 T* get() const { return m_raw; } | 150 T* get() const { return m_raw; } |
151 | 151 |
152 template<typename U> | 152 template<typename U> |
153 PersistentBase& operator=(U* other) | 153 PersistentBase& operator=(U* other) |
154 { | 154 { |
155 m_raw = other; | 155 assign(other); |
156 checkPointer(); | |
157 recordBacktrace(); | |
158 return *this; | 156 return *this; |
159 } | 157 } |
160 | 158 |
161 PersistentBase& operator=(std::nullptr_t) | 159 PersistentBase& operator=(std::nullptr_t) |
162 { | 160 { |
163 m_raw = nullptr; | 161 assign(nullptr); |
164 return *this; | 162 return *this; |
165 } | 163 } |
166 | 164 |
167 PersistentBase& operator=(const PersistentBase& other) | 165 PersistentBase& operator=(const PersistentBase& other) |
168 { | 166 { |
169 m_raw = other; | 167 assign(other); |
170 checkPointer(); | |
171 recordBacktrace(); | |
172 return *this; | 168 return *this; |
173 } | 169 } |
174 | 170 |
175 template<typename U> | 171 template<typename U> |
176 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro ssThreadnessConfiguration>& other) | 172 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro ssThreadnessConfiguration>& other) |
177 { | 173 { |
178 m_raw = other; | 174 assign(other); |
179 checkPointer(); | |
180 recordBacktrace(); | |
181 return *this; | 175 return *this; |
182 } | 176 } |
183 | 177 |
184 template<typename U> | 178 template<typename U> |
185 PersistentBase& operator=(const Member<U>& other) | 179 PersistentBase& operator=(const Member<U>& other) |
186 { | 180 { |
187 m_raw = other; | 181 assign(other); |
188 checkPointer(); | |
189 recordBacktrace(); | |
190 return *this; | 182 return *this; |
191 } | 183 } |
192 | 184 |
193 template<typename U> | 185 template<typename U> |
194 PersistentBase& operator=(const RawPtr<U>& other) | 186 PersistentBase& operator=(const RawPtr<U>& other) |
195 { | 187 { |
196 m_raw = other; | 188 assign(other); |
197 checkPointer(); | |
198 recordBacktrace(); | |
199 return *this; | 189 return *this; |
200 } | 190 } |
201 | 191 |
202 | 192 |
203 private: | 193 private: |
204 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 194 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
195 void assign(T* ptr) | |
196 { | |
197 m_raw = ptr; | |
198 checkPointer(); | |
199 recordBacktrace(); | |
200 if (m_raw) { | |
201 if (!m_persistentNode) | |
202 initialize(); | |
203 return; | |
204 } | |
205 if (m_persistentNode && crossThreadnessConfiguration != CrossThreadPersi stentConfiguration) | |
206 uninitialize(); | |
207 } | |
208 | |
209 NO_LAZY_SWEEP_SANITIZE_ADDRESS | |
205 void initialize() | 210 void initialize() |
206 { | 211 { |
212 ASSERT(!m_persistentNode); | |
sof
2015/09/14 09:51:59
Of course we need a !m_raw test here still! :)
| |
213 | |
207 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon figuration, crossThreadnessConfiguration>::trace>::trampoline; | 214 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon figuration, crossThreadnessConfiguration>::trace>::trampoline; |
208 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { | 215 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { |
209 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca tePersistentNode(this, traceCallback); | 216 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca tePersistentNode(this, traceCallback); |
210 } else { | 217 } else { |
211 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); | 218 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); |
212 ASSERT(state->checkThread()); | 219 ASSERT(state->checkThread()); |
213 m_persistentNode = state->persistentRegion()->allocatePersistentNode (this, traceCallback); | 220 m_persistentNode = state->persistentRegion()->allocatePersistentNode (this, traceCallback); |
214 #if ENABLE(ASSERT) | 221 #if ENABLE(ASSERT) |
215 m_state = state; | 222 m_state = state; |
216 #endif | 223 #endif |
217 } | 224 } |
218 } | 225 } |
219 | 226 |
220 void uninitialize() | 227 void uninitialize() |
221 { | 228 { |
229 if (!m_persistentNode) | |
230 return; | |
231 | |
222 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { | 232 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { |
223 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers istentNode); | 233 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers istentNode); |
224 } else { | 234 } else { |
225 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); | 235 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); |
226 ASSERT(state->checkThread()); | 236 ASSERT(state->checkThread()); |
227 // Persistent handle must be created and destructed in the same thre ad. | 237 // Persistent handle must be created and destructed in the same thre ad. |
228 ASSERT(m_state == state); | 238 ASSERT(m_state == state); |
229 state->persistentRegion()->freePersistentNode(m_persistentNode); | 239 state->persistentRegion()->freePersistentNode(m_persistentNode); |
230 } | 240 } |
241 m_persistentNode = nullptr; | |
231 } | 242 } |
232 | 243 |
233 void checkPointer() | 244 void checkPointer() |
234 { | 245 { |
235 #if ENABLE(ASSERT) | 246 #if ENABLE(ASSERT) |
236 if (!m_raw) | 247 if (!m_raw) |
237 return; | 248 return; |
238 | 249 |
239 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 250 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
240 // object. In other words, it checks that the pointer is either of: | 251 // object. In other words, it checks that the pointer is either of: |
(...skipping 13 matching lines...) Expand all Loading... | |
254 if (m_raw) | 265 if (m_raw) |
255 m_tracingName = Heap::createBacktraceString(); | 266 m_tracingName = Heap::createBacktraceString(); |
256 } | 267 } |
257 | 268 |
258 String m_tracingName; | 269 String m_tracingName; |
259 #else | 270 #else |
260 inline void recordBacktrace() const { } | 271 inline void recordBacktrace() const { } |
261 #endif | 272 #endif |
262 // m_raw is accessed most, so put it at the first field. | 273 // m_raw is accessed most, so put it at the first field. |
263 T* m_raw; | 274 T* m_raw; |
264 PersistentNode* m_persistentNode; | 275 PersistentNode* m_persistentNode = nullptr; |
265 #if ENABLE(ASSERT) | 276 #if ENABLE(ASSERT) |
266 ThreadState* m_state; | 277 ThreadState* m_state = nullptr; |
267 #endif | 278 #endif |
268 }; | 279 }; |
269 | 280 |
270 // Persistent is a way to create a strong pointer from an off-heap object | 281 // Persistent is a way to create a strong pointer from an off-heap object |
271 // to another on-heap object. As long as the Persistent handle is alive | 282 // to another on-heap object. As long as the Persistent handle is alive |
272 // the GC will keep the object pointed to alive. The Persistent handle is | 283 // the GC will keep the object pointed to alive. The Persistent handle is |
273 // always a GC root from the point of view of the GC. | 284 // always a GC root from the point of view of the GC. |
274 // | 285 // |
275 // We have to construct and destruct Persistent in the same thread. | 286 // We have to construct and destruct Persistent in the same thread. |
276 template<typename T> | 287 template<typename T> |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1209 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C rossThread)WeakPersistent. | 1220 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C rossThread)WeakPersistent. |
1210 static T* unwrap(const StorageType& value) { return value.get(); } | 1221 static T* unwrap(const StorageType& value) { return value.get(); } |
1211 }; | 1222 }; |
1212 | 1223 |
1213 template<typename T> | 1224 template<typename T> |
1214 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1225 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1215 | 1226 |
1216 } // namespace WTF | 1227 } // namespace WTF |
1217 | 1228 |
1218 #endif | 1229 #endif |
OLD | NEW |