Changeset 102721 in webkit


Ignore:
Timestamp:
Dec 13, 2011 5:03:01 PM (12 years ago)
Author:
adamk@chromium.org
Message:

[MutationObservers] Avoid allocations if no observers are present
https://bugs.webkit.org/show_bug.cgi?id=74423

Patch by Rafael Weinstein <rafaelw@chromium.org> on 2011-12-13
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:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r102718 r102721  
     12011-12-13  Rafael Weinstein  <rafaelw@chromium.org>
     2
     3        [MutationObservers] Avoid allocations if no observers are present
     4        https://bugs.webkit.org/show_bug.cgi?id=74423
     5
     6        Reviewed by Ojan Vafai.
     7
     8        This patch adds Node::mayHaveMutationObserversOfType which can be used to check
     9        if there are any observers at all which could receive a give type of mutation.
     10        MutationObserverInterestGroup uses this to possibly exit early (returning
     11        null) if no observers are present.
     12
     13        No tests needed. This patch is just a refactor.
     14
     15        * css/CSSMutableStyleDeclaration.cpp:
     16        * dom/CharacterData.cpp:
     17        (WebCore::CharacterData::dispatchModifiedEvent):
     18        * dom/ChildListMutationScope.cpp:
     19        (WebCore::ChildListMutationAccumulator::MutationAccumulationRouter::incrementScopingLevel):
     20        * dom/Element.cpp:
     21        (WebCore::enqueueAttributesMutationRecord):
     22        * dom/Node.cpp:
     23        (WebCore::Node::mayHaveMutationObserversOfType):
     24        * dom/Node.h:
     25        * dom/WebKitMutationObserver.cpp:
     26        (WebCore::MutationObserverInterestGroup::createIfNeeded):
     27        (WebCore::MutationObserverInterestGroup::createForChildListMutation):
     28        (WebCore::MutationObserverInterestGroup::createForCharacterDataMutation):
     29        (WebCore::MutationObserverInterestGroup::createForAttributesMutation):
     30        (WebCore::MutationObserverInterestGroup::MutationObserverInterestGroup):
     31        (WebCore::MutationObserverInterestGroup::enqueueMutationRecord):
     32        * dom/WebKitMutationObserver.h:
     33
    1342011-12-13  Robin Dunn  <robin@alldunn.com>
    235
  • trunk/Source/WebCore/css/CSSMutableStyleDeclaration.cpp

    r102639 r102721  
    7272
    7373        m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(inlineDecl->element(), HTMLNames::styleAttr);
    74         if (m_mutationRecipients->isEmpty()) {
    75             m_mutationRecipients.clear();
     74        if (!m_mutationRecipients)
    7675            return;
    77         }
    7876
    7977        AtomicString oldValue = m_mutationRecipients->isOldValueRequested() ? inlineDecl->element()->getAttribute(HTMLNames::styleAttr) : nullAtom;
  • trunk/Source/WebCore/dom/CharacterData.cpp

    r101061 r102721  
    192192{
    193193#if ENABLE(MUTATION_OBSERVERS)
    194     OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(this);
    195     mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
     194    if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(this))
     195        mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
    196196#endif
    197197    if (parentNode())
  • trunk/Source/WebCore/dom/ChildListMutationScope.cpp

    r102410 r102721  
    219219    HashMap<Node*, OwnPtr<ChildListMutationAccumulator> >::iterator iter = m_accumulations.find(target);
    220220    ASSERT(iter != m_accumulations.end());
    221 
    222     if (iter->second)
    223         iter->second->childAdded(child);
     221    if (iter == m_accumulations.end() || !iter->second)
     222        return;
     223
     224    iter->second->childAdded(child);
    224225}
    225226
     
    228229    HashMap<Node*, OwnPtr<ChildListMutationAccumulator> >::iterator iter = m_accumulations.find(target);
    229230    ASSERT(iter != m_accumulations.end());
    230 
    231     if (iter->second)
    232         iter->second->willRemoveChild(child);
     231    if (iter == m_accumulations.end() || !iter->second)
     232        return;
     233
     234    iter->second->willRemoveChild(child);
    233235}
    234236
     
    241243    }
    242244
    243     OwnPtr<MutationObserverInterestGroup> observers = MutationObserverInterestGroup::createForChildListMutation(target);
    244     if (observers->isEmpty())
     245    if (OwnPtr<MutationObserverInterestGroup> observers = MutationObserverInterestGroup::createForChildListMutation(target))
     246        m_accumulations.set(target, adoptPtr(new ChildListMutationAccumulator(target, observers.release())));
     247#ifndef NDEBUG
     248    else
    245249        m_accumulations.set(target, nullptr);
    246     else
    247         m_accumulations.set(target, adoptPtr(new ChildListMutationAccumulator(target, observers.release())));
     250#endif
    248251}
    249252
  • trunk/Source/WebCore/dom/Element.cpp

    r102695 r102721  
    184184static void enqueueAttributesMutationRecord(Element* target, const QualifiedName& attributeName, const AtomicString& oldValue)
    185185{
    186     OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(target, attributeName);
    187     mutationRecipients->enqueueMutationRecord(MutationRecord::createAttributes(target, attributeName, oldValue));
     186    if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(target, attributeName))
     187        mutationRecipients->enqueueMutationRecord(MutationRecord::createAttributes(target, attributeName, oldValue));
    188188}
    189189#endif
  • trunk/Source/WebCore/dom/Node.cpp

    r102431 r102721  
    27152715}
    27162716
     2717bool Node::mayHaveMutationObserversOfType(WebKitMutationObserver::MutationType type)
     2718{
     2719    return document()->hasSubtreeMutationObserverOfType(type) || (hasRareData() && (rareData()->mutationObserverRegistry() || rareData()->transientMutationObserverRegistry()));
     2720}
     2721
    27172722void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type, const AtomicString& attributeName)
    27182723{
  • trunk/Source/WebCore/dom/Node.h

    r102619 r102721  
    600600#if ENABLE(MUTATION_OBSERVERS)
    601601    void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType, const AtomicString& attributeName = nullAtom);
     602    bool mayHaveMutationObserversOfType(WebKitMutationObserver::MutationType);
    602603    MutationObserverRegistration* registerMutationObserver(PassRefPtr<WebKitMutationObserver>);
    603604    void unregisterMutationObserver(MutationObserverRegistration*);
  • trunk/Source/WebCore/dom/WebKitMutationObserver.cpp

    r101597 r102721  
    150150}
    151151
     152PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, WebKitMutationObserver::MutationType type, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag)
     153{
     154    if (!target->mayHaveMutationObserversOfType(type))
     155        return nullptr;
     156
     157    HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
     158    target->getRegisteredMutationObserversOfType(observers, type, attributeName);
     159    if (observers.isEmpty())
     160        return nullptr;
     161
     162    return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
     163}
     164
    152165PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createForChildListMutation(Node* target)
    153166{
    154     return adoptPtr(new MutationObserverInterestGroup(target, WebKitMutationObserver::ChildList));
     167    MutationRecordDeliveryOptions oldValueFlag = 0;
     168    return createIfNeeded(target, WebKitMutationObserver::ChildList, nullAtom, oldValueFlag);
    155169}
    156170
    157171PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createForCharacterDataMutation(Node* target)
    158172{
    159     return adoptPtr(new MutationObserverInterestGroup(target, WebKitMutationObserver::CharacterData));
     173    return createIfNeeded(target, WebKitMutationObserver::CharacterData, nullAtom, WebKitMutationObserver::CharacterDataOldValue);
    160174}
    161175
    162176PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createForAttributesMutation(Node* target, const QualifiedName& attributeName)
    163177{
    164     return adoptPtr(new MutationObserverInterestGroup(target, WebKitMutationObserver::Attributes, attributeName.localName()));
    165 }
    166 
    167 MutationObserverInterestGroup::MutationObserverInterestGroup(Node* target, WebKitMutationObserver::MutationType type, const AtomicString& attributeName)
    168 {
    169     target->getRegisteredMutationObserversOfType(m_observers, type, attributeName);
    170     if (type & WebKitMutationObserver::Attributes)
    171         m_oldValueFlag = WebKitMutationObserver::AttributeOldValue;
    172     else if (type & WebKitMutationObserver::CharacterData)
    173         m_oldValueFlag = WebKitMutationObserver::CharacterDataOldValue;
     178    return createIfNeeded(target, WebKitMutationObserver::Attributes, attributeName.localName(), WebKitMutationObserver::AttributeOldValue);
     179}
     180
     181MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers, MutationRecordDeliveryOptions oldValueFlag)
     182    : m_oldValueFlag(oldValueFlag)
     183{
     184    ASSERT(!observers.isEmpty());
     185    m_observers.swap(observers);
    174186}
    175187
     
    185197void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRecord> prpMutation)
    186198{
    187     if (m_observers.isEmpty())
    188         return;
    189 
    190199    RefPtr<MutationRecord> mutation = prpMutation;
    191200    RefPtr<MutationRecord> mutationWithNullOldValue;
  • trunk/Source/WebCore/dom/WebKitMutationObserver.h

    r101101 r102721  
    104104
    105105    bool isOldValueRequested();
    106     bool isEmpty() { return m_observers.isEmpty(); }
    107106    void enqueueMutationRecord(PassRefPtr<MutationRecord>);
    108107private:
    109     MutationObserverInterestGroup(Node* target, WebKitMutationObserver::MutationType, const AtomicString& attributeName = nullAtom);
     108    static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, WebKitMutationObserver::MutationType, const AtomicString& attributeName, MutationRecordDeliveryOptions oldValueFlag);
     109    MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers, MutationRecordDeliveryOptions oldValueFlag);
    110110
    111111    inline bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
    112112
    113113    HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> m_observers;
    114     WebKitMutationObserver::DeliveryFlags m_oldValueFlag;
     114    MutationRecordDeliveryOptions m_oldValueFlag;
    115115};
    116116
Note: See TracChangeset for help on using the changeset viewer.