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

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: Have MutationObserver keep weak references to its registrations 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<RawPtrWillBeWeakMember<MutationObserverRegistration> > reg istrations(m_registrations);
156 for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.b egin(); iter != registrations.end(); ++iter) 156 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> >::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
157 (*iter)->unregister(); 157 (*iter)->unregister();
158 #if ENABLE(OILPAN)
159 m_registrations.clear();
160 #endif
158 } 161 }
159 162
160 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion) 163 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion)
161 { 164 {
162 ASSERT(!m_registrations.contains(registration)); 165 ASSERT(!m_registrations.contains(registration));
163 m_registrations.add(registration); 166 m_registrations.add(registration);
164 } 167 }
165 168
166 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on) 169 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on)
167 { 170 {
168 ASSERT(m_registrations.contains(registration)); 171 ASSERT(m_registrations.contains(registration));
169 m_registrations.remove(registration); 172 m_registrations.remove(registration);
170 } 173 }
171 174
172 typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet; 175 typedef WillBeHeapHashSet<RefPtrWillBeMember<MutationObserver> > MutationObserve rSet;
173 176
174 static MutationObserverSet& activeMutationObservers() 177 static MutationObserverSet& activeMutationObservers()
175 { 178 {
179 #if ENABLE(OILPAN)
180 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, activeObservers, (new M utationObserverSet()));
181 return *activeObservers;
182 #else
176 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ()); 183 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ());
177 return activeObservers; 184 return activeObservers;
185 #endif
178 } 186 }
179 187
180 static MutationObserverSet& suspendedMutationObservers() 188 static MutationObserverSet& suspendedMutationObservers()
181 { 189 {
190 #if ENABLE(OILPAN)
191 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspendedObservers, (ne w MutationObserverSet()));
192 return *suspendedObservers;
193 #else
182 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ()); 194 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ());
183 return suspendedObservers; 195 return suspendedObservers;
196 #endif
184 } 197 }
185 198
186 static void activateObserver(PassRefPtr<MutationObserver> observer) 199 static void activateObserver(PassRefPtrWillBeRawPtr<MutationObserver> observer)
187 { 200 {
188 if (activeMutationObservers().isEmpty()) 201 if (activeMutationObservers().isEmpty())
189 Microtask::enqueueMicrotask(&MutationObserver::deliverMutations); 202 Microtask::enqueueMicrotask(&MutationObserver::deliverMutations);
190 203
191 activeMutationObservers().add(observer); 204 activeMutationObservers().add(observer);
192 } 205 }
193 206
194 void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation ) 207 void MutationObserver::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationReco rd> mutation)
195 { 208 {
196 ASSERT(isMainThread()); 209 ASSERT(isMainThread());
197 m_records.append(mutation); 210 m_records.append(mutation);
198 activateObserver(this); 211 activateObserver(this);
199 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this); 212 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this);
200 } 213 }
201 214
202 void MutationObserver::setHasTransientRegistration() 215 void MutationObserver::setHasTransientRegistration()
203 { 216 {
204 ASSERT(isMainThread()); 217 ASSERT(isMainThread());
205 activateObserver(this); 218 activateObserver(this);
206 } 219 }
207 220
208 HashSet<Node*> MutationObserver::getObservedNodes() const 221 HashSet<Node*> MutationObserver::getObservedNodes() const
209 { 222 {
210 HashSet<Node*> observedNodes; 223 HashSet<Node*> observedNodes;
211 for (HashSet<MutationObserverRegistration*>::const_iterator iter = m_registr ations.begin(); iter != m_registrations.end(); ++iter) 224 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> >::const_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter)
212 (*iter)->addRegistrationNodesToSet(observedNodes); 225 (*iter)->addRegistrationNodesToSet(observedNodes);
213 return observedNodes; 226 return observedNodes;
214 } 227 }
215 228
216 bool MutationObserver::canDeliver() 229 bool MutationObserver::canDeliver()
217 { 230 {
218 return !m_callback->executionContext()->activeDOMObjectsAreSuspended(); 231 return !m_callback->executionContext()->activeDOMObjectsAreSuspended();
219 } 232 }
220 233
221 void MutationObserver::deliver() 234 void MutationObserver::deliver()
222 { 235 {
223 ASSERT(canDeliver()); 236 ASSERT(canDeliver());
224 237
225 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary 238 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary
226 // to make a copy of the transient registrations before operating on them. 239 // to make a copy of the transient registrations before operating on them.
227 Vector<MutationObserverRegistration*, 1> transientRegistrations; 240 WillBeHeapVector<RawPtrWillBeMember<MutationObserverRegistration>, 1> transi entRegistrations;
228 for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations .begin(); iter != m_registrations.end(); ++iter) { 241 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> >::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++ite r) {
229 if ((*iter)->hasTransientRegistrations()) 242 if ((*iter)->hasTransientRegistrations())
230 transientRegistrations.append(*iter); 243 transientRegistrations.append(*iter);
231 } 244 }
232 for (size_t i = 0; i < transientRegistrations.size(); ++i) 245 for (size_t i = 0; i < transientRegistrations.size(); ++i)
233 transientRegistrations[i]->clearTransientRegistrations(); 246 transientRegistrations[i]->clearTransientRegistrations();
234 247
235 if (m_records.isEmpty()) 248 if (m_records.isEmpty())
236 return; 249 return;
237 250
238 Vector<RefPtr<MutationRecord> > records; 251 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > records;
239 records.swap(m_records); 252 records.swap(m_records);
240 253
241 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this); 254 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this);
242 m_callback->call(records, this); 255 m_callback->call(records, this);
243 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text()); 256 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text());
244 } 257 }
245 258
246 void MutationObserver::resumeSuspendedObservers() 259 void MutationObserver::resumeSuspendedObservers()
247 { 260 {
248 ASSERT(isMainThread()); 261 ASSERT(isMainThread());
249 if (suspendedMutationObservers().isEmpty()) 262 if (suspendedMutationObservers().isEmpty())
250 return; 263 return;
251 264
252 Vector<RefPtr<MutationObserver> > suspended; 265 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > suspended;
253 copyToVector(suspendedMutationObservers(), suspended); 266 copyToVector(suspendedMutationObservers(), suspended);
254 for (size_t i = 0; i < suspended.size(); ++i) { 267 for (size_t i = 0; i < suspended.size(); ++i) {
255 if (suspended[i]->canDeliver()) { 268 if (suspended[i]->canDeliver()) {
256 suspendedMutationObservers().remove(suspended[i]); 269 suspendedMutationObservers().remove(suspended[i]);
257 activateObserver(suspended[i]); 270 activateObserver(suspended[i]);
258 } 271 }
259 } 272 }
260 } 273 }
261 274
262 void MutationObserver::deliverMutations() 275 void MutationObserver::deliverMutations()
263 { 276 {
264 ASSERT(isMainThread()); 277 ASSERT(isMainThread());
265 Vector<RefPtr<MutationObserver> > observers; 278 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > observers;
266 copyToVector(activeMutationObservers(), observers); 279 copyToVector(activeMutationObservers(), observers);
267 activeMutationObservers().clear(); 280 activeMutationObservers().clear();
268 std::sort(observers.begin(), observers.end(), ObserverLessThan()); 281 std::sort(observers.begin(), observers.end(), ObserverLessThan());
269 for (size_t i = 0; i < observers.size(); ++i) { 282 for (size_t i = 0; i < observers.size(); ++i) {
270 if (observers[i]->canDeliver()) 283 if (observers[i]->canDeliver())
271 observers[i]->deliver(); 284 observers[i]->deliver();
272 else 285 else
273 suspendedMutationObservers().add(observers[i]); 286 suspendedMutationObservers().add(observers[i]);
274 } 287 }
275 } 288 }
276 289
290 void MutationObserver::trace(Visitor* visitor)
291 {
292 visitor->trace(m_records);
293 visitor->trace(m_registrations);
294 }
295
277 } // namespace WebCore 296 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698