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

Side by Side Diff: Source/core/dom/MutationObserver.cpp

Issue 236653002: Oilpan: move mutation observers to the Oilpan heap. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased + explicitly dispose() mutation observer registrations always (non-Oilpan also.) Created 6 years, 8 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) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "core/dom/MutationRecord.h" 42 #include "core/dom/MutationRecord.h"
43 #include "core/dom/Node.h" 43 #include "core/dom/Node.h"
44 #include "core/inspector/InspectorInstrumentation.h" 44 #include "core/inspector/InspectorInstrumentation.h"
45 #include "wtf/MainThread.h" 45 #include "wtf/MainThread.h"
46 46
47 namespace WebCore { 47 namespace WebCore {
48 48
49 static unsigned s_observerPriority = 0; 49 static unsigned s_observerPriority = 0;
50 50
51 struct MutationObserver::ObserverLessThan { 51 struct MutationObserver::ObserverLessThan {
52 bool operator()(const RefPtr<MutationObserver>& lhs, const RefPtr<MutationOb server>& rhs) 52 bool operator()(const RefPtrWillBeMember<MutationObserver>& lhs, const RefPt rWillBeMember<MutationObserver>& rhs)
53 { 53 {
54 return lhs->m_priority < rhs->m_priority; 54 return lhs->m_priority < rhs->m_priority;
55 } 55 }
56 }; 56 };
57 57
58 PassRefPtr<MutationObserver> MutationObserver::create(PassOwnPtr<MutationCallbac k> callback) 58 PassRefPtrWillBeRawPtr<MutationObserver> MutationObserver::create(PassOwnPtr<Mut ationCallback> callback)
59 { 59 {
60 ASSERT(isMainThread()); 60 ASSERT(isMainThread());
61 return adoptRef(new MutationObserver(callback)); 61 return adoptRefWillBeNoop(new MutationObserver(callback));
62 } 62 }
63 63
64 MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback) 64 MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback)
65 : m_callback(callback) 65 : m_callback(callback)
66 , m_priority(s_observerPriority++) 66 , m_priority(s_observerPriority++)
67 { 67 {
68 ScriptWrappable::init(this); 68 ScriptWrappable::init(this);
69 } 69 }
70 70
71 MutationObserver::~MutationObserver() 71 MutationObserver::~MutationObserver()
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } 133 }
134 134
135 if (!(options & (Attributes | CharacterData | ChildList))) { 135 if (!(options & (Attributes | CharacterData | ChildList))) {
136 exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true."); 136 exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
137 return; 137 return;
138 } 138 }
139 139
140 node->registerMutationObserver(*this, options, attributeFilter); 140 node->registerMutationObserver(*this, options, attributeFilter);
141 } 141 }
142 142
143 Vector<RefPtr<MutationRecord> > MutationObserver::takeRecords() 143 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > MutationObserver::takeReco rds()
144 { 144 {
145 Vector<RefPtr<MutationRecord> > records; 145 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > records;
146 records.swap(m_records); 146 records.swap(m_records);
147 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this); 147 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this);
148 return records; 148 return records;
149 } 149 }
150 150
151 void MutationObserver::disconnect() 151 void MutationObserver::disconnect()
152 { 152 {
153 m_records.clear(); 153 m_records.clear();
154 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this); 154 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this);
155 HashSet<MutationObserverRegistration*> registrations(m_registrations); 155 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > registr ations(m_registrations);
156 for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.b egin(); iter != registrations.end(); ++iter) 156 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::i terator iter = registrations.begin(); iter != registrations.end(); ++iter)
157 (*iter)->unregister(); 157 (*iter)->unregister();
158 ASSERT(m_registrations.isEmpty());
158 } 159 }
159 160
160 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion) 161 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion)
161 { 162 {
162 ASSERT(!m_registrations.contains(registration)); 163 ASSERT(!m_registrations.contains(registration));
163 m_registrations.add(registration); 164 m_registrations.add(registration);
164 } 165 }
165 166
166 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on) 167 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on)
167 { 168 {
168 ASSERT(m_registrations.contains(registration)); 169 ASSERT(m_registrations.contains(registration));
169 m_registrations.remove(registration); 170 m_registrations.remove(registration);
170 } 171 }
171 172
172 typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet; 173 typedef WillBeHeapHashSet<RefPtrWillBeMember<MutationObserver> > MutationObserve rSet;
173 174
174 static MutationObserverSet& activeMutationObservers() 175 static MutationObserverSet& activeMutationObservers()
175 { 176 {
177 #if ENABLE(OILPAN)
178 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, activeObservers, (new M utationObserverSet()));
179 return *activeObservers;
180 #else
176 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ()); 181 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ());
177 return activeObservers; 182 return activeObservers;
183 #endif
178 } 184 }
179 185
180 static MutationObserverSet& suspendedMutationObservers() 186 static MutationObserverSet& suspendedMutationObservers()
181 { 187 {
188 #if ENABLE(OILPAN)
189 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspendedObservers, (ne w MutationObserverSet()));
190 return *suspendedObservers;
191 #else
182 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ()); 192 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ());
183 return suspendedObservers; 193 return suspendedObservers;
194 #endif
184 } 195 }
185 196
186 static void activateObserver(PassRefPtr<MutationObserver> observer) 197 static void activateObserver(PassRefPtrWillBeRawPtr<MutationObserver> observer)
187 { 198 {
188 if (activeMutationObservers().isEmpty()) 199 if (activeMutationObservers().isEmpty())
189 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutation s)); 200 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutation s));
190 201
191 activeMutationObservers().add(observer); 202 activeMutationObservers().add(observer);
192 } 203 }
193 204
194 void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation ) 205 void MutationObserver::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationReco rd> mutation)
195 { 206 {
196 ASSERT(isMainThread()); 207 ASSERT(isMainThread());
197 m_records.append(mutation); 208 m_records.append(mutation);
198 activateObserver(this); 209 activateObserver(this);
199 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this); 210 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this);
200 } 211 }
201 212
202 void MutationObserver::setHasTransientRegistration() 213 void MutationObserver::setHasTransientRegistration()
203 { 214 {
204 ASSERT(isMainThread()); 215 ASSERT(isMainThread());
205 activateObserver(this); 216 activateObserver(this);
206 } 217 }
207 218
208 HashSet<Node*> MutationObserver::getObservedNodes() const 219 HashSet<Node*> MutationObserver::getObservedNodes() const
209 { 220 {
210 HashSet<Node*> observedNodes; 221 HashSet<Node*> observedNodes;
211 for (HashSet<MutationObserverRegistration*>::const_iterator iter = m_registr ations.begin(); iter != m_registrations.end(); ++iter) 222 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::c onst_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++i ter)
212 (*iter)->addRegistrationNodesToSet(observedNodes); 223 (*iter)->addRegistrationNodesToSet(observedNodes);
213 return observedNodes; 224 return observedNodes;
214 } 225 }
215 226
216 bool MutationObserver::canDeliver() 227 bool MutationObserver::canDeliver()
217 { 228 {
218 return !m_callback->executionContext()->activeDOMObjectsAreSuspended(); 229 return !m_callback->executionContext()->activeDOMObjectsAreSuspended();
219 } 230 }
220 231
221 void MutationObserver::deliver() 232 void MutationObserver::deliver()
222 { 233 {
223 ASSERT(canDeliver()); 234 ASSERT(canDeliver());
224 235
225 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary 236 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary
226 // to make a copy of the transient registrations before operating on them. 237 // to make a copy of the transient registrations before operating on them.
227 Vector<MutationObserverRegistration*, 1> transientRegistrations; 238 WillBeHeapVector<RawPtrWillBeMember<MutationObserverRegistration>, 1> transi entRegistrations;
228 for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations .begin(); iter != m_registrations.end(); ++iter) { 239 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::i terator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) {
229 if ((*iter)->hasTransientRegistrations()) 240 if ((*iter)->hasTransientRegistrations())
230 transientRegistrations.append(*iter); 241 transientRegistrations.append(*iter);
231 } 242 }
232 for (size_t i = 0; i < transientRegistrations.size(); ++i) 243 for (size_t i = 0; i < transientRegistrations.size(); ++i)
233 transientRegistrations[i]->clearTransientRegistrations(); 244 transientRegistrations[i]->clearTransientRegistrations();
234 245
235 if (m_records.isEmpty()) 246 if (m_records.isEmpty())
236 return; 247 return;
237 248
238 Vector<RefPtr<MutationRecord> > records; 249 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > records;
239 records.swap(m_records); 250 records.swap(m_records);
240 251
241 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this); 252 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this);
242 m_callback->call(records, this); 253 m_callback->call(records, this);
243 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text()); 254 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text());
244 } 255 }
245 256
246 void MutationObserver::resumeSuspendedObservers() 257 void MutationObserver::resumeSuspendedObservers()
247 { 258 {
248 ASSERT(isMainThread()); 259 ASSERT(isMainThread());
249 if (suspendedMutationObservers().isEmpty()) 260 if (suspendedMutationObservers().isEmpty())
250 return; 261 return;
251 262
252 Vector<RefPtr<MutationObserver> > suspended; 263 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > suspended;
253 copyToVector(suspendedMutationObservers(), suspended); 264 copyToVector(suspendedMutationObservers(), suspended);
254 for (size_t i = 0; i < suspended.size(); ++i) { 265 for (size_t i = 0; i < suspended.size(); ++i) {
255 if (suspended[i]->canDeliver()) { 266 if (suspended[i]->canDeliver()) {
256 suspendedMutationObservers().remove(suspended[i]); 267 suspendedMutationObservers().remove(suspended[i]);
257 activateObserver(suspended[i]); 268 activateObserver(suspended[i]);
258 } 269 }
259 } 270 }
260 } 271 }
261 272
262 void MutationObserver::deliverMutations() 273 void MutationObserver::deliverMutations()
263 { 274 {
264 ASSERT(isMainThread()); 275 ASSERT(isMainThread());
265 Vector<RefPtr<MutationObserver> > observers; 276 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > observers;
266 copyToVector(activeMutationObservers(), observers); 277 copyToVector(activeMutationObservers(), observers);
267 activeMutationObservers().clear(); 278 activeMutationObservers().clear();
268 std::sort(observers.begin(), observers.end(), ObserverLessThan()); 279 std::sort(observers.begin(), observers.end(), ObserverLessThan());
269 for (size_t i = 0; i < observers.size(); ++i) { 280 for (size_t i = 0; i < observers.size(); ++i) {
270 if (observers[i]->canDeliver()) 281 if (observers[i]->canDeliver())
271 observers[i]->deliver(); 282 observers[i]->deliver();
272 else 283 else
273 suspendedMutationObservers().add(observers[i]); 284 suspendedMutationObservers().add(observers[i]);
274 } 285 }
275 } 286 }
276 287
288 void MutationObserver::trace(Visitor* visitor)
289 {
290 visitor->trace(m_records);
291 visitor->trace(m_registrations);
292 }
293
277 } // namespace WebCore 294 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698