OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef GarbageCollected_h | 5 #ifndef GarbageCollected_h |
6 #define GarbageCollected_h | 6 #define GarbageCollected_h |
7 | 7 |
8 #include "platform/heap/ThreadState.h" | 8 #include "platform/heap/ThreadState.h" |
9 #include "wtf/Allocator.h" | 9 #include "wtf/Allocator.h" |
10 #include "wtf/Assertions.h" | 10 #include "wtf/Assertions.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 static_cast<T*>(this)->~T(); | 266 static_cast<T*>(this)->~T(); |
267 } | 267 } |
268 | 268 |
269 GarbageCollectedFinalized() { } | 269 GarbageCollectedFinalized() { } |
270 ~GarbageCollectedFinalized() { } | 270 ~GarbageCollectedFinalized() { } |
271 | 271 |
272 template<typename U> friend struct HasFinalizer; | 272 template<typename U> friend struct HasFinalizer; |
273 template<typename U, bool> friend struct FinalizerTraitImpl; | 273 template<typename U, bool> friend struct FinalizerTraitImpl; |
274 }; | 274 }; |
275 | 275 |
276 // Base class for objects that are in the Blink garbage-collected heap | |
277 // and are still reference counted. | |
278 // | |
279 // This class should be used sparingly and only to gradually move | |
280 // objects from being reference counted to being managed by the blink | |
281 // garbage collector. | |
282 // | |
283 // While the current reference counting keeps one of these objects | |
284 // alive it will have a Persistent handle to itself allocated so we | |
285 // will not reclaim the memory. When the reference count reaches 0 the | |
286 // persistent handle will be deleted. When the garbage collector | |
287 // determines that there are no other references to the object it will | |
288 // be reclaimed and the destructor of the reclaimed object will be | |
289 // called at that time. | |
290 template<typename T> | |
291 class RefCountedGarbageCollected : public GarbageCollectedFinalized<T> { | |
292 WTF_MAKE_NONCOPYABLE(RefCountedGarbageCollected); | |
293 | |
294 public: | |
295 RefCountedGarbageCollected() | |
296 : m_refCount(0) | |
297 { | |
298 } | |
299 | |
300 // Implement method to increase reference count for use with RefPtrs. | |
301 // | |
302 // In contrast to the normal WTF::RefCounted, the reference count can reach | |
303 // 0 and increase again. This happens in the following scenario: | |
304 // | |
305 // (1) The reference count becomes 0, but members, persistents, or | |
306 // on-stack pointers keep references to the object. | |
307 // | |
308 // (2) The pointer is assigned to a RefPtr again and the reference | |
309 // count becomes 1. | |
310 // | |
311 // In this case, we have to resurrect m_keepAlive. | |
312 void ref() | |
313 { | |
314 if (UNLIKELY(!m_refCount)) { | |
315 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<
Address>(this))); | |
316 makeKeepAlive(); | |
317 } | |
318 ++m_refCount; | |
319 } | |
320 | |
321 // Implement method to decrease reference count for use with RefPtrs. | |
322 // | |
323 // In contrast to the normal WTF::RefCounted implementation, the | |
324 // object itself is not deleted when the reference count reaches | |
325 // 0. Instead, the keep-alive persistent handle is deallocated so | |
326 // that the object can be reclaimed when the garbage collector | |
327 // determines that there are no other references to the object. | |
328 void deref() | |
329 { | |
330 ASSERT(m_refCount > 0); | |
331 if (!--m_refCount) { | |
332 delete m_keepAlive; | |
333 m_keepAlive = 0; | |
334 } | |
335 } | |
336 | |
337 bool hasOneRef() | |
338 { | |
339 return m_refCount == 1; | |
340 } | |
341 | |
342 protected: | |
343 ~RefCountedGarbageCollected() { } | |
344 | |
345 private: | |
346 void makeKeepAlive() | |
347 { | |
348 ASSERT(!m_keepAlive); | |
349 m_keepAlive = new Persistent<T>(static_cast<T*>(this)); | |
350 } | |
351 | |
352 int m_refCount; | |
353 Persistent<T>* m_keepAlive; | |
354 }; | |
355 | |
356 template<typename T, bool = WTF::IsSubclassOfTemplate<typename std::remove_const
<T>::type, GarbageCollected>::value> class NeedsAdjustAndMark; | 276 template<typename T, bool = WTF::IsSubclassOfTemplate<typename std::remove_const
<T>::type, GarbageCollected>::value> class NeedsAdjustAndMark; |
357 | 277 |
358 template<typename T> | 278 template<typename T> |
359 class NeedsAdjustAndMark<T, true> { | 279 class NeedsAdjustAndMark<T, true> { |
360 static_assert(sizeof(T), "T must be fully defined"); | 280 static_assert(sizeof(T), "T must be fully defined"); |
361 public: | 281 public: |
362 static const bool value = false; | 282 static const bool value = false; |
363 }; | 283 }; |
364 template <typename T> const bool NeedsAdjustAndMark<T, true>::value; | 284 template <typename T> const bool NeedsAdjustAndMark<T, true>::value; |
365 | 285 |
(...skipping 17 matching lines...) Expand all Loading... |
383 static FalseType isSizeofKnown(...); | 303 static FalseType isSizeofKnown(...); |
384 static T& t; | 304 static T& t; |
385 public: | 305 public: |
386 static const bool value = sizeof(TrueType) == sizeof(isSizeofKnown(&t)); | 306 static const bool value = sizeof(TrueType) == sizeof(isSizeofKnown(&t)); |
387 }; | 307 }; |
388 | 308 |
389 } // namespace blink | 309 } // namespace blink |
390 | 310 |
391 namespace WTF { | 311 namespace WTF { |
392 | 312 |
393 // Adoption is not needed nor wanted for RefCountedGarbageCollected<>-derived ty
pes. | |
394 template<typename T> | |
395 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | |
396 | |
397 } // namespace WTF | 313 } // namespace WTF |
398 | 314 |
399 #endif | 315 #endif |
OLD | NEW |