Diff
Modified: trunk/Source/WebCore/ChangeLog (102720 => 102721)
--- trunk/Source/WebCore/ChangeLog 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/ChangeLog 2011-12-14 01:03:01 UTC (rev 102721)
@@ -1,3 +1,36 @@
+2011-12-13 Rafael Weinstein <[email protected]>
+
+ [MutationObservers] Avoid allocations if no observers are present
+ https://bugs.webkit.org/show_bug.cgi?id=74423
+
+ Reviewed by Ojan Vafai.
+
+ This patch adds Node::mayHaveMutationObserversOfType which can be used to check
+ if there are any observers at all which could receive a give type of mutation.
+ MutationObserverInterestGroup uses this to possibly exit early (returning
+ null) if no observers are present.
+
+ No tests needed. This patch is just a refactor.
+
+ * css/CSSMutableStyleDeclaration.cpp:
+ * dom/CharacterData.cpp:
+ (WebCore::CharacterData::dispatchModifiedEvent):
+ * dom/ChildListMutationScope.cpp:
+ (WebCore::ChildListMutationAccumulator::MutationAccumulationRouter::incrementScopingLevel):
+ * dom/Element.cpp:
+ (WebCore::enqueueAttributesMutationRecord):
+ * dom/Node.cpp:
+ (WebCore::Node::mayHaveMutationObserversOfType):
+ * dom/Node.h:
+ * dom/WebKitMutationObserver.cpp:
+ (WebCore::MutationObserverInterestGroup::createIfNeeded):
+ (WebCore::MutationObserverInterestGroup::createForChildListMutation):
+ (WebCore::MutationObserverInterestGroup::createForCharacterDataMutation):
+ (WebCore::MutationObserverInterestGroup::createForAttributesMutation):
+ (WebCore::MutationObserverInterestGroup::MutationObserverInterestGroup):
+ (WebCore::MutationObserverInterestGroup::enqueueMutationRecord):
+ * dom/WebKitMutationObserver.h:
+
2011-12-13 Robin Dunn <[email protected]>
Don't make the bitmap transparent when using theme drawing
Modified: trunk/Source/WebCore/css/CSSMutableStyleDeclaration.cpp (102720 => 102721)
--- trunk/Source/WebCore/css/CSSMutableStyleDeclaration.cpp 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/css/CSSMutableStyleDeclaration.cpp 2011-12-14 01:03:01 UTC (rev 102721)
@@ -71,10 +71,8 @@
return;
m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(inlineDecl->element(), HTMLNames::styleAttr);
- if (m_mutationRecipients->isEmpty()) {
- m_mutationRecipients.clear();
+ if (!m_mutationRecipients)
return;
- }
AtomicString oldValue = m_mutationRecipients->isOldValueRequested() ? inlineDecl->element()->getAttribute(HTMLNames::styleAttr) : nullAtom;
m_mutation = MutationRecord::createAttributes(inlineDecl->element(), HTMLNames::styleAttr, oldValue);
Modified: trunk/Source/WebCore/dom/CharacterData.cpp (102720 => 102721)
--- trunk/Source/WebCore/dom/CharacterData.cpp 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/CharacterData.cpp 2011-12-14 01:03:01 UTC (rev 102721)
@@ -191,8 +191,8 @@
void CharacterData::dispatchModifiedEvent(const String& oldData)
{
#if ENABLE(MUTATION_OBSERVERS)
- OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(this);
- mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
+ if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(this))
+ mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
#endif
if (parentNode())
parentNode()->childrenChanged();
Modified: trunk/Source/WebCore/dom/ChildListMutationScope.cpp (102720 => 102721)
--- trunk/Source/WebCore/dom/ChildListMutationScope.cpp 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/ChildListMutationScope.cpp 2011-12-14 01:03:01 UTC (rev 102721)
@@ -218,18 +218,20 @@
{
HashMap<Node*, OwnPtr<ChildListMutationAccumulator> >::iterator iter = m_accumulations.find(target);
ASSERT(iter != m_accumulations.end());
+ if (iter == m_accumulations.end() || !iter->second)
+ return;
- if (iter->second)
- iter->second->childAdded(child);
+ iter->second->childAdded(child);
}
void MutationAccumulationRouter::willRemoveChild(Node* target, Node* child)
{
HashMap<Node*, OwnPtr<ChildListMutationAccumulator> >::iterator iter = m_accumulations.find(target);
ASSERT(iter != m_accumulations.end());
+ if (iter == m_accumulations.end() || !iter->second)
+ return;
- if (iter->second)
- iter->second->willRemoveChild(child);
+ iter->second->willRemoveChild(child);
}
void MutationAccumulationRouter::incrementScopingLevel(Node* target)
@@ -240,11 +242,12 @@
return;
}
- OwnPtr<MutationObserverInterestGroup> observers = MutationObserverInterestGroup::createForChildListMutation(target);
- if (observers->isEmpty())
+ if (OwnPtr<MutationObserverInterestGroup> observers = MutationObserverInterestGroup::createForChildListMutation(target))
+ m_accumulations.set(target, adoptPtr(new ChildListMutationAccumulator(target, observers.release())));
+#ifndef NDEBUG
+ else
m_accumulations.set(target, nullptr);
- else
- m_accumulations.set(target, adoptPtr(new ChildListMutationAccumulator(target, observers.release())));
+#endif
}
void MutationAccumulationRouter::decrementScopingLevel(Node* target)
Modified: trunk/Source/WebCore/dom/Element.cpp (102720 => 102721)
--- trunk/Source/WebCore/dom/Element.cpp 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/Element.cpp 2011-12-14 01:03:01 UTC (rev 102721)
@@ -183,8 +183,8 @@
#if ENABLE(MUTATION_OBSERVERS)
static void enqueueAttributesMutationRecord(Element* target, const QualifiedName& attributeName, const AtomicString& oldValue)
{
- OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(target, attributeName);
- mutationRecipients->enqueueMutationRecord(MutationRecord::createAttributes(target, attributeName, oldValue));
+ if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(target, attributeName))
+ mutationRecipients->enqueueMutationRecord(MutationRecord::createAttributes(target, attributeName, oldValue));
}
#endif
Modified: trunk/Source/WebCore/dom/Node.cpp (102720 => 102721)
--- trunk/Source/WebCore/dom/Node.cpp 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/Node.cpp 2011-12-14 01:03:01 UTC (rev 102721)
@@ -2714,6 +2714,11 @@
}
}
+bool Node::mayHaveMutationObserversOfType(WebKitMutationObserver::MutationType type)
+{
+ return document()->hasSubtreeMutationObserverOfType(type) || (hasRareData() && (rareData()->mutationObserverRegistry() || rareData()->transientMutationObserverRegistry()));
+}
+
void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type, const AtomicString& attributeName)
{
collectMatchingObserversForMutation(observers, this, type, attributeName);
Modified: trunk/Source/WebCore/dom/Node.h (102720 => 102721)
--- trunk/Source/WebCore/dom/Node.h 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/Node.h 2011-12-14 01:03:01 UTC (rev 102721)
@@ -599,6 +599,7 @@
#if ENABLE(MUTATION_OBSERVERS)
void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType, const AtomicString& attributeName = nullAtom);
+ bool mayHaveMutationObserversOfType(WebKitMutationObserver::MutationType);
MutationObserverRegistration* registerMutationObserver(PassRefPtr<WebKitMutationObserver>);
void unregisterMutationObserver(MutationObserverRegistration*);
void registerTransientMutationObserver(MutationObserverRegistration*);
Modified: trunk/Source/WebCore/dom/WebKitMutationObserver.cpp (102720 => 102721)
--- trunk/Source/WebCore/dom/WebKitMutationObserver.cpp 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/WebKitMutationObserver.cpp 2011-12-14 01:03:01 UTC (rev 102721)
@@ -149,28 +149,40 @@
deliveryInProgress = false;
}
+PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, WebKitMutationObserver::MutationType type, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag)
+{
+ if (!target->mayHaveMutationObserversOfType(type))
+ return nullptr;
+
+ HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
+ target->getRegisteredMutationObserversOfType(observers, type, attributeName);
+ if (observers.isEmpty())
+ return nullptr;
+
+ return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
+}
+
PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createForChildListMutation(Node* target)
{
- return adoptPtr(new MutationObserverInterestGroup(target, WebKitMutationObserver::ChildList));
+ MutationRecordDeliveryOptions oldValueFlag = 0;
+ return createIfNeeded(target, WebKitMutationObserver::ChildList, nullAtom, oldValueFlag);
}
PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createForCharacterDataMutation(Node* target)
{
- return adoptPtr(new MutationObserverInterestGroup(target, WebKitMutationObserver::CharacterData));
+ return createIfNeeded(target, WebKitMutationObserver::CharacterData, nullAtom, WebKitMutationObserver::CharacterDataOldValue);
}
PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createForAttributesMutation(Node* target, const QualifiedName& attributeName)
{
- return adoptPtr(new MutationObserverInterestGroup(target, WebKitMutationObserver::Attributes, attributeName.localName()));
+ return createIfNeeded(target, WebKitMutationObserver::Attributes, attributeName.localName(), WebKitMutationObserver::AttributeOldValue);
}
-MutationObserverInterestGroup::MutationObserverInterestGroup(Node* target, WebKitMutationObserver::MutationType type, const AtomicString& attributeName)
+MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers, MutationRecordDeliveryOptions oldValueFlag)
+ : m_oldValueFlag(oldValueFlag)
{
- target->getRegisteredMutationObserversOfType(m_observers, type, attributeName);
- if (type & WebKitMutationObserver::Attributes)
- m_oldValueFlag = WebKitMutationObserver::AttributeOldValue;
- else if (type & WebKitMutationObserver::CharacterData)
- m_oldValueFlag = WebKitMutationObserver::CharacterDataOldValue;
+ ASSERT(!observers.isEmpty());
+ m_observers.swap(observers);
}
bool MutationObserverInterestGroup::isOldValueRequested()
@@ -184,9 +196,6 @@
void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRecord> prpMutation)
{
- if (m_observers.isEmpty())
- return;
-
RefPtr<MutationRecord> mutation = prpMutation;
RefPtr<MutationRecord> mutationWithNullOldValue;
for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
Modified: trunk/Source/WebCore/dom/WebKitMutationObserver.h (102720 => 102721)
--- trunk/Source/WebCore/dom/WebKitMutationObserver.h 2011-12-14 00:20:11 UTC (rev 102720)
+++ trunk/Source/WebCore/dom/WebKitMutationObserver.h 2011-12-14 01:03:01 UTC (rev 102721)
@@ -103,15 +103,15 @@
static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node* target, const QualifiedName& attributeName);
bool isOldValueRequested();
- bool isEmpty() { return m_observers.isEmpty(); }
void enqueueMutationRecord(PassRefPtr<MutationRecord>);
private:
- MutationObserverInterestGroup(Node* target, WebKitMutationObserver::MutationType, const AtomicString& attributeName = nullAtom);
+ static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, WebKitMutationObserver::MutationType, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag);
+ MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers, MutationRecordDeliveryOptions oldValueFlag);
inline bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> m_observers;
- WebKitMutationObserver::DeliveryFlags m_oldValueFlag;
+ MutationRecordDeliveryOptions m_oldValueFlag;
};
}