OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 class RefCountedHeapAllocated : public RefCounted<T>, public HeapAllocatedFinali
zed<T> { | 430 class RefCountedHeapAllocated : public RefCounted<T>, public HeapAllocatedFinali
zed<T> { |
431 WTF_MAKE_NONCOPYABLE(RefCountedHeapAllocated); | 431 WTF_MAKE_NONCOPYABLE(RefCountedHeapAllocated); |
432 | 432 |
433 public: | 433 public: |
434 RefCountedHeapAllocated() | 434 RefCountedHeapAllocated() |
435 { | 435 { |
436 ASSERT(Heap::contains(reinterpret_cast<Address>(this))); | 436 ASSERT(Heap::contains(reinterpret_cast<Address>(this))); |
437 m_keepAlive = new Persistent<T>(static_cast<T*>(this)); | 437 m_keepAlive = new Persistent<T>(static_cast<T*>(this)); |
438 } | 438 } |
439 | 439 |
| 440 // Override ref to deal with a case where a reference count goes up |
| 441 // from 0 to 1. This can happen in the following scenario: |
| 442 // (1) The reference count becomes 0, but Handles have references to the obj
ect. |
| 443 // (2) The Handle is assigned to a RefPtr. The reference count becomes 1. |
| 444 // In this case, we have to resurrect m_keepAlive. |
| 445 void ref() |
| 446 { |
| 447 if (UNLIKELY(!RefCounted<T>::refCount())) { |
| 448 ASSERT(!m_keepAlive); |
| 449 ASSERT(Heap::contains(reinterpret_cast<Address>(this))); |
| 450 m_keepAlive = new Persistent<T>(static_cast<T*>(this)); |
| 451 } |
| 452 RefCounted<T>::refBase(); |
| 453 } |
| 454 |
440 // Override deref to deal with our own deallocation based on ref counting. | 455 // Override deref to deal with our own deallocation based on ref counting. |
441 void deref() | 456 void deref() |
442 { | 457 { |
443 if (RefCounted<T>::derefBase()) | 458 if (RefCounted<T>::derefBase()) { |
444 delete m_keepAlive; | 459 delete m_keepAlive; |
| 460 m_keepAlive = 0; |
| 461 } |
445 } | 462 } |
446 | 463 |
447 // For now we don't trace through things that are still ref counted, so | 464 // For now we don't trace through things that are still ref counted, so |
448 // there is nothing to do in the accept method. | 465 // there is nothing to do in the accept method. |
449 void accept(Visitor*) { } | 466 void accept(Visitor*) { } |
450 | 467 |
451 protected: | 468 protected: |
452 ~RefCountedHeapAllocated() { } | 469 ~RefCountedHeapAllocated() { } |
453 | 470 |
454 private: | 471 private: |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 // You can't mark an object that isn't in the heap. | 577 // You can't mark an object that isn't in the heap. |
561 ASSERT(contains(header)); | 578 ASSERT(contains(header)); |
562 // End of object should also be in the heap. | 579 // End of object should also be in the heap. |
563 ASSERT(contains(header->payloadEnd() - 1)); | 580 ASSERT(contains(header->payloadEnd() - 1)); |
564 header->mark(); | 581 header->mark(); |
565 } | 582 } |
566 | 583 |
567 } // namespace WebCore | 584 } // namespace WebCore |
568 | 585 |
569 #endif | 586 #endif |
OLD | NEW |