Index: Source/heap/Heap.h |
diff --git a/Source/heap/Heap.h b/Source/heap/Heap.h |
index 5c4bebf5291cc957248698461ab22dc4e3b2dff9..a5d921b93aa0621202527168003f97106f2b3ff4 100644 |
--- a/Source/heap/Heap.h |
+++ b/Source/heap/Heap.h |
@@ -437,11 +437,28 @@ public: |
m_keepAlive = new Persistent<T>(static_cast<T*>(this)); |
} |
+ // Override ref to deal with a case where a reference count goes up |
+ // from 0 to 1. This can happen in the following scenario: |
+ // (1) The reference count becomes 0, but Handles keep references to the object. |
+ // (2) The Handle is assigned to a RefPtr. The reference count becomes 1. |
+ // In this case, we have to resurrect m_keepAlive. |
+ void ref() |
+ { |
+ if (UNLIKELY(!RefCounted<T>::refCount())) { |
abarth-chromium
2013/05/29 20:39:38
This is likely to be a noticeable perf hit on some
haraken
2013/05/30 04:50:52
Yes, but I guess we will face a bunch of other per
|
+ ASSERT(!m_keepAlive); |
+ ASSERT(Heap::contains(reinterpret_cast<Address>(this))); |
+ m_keepAlive = new Persistent<T>(static_cast<T*>(this)); |
+ } |
+ RefCounted<T>::refBase(); |
+ } |
+ |
// Override deref to deal with our own deallocation based on ref counting. |
void deref() |
{ |
- if (RefCounted<T>::derefBase()) |
+ if (RefCounted<T>::derefBase()) { |
delete m_keepAlive; |
+ m_keepAlive = 0; |
+ } |
} |
// For now we don't trace through things that are still ref counted, so |