Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: Source/platform/LifecycleNotifier.h

Issue 1132053002: [WIP]Oilpan: checking for nearly-dead observers. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2013 Google Inc. All Rights Reserved. 3 * Copyright (C) 2013 Google Inc. All Rights Reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 20 matching lines...) Expand all
31 #include "wtf/HashSet.h" 31 #include "wtf/HashSet.h"
32 #include "wtf/TemporaryChange.h" 32 #include "wtf/TemporaryChange.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 template<typename T, typename Observer> 36 template<typename T, typename Observer>
37 class LifecycleNotifier { 37 class LifecycleNotifier {
38 public: 38 public:
39 virtual ~LifecycleNotifier(); 39 virtual ~LifecycleNotifier();
40 40
41 void addObserver(Observer*); 41 void addObserver(Observer*, bool);
42 void removeObserver(Observer*); 42 void removeObserver(Observer*, bool);
43 43
44 // notifyContextDestroyed() should be explicitly dispatched from an 44 // notifyContextDestroyed() should be explicitly dispatched from an
45 // observed context to notify observers that contextDestroyed(). 45 // observed context to notify observers that contextDestroyed().
46 // 46 //
47 // When contextDestroyed() is called, the observer's lifecycleContext() 47 // When contextDestroyed() is called, the observer's lifecycleContext()
48 // is still valid and safe to use during the notification. 48 // is still valid and safe to use during the notification.
49 virtual void notifyContextDestroyed(); 49 virtual void notifyContextDestroyed();
50 50
51 DEFINE_INLINE_VIRTUAL_TRACE() 51 DEFINE_INLINE_VIRTUAL_TRACE()
52 { 52 {
(...skipping 20 matching lines...) Expand all
73 73
74 protected: 74 protected:
75 using ObserverSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Observer>>; 75 using ObserverSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Observer>>;
76 76
77 // FIXME: Oilpan: make LifecycleNotifier<> a GC mixin, somehow. ExecutionCon text 77 // FIXME: Oilpan: make LifecycleNotifier<> a GC mixin, somehow. ExecutionCon text
78 // is the problematic case, as it would then be a class with two GC mixin 78 // is the problematic case, as it would then be a class with two GC mixin
79 // bases, but cannot itself derive from a GC base class also. 79 // bases, but cannot itself derive from a GC base class also.
80 GC_PLUGIN_IGNORE("467502") 80 GC_PLUGIN_IGNORE("467502")
81 ObserverSet m_observers; 81 ObserverSet m_observers;
82 82
83 #if !ENABLE(OILPAN)
84 bool isObserverAlive(Observer*&) const;
85 #endif
86
83 #if ENABLE(ASSERT) 87 #if ENABLE(ASSERT)
84 T* context() { return static_cast<T*>(this); } 88 T* context() { return static_cast<T*>(this); }
85 #endif 89 #endif
86 90
87 private: 91 private:
88 bool m_didCallContextDestroyed; 92 bool m_didCallContextDestroyed;
89 }; 93 };
90 94
95 #if !ENABLE(OILPAN)
96 template<typename T, typename Observer>
97 bool LifecycleNotifier<T, Observer>::isObserverAlive(Observer*& observer) const
98 {
99 if (reinterpret_cast<uintptr_t>(observer) & 0x1) {
100 observer = reinterpret_cast<Observer*>(reinterpret_cast<uintptr_t>(obser ver) & ~0x1);
101 if (Heap::willObjectBeLazilySwept(observer))
102 return false;
103 }
104 return true;
105 }
106 #endif
107
91 template<typename T, typename Observer> 108 template<typename T, typename Observer>
92 inline LifecycleNotifier<T, Observer>::~LifecycleNotifier() 109 inline LifecycleNotifier<T, Observer>::~LifecycleNotifier()
93 { 110 {
94 // FIXME: Enable the following ASSERT. Also see a FIXME in Document::detach( ). 111 // FIXME: Enable the following ASSERT. Also see a FIXME in Document::detach( ).
95 // ASSERT(!m_observers.size() || m_didCallContextDestroyed); 112 // ASSERT(!m_observers.size() || m_didCallContextDestroyed);
96 113
97 #if !ENABLE(OILPAN) 114 #if !ENABLE(OILPAN)
98 TemporaryChange<IterationType> scope(m_iterating, IteratingOverAll); 115 TemporaryChange<IterationType> scope(m_iterating, IteratingOverAll);
99 for (Observer* observer : m_observers) { 116 for (Observer* observer : m_observers) {
117 if (!isObserverAlive(observer))
118 continue;
100 ASSERT(observer->lifecycleContext() == context()); 119 ASSERT(observer->lifecycleContext() == context());
101 observer->clearLifecycleContext(); 120 observer->clearLifecycleContext();
102 } 121 }
103 #endif 122 #endif
104 } 123 }
105 124
106 template<typename T, typename Observer> 125 template<typename T, typename Observer>
107 inline void LifecycleNotifier<T, Observer>::notifyContextDestroyed() 126 inline void LifecycleNotifier<T, Observer>::notifyContextDestroyed()
108 { 127 {
109 // Don't notify contextDestroyed() twice. 128 // Don't notify contextDestroyed() twice.
110 if (m_didCallContextDestroyed) 129 if (m_didCallContextDestroyed)
111 return; 130 return;
112 131
113 TemporaryChange<IterationType> scope(m_iterating, IteratingOverAll); 132 TemporaryChange<IterationType> scope(m_iterating, IteratingOverAll);
114 Vector<Observer*> snapshotOfObservers; 133 Vector<Observer*> snapshotOfObservers;
115 copyToVector(m_observers, snapshotOfObservers); 134 copyToVector(m_observers, snapshotOfObservers);
116 for (Observer* observer : snapshotOfObservers) { 135 for (Observer* observer : snapshotOfObservers) {
136 #if !ENABLE(OILPAN)
137 if (!isObserverAlive(observer))
138 continue;
139 #endif
117 // FIXME: Oilpan: At the moment, it's possible that the Observer is 140 // FIXME: Oilpan: At the moment, it's possible that the Observer is
118 // destructed during the iteration. Once we enable Oilpan by default 141 // destructed during the iteration. Once we enable Oilpan by default
119 // for Observers, we can remove the hack by making m_observers 142 // for Observers, we can remove the hack by making m_observers
120 // a HeapHashSet<WeakMember<Observers>>. (i.e., we can just iterate 143 // a HeapHashSet<WeakMember<Observers>>. (i.e., we can just iterate
121 // m_observers without taking a snapshot). 144 // m_observers without taking a snapshot).
122 if (m_observers.contains(observer)) { 145 if (m_observers.contains(observer)) {
123 ASSERT(observer->lifecycleContext() == context()); 146 ASSERT(observer->lifecycleContext() == context());
124 observer->contextDestroyed(); 147 observer->contextDestroyed();
125 } 148 }
126 } 149 }
127 m_didCallContextDestroyed = true; 150 m_didCallContextDestroyed = true;
128 } 151 }
129 152
130 template<typename T, typename Observer> 153 template<typename T, typename Observer>
131 inline void LifecycleNotifier<T, Observer>::addObserver(Observer* observer) 154 inline void LifecycleNotifier<T, Observer>::addObserver(Observer* observer, bool isGarbageCollected)
132 { 155 {
133 RELEASE_ASSERT(m_iterating != IteratingOverAll); 156 RELEASE_ASSERT(m_iterating != IteratingOverAll);
157 #if !ENABLE(OILPAN)
158 if (isGarbageCollected)
159 observer = reinterpret_cast<Observer*>(reinterpret_cast<uintptr_t>(obser ver) | 1);
160 #else
161 (void)isGarbageCollected;
162 #endif
134 m_observers.add(observer); 163 m_observers.add(observer);
135 } 164 }
136 165
137 template<typename T, typename Observer> 166 template<typename T, typename Observer>
138 inline void LifecycleNotifier<T, Observer>::removeObserver(Observer* observer) 167 inline void LifecycleNotifier<T, Observer>::removeObserver(Observer* observer, b ool isGarbageCollected)
139 { 168 {
169 #if !ENABLE(OILPAN)
170 if (isGarbageCollected)
171 observer = reinterpret_cast<Observer*>(reinterpret_cast<uintptr_t>(obser ver) | 1);
172 #else
173 (void)isGarbageCollected;
174 #endif
140 m_observers.remove(observer); 175 m_observers.remove(observer);
141 } 176 }
142 177
143 } // namespace blink 178 } // namespace blink
144 179
145 #endif // LifecycleNotifier_h 180 #endif // LifecycleNotifier_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698