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

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

Powered by Google App Engine
This is Rietveld 408576698