Index: Source/platform/LifecycleNotifier.h |
diff --git a/Source/platform/LifecycleNotifier.h b/Source/platform/LifecycleNotifier.h |
index b11ad9b50835020d9650eabb9649551c0d084384..9106a799c3e62951f579bae007b43b3b4f5e3278 100644 |
--- a/Source/platform/LifecycleNotifier.h |
+++ b/Source/platform/LifecycleNotifier.h |
@@ -38,8 +38,8 @@ class LifecycleNotifier { |
public: |
virtual ~LifecycleNotifier(); |
- void addObserver(Observer*); |
- void removeObserver(Observer*); |
+ void addObserver(Observer*, bool); |
+ void removeObserver(Observer*, bool); |
// notifyContextDestroyed() should be explicitly dispatched from an |
// observed context to notify observers that contextDestroyed(). |
@@ -80,6 +80,10 @@ protected: |
GC_PLUGIN_IGNORE("467502") |
ObserverSet m_observers; |
+#if !ENABLE(OILPAN) |
+ bool isObserverAlive(Observer*&) const; |
+#endif |
+ |
#if ENABLE(ASSERT) |
T* context() { return static_cast<T*>(this); } |
#endif |
@@ -88,6 +92,19 @@ private: |
bool m_didCallContextDestroyed; |
}; |
+#if !ENABLE(OILPAN) |
+template<typename T, typename Observer> |
+bool LifecycleNotifier<T, Observer>::isObserverAlive(Observer*& observer) const |
+{ |
+ if (reinterpret_cast<uintptr_t>(observer) & 0x1) { |
+ observer = reinterpret_cast<Observer*>(reinterpret_cast<uintptr_t>(observer) & ~0x1); |
+ if (Heap::willObjectBeLazilySwept(observer)) |
+ return false; |
+ } |
+ return true; |
+} |
+#endif |
+ |
template<typename T, typename Observer> |
inline LifecycleNotifier<T, Observer>::~LifecycleNotifier() |
{ |
@@ -97,6 +114,8 @@ inline LifecycleNotifier<T, Observer>::~LifecycleNotifier() |
#if !ENABLE(OILPAN) |
TemporaryChange<IterationType> scope(m_iterating, IteratingOverAll); |
for (Observer* observer : m_observers) { |
+ if (!isObserverAlive(observer)) |
+ continue; |
ASSERT(observer->lifecycleContext() == context()); |
observer->clearLifecycleContext(); |
} |
@@ -114,6 +133,10 @@ inline void LifecycleNotifier<T, Observer>::notifyContextDestroyed() |
Vector<Observer*> snapshotOfObservers; |
copyToVector(m_observers, snapshotOfObservers); |
for (Observer* observer : snapshotOfObservers) { |
+#if !ENABLE(OILPAN) |
+ if (!isObserverAlive(observer)) |
+ continue; |
+#endif |
// FIXME: Oilpan: At the moment, it's possible that the Observer is |
// destructed during the iteration. Once we enable Oilpan by default |
// for Observers, we can remove the hack by making m_observers |
@@ -128,15 +151,27 @@ inline void LifecycleNotifier<T, Observer>::notifyContextDestroyed() |
} |
template<typename T, typename Observer> |
-inline void LifecycleNotifier<T, Observer>::addObserver(Observer* observer) |
+inline void LifecycleNotifier<T, Observer>::addObserver(Observer* observer, bool isGarbageCollected) |
{ |
RELEASE_ASSERT(m_iterating != IteratingOverAll); |
+#if !ENABLE(OILPAN) |
+ if (isGarbageCollected) |
+ observer = reinterpret_cast<Observer*>(reinterpret_cast<uintptr_t>(observer) | 1); |
+#else |
+ (void)isGarbageCollected; |
+#endif |
m_observers.add(observer); |
} |
template<typename T, typename Observer> |
-inline void LifecycleNotifier<T, Observer>::removeObserver(Observer* observer) |
+inline void LifecycleNotifier<T, Observer>::removeObserver(Observer* observer, bool isGarbageCollected) |
{ |
+#if !ENABLE(OILPAN) |
+ if (isGarbageCollected) |
+ observer = reinterpret_cast<Observer*>(reinterpret_cast<uintptr_t>(observer) | 1); |
+#else |
+ (void)isGarbageCollected; |
+#endif |
m_observers.remove(observer); |
} |