Title: [267175] trunk/Source/WebCore
Revision
267175
Author
rn...@webkit.org
Date
2020-09-16 18:53:21 -0700 (Wed, 16 Sep 2020)

Log Message

MutationObserverRegistration should be ref counted
https://bugs.webkit.org/show_bug.cgi?id=216528

Reviewed by Darin Adler.

This patch makes MutationObserverRegistration ref counted so that the transient registry can store
Ref<MutationObserverRegistration> instead of a raw pointer. It also merges NodeMutationObserverData
into NodeRareData now that NodeRareData is actually rare after r266714 and r266769.

Before this patch, MutationObserverRegistration had to be kept alive by the originally observed node
using m_nodeKeptAlive whenever a transient observation occurs (i.e. observation of a node which used
to be a part of the subtree of the observed node). With this patch, this complexity is eliminated.

No new tests since there should be no behavioral difference.

* dom/MutationObserver.cpp:
(WebCore::MutationObserver::disconnect): Skip any node for which the observed node had been deleted.
This means that the registration is alive for transient nodes (i.e. a node which used to be a part of
the subtree of the observed node).
(WebCore::MutationObserver::observationStarted): Converted debug assert to a release assert.
(WebCore::MutationObserver::observationEnded): Ditto.
(WebCore::MutationObserver::deliver): Simplified logic a bit using WTF::map.
* dom/MutationObserverRegistration.cpp:
(WebCore::MutationObserverRegistration::create): Added.
(WebCore::MutationObserverRegistration::MutationObserverRegistration): Create a WeakPtr for m_node.
(WebCore::MutationObserverRegistration::observedSubtreeNodeWillDetach): Deleted the code for
m_nodeKeptAlive since the observed node is no longer responsible for keeping this
MutationObserverRegistration alive while transient observarion takes place.
(WebCore::MutationObserverRegistration::takeTransientRegistrations): Ditto.
(WebCore::MutationObserverRegistration::shouldReceiveMutationFrom const):
(WebCore::MutationObserverRegistration::addRegistrationNodesToSet const): Skip m_node if it has been
deleted. This is possible during transient observations.
* dom/MutationObserverRegistration.h:
(WebCore::MutationObserverRegistration): This class is now ref counted. Also made m_node WeakPtr.
(WebCore::MutationObserverRegistration::node):
* dom/Node.cpp:
(WebCore::Node::clearRareData):
(WebCore::Node::moveNodeToNewDocument):
(WebCore::Node::mutationObserverRegistry): Deleted.
(WebCore::Node::transientMutationObserverRegistry): Deleted.
(WebCore::collectMatchingObserversForMutation): Now takes a reference to registry.
(WebCore::Node::registeredMutationObservers):
(WebCore::Node::registerMutationObserver):
(WebCore::Node::unregisterMutationObserver): Converted debug assertions to release assertions. With
script execution forbidden during tree mutations, this should never happen now.
(WebCore::Node::registerTransientMutationObserver):
(WebCore::Node::unregisterTransientMutationObserver): Ditto.
(WebCore::Node::notifyMutationObserversNodeWillDetach):
* dom/Node.h:
* dom/NodeRareData.cpp:
* dom/NodeRareData.h:
(WebCore::NodeMutationObserverData): Merged into NodeRareData.
(WebCore::NodeRareData::mutationObserverData): Deleted.
(WebCore::NodeRareData::ensureMutationObserverData): Deleted.
(WebCore::NodeRareData::mutationObserverRegistry): Added.
(WebCore::NodeRareData::mutationObserverRegistryIfExists): Added.
(WebCore::NodeRareData::transientMutationObserverRegistry): Added.
(WebCore::NodeRareData::useTypes const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (267174 => 267175)


--- trunk/Source/WebCore/ChangeLog	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/ChangeLog	2020-09-17 01:53:21 UTC (rev 267175)
@@ -1,3 +1,64 @@
+2020-09-16  Ryosuke Niwa  <rn...@webkit.org>
+
+        MutationObserverRegistration should be ref counted
+        https://bugs.webkit.org/show_bug.cgi?id=216528
+
+        Reviewed by Darin Adler.
+
+        This patch makes MutationObserverRegistration ref counted so that the transient registry can store
+        Ref<MutationObserverRegistration> instead of a raw pointer. It also merges NodeMutationObserverData
+        into NodeRareData now that NodeRareData is actually rare after r266714 and r266769.
+
+        Before this patch, MutationObserverRegistration had to be kept alive by the originally observed node
+        using m_nodeKeptAlive whenever a transient observation occurs (i.e. observation of a node which used
+        to be a part of the subtree of the observed node). With this patch, this complexity is eliminated.
+
+        No new tests since there should be no behavioral difference.
+
+        * dom/MutationObserver.cpp:
+        (WebCore::MutationObserver::disconnect): Skip any node for which the observed node had been deleted.
+        This means that the registration is alive for transient nodes (i.e. a node which used to be a part of
+        the subtree of the observed node).
+        (WebCore::MutationObserver::observationStarted): Converted debug assert to a release assert.
+        (WebCore::MutationObserver::observationEnded): Ditto.
+        (WebCore::MutationObserver::deliver): Simplified logic a bit using WTF::map.
+        * dom/MutationObserverRegistration.cpp:
+        (WebCore::MutationObserverRegistration::create): Added.
+        (WebCore::MutationObserverRegistration::MutationObserverRegistration): Create a WeakPtr for m_node.
+        (WebCore::MutationObserverRegistration::observedSubtreeNodeWillDetach): Deleted the code for
+        m_nodeKeptAlive since the observed node is no longer responsible for keeping this
+        MutationObserverRegistration alive while transient observarion takes place.
+        (WebCore::MutationObserverRegistration::takeTransientRegistrations): Ditto.
+        (WebCore::MutationObserverRegistration::shouldReceiveMutationFrom const):
+        (WebCore::MutationObserverRegistration::addRegistrationNodesToSet const): Skip m_node if it has been
+        deleted. This is possible during transient observations.
+        * dom/MutationObserverRegistration.h:
+        (WebCore::MutationObserverRegistration): This class is now ref counted. Also made m_node WeakPtr.
+        (WebCore::MutationObserverRegistration::node):
+        * dom/Node.cpp:
+        (WebCore::Node::clearRareData):
+        (WebCore::Node::moveNodeToNewDocument):
+        (WebCore::Node::mutationObserverRegistry): Deleted.
+        (WebCore::Node::transientMutationObserverRegistry): Deleted.
+        (WebCore::collectMatchingObserversForMutation): Now takes a reference to registry.
+        (WebCore::Node::registeredMutationObservers):
+        (WebCore::Node::registerMutationObserver):
+        (WebCore::Node::unregisterMutationObserver): Converted debug assertions to release assertions. With
+        script execution forbidden during tree mutations, this should never happen now.
+        (WebCore::Node::registerTransientMutationObserver):
+        (WebCore::Node::unregisterTransientMutationObserver): Ditto.
+        (WebCore::Node::notifyMutationObserversNodeWillDetach):
+        * dom/Node.h:
+        * dom/NodeRareData.cpp:
+        * dom/NodeRareData.h:
+        (WebCore::NodeMutationObserverData): Merged into NodeRareData.
+        (WebCore::NodeRareData::mutationObserverData): Deleted.
+        (WebCore::NodeRareData::ensureMutationObserverData): Deleted.
+        (WebCore::NodeRareData::mutationObserverRegistry): Added.
+        (WebCore::NodeRareData::mutationObserverRegistryIfExists): Added.
+        (WebCore::NodeRareData::transientMutationObserverRegistry): Added.
+        (WebCore::NodeRareData::useTypes const):
+
 2020-09-16  Sam Weinig  <wei...@apple.com>
 
         Remove runtime setting for enabling/disabling CSS shadow parts

Modified: trunk/Source/WebCore/dom/MutationObserver.cpp (267174 => 267175)


--- trunk/Source/WebCore/dom/MutationObserver.cpp	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/MutationObserver.cpp	2020-09-17 01:53:21 UTC (rev 267175)
@@ -120,21 +120,26 @@
 {
     m_pendingTargets.clear();
     m_records.clear();
-    HashSet<MutationObserverRegistration*> registrations(m_registrations);
-    for (auto* registration : registrations)
-        registration->node().unregisterMutationObserver(*registration);
+    auto registrationAndNodeList = WTF::compactMap(m_registrations, [](auto* registration) -> Optional<std::pair<Ref<Node>, Ref<MutationObserverRegistration>>> {
+        auto node = makeRefPtr(registration->node());
+        if (!node)
+            return WTF::nullopt;
+        return { { node.releaseNonNull(), makeRef(*registration) } };
+    });
+    for (auto& registrationAndNode : registrationAndNodeList)
+        registrationAndNode.first->unregisterMutationObserver(registrationAndNode.second.get());
 }
 
 void MutationObserver::observationStarted(MutationObserverRegistration& registration)
 {
-    ASSERT(!m_registrations.contains(&registration));
-    m_registrations.add(&registration);
+    auto result = m_registrations.add(&registration);
+    RELEASE_ASSERT(result.isNewEntry);
 }
 
 void MutationObserver::observationEnded(MutationObserverRegistration& registration)
 {
-    ASSERT(m_registrations.contains(&registration));
-    m_registrations.remove(&registration);
+    auto removed = m_registrations.remove(&registration);
+    RELEASE_ASSERT(removed);
 }
 
 void MutationObserver::enqueueMutationRecord(Ref<MutationRecord>&& mutation)
@@ -186,18 +191,14 @@
 {
     ASSERT(canDeliver());
 
-    // Calling takeTransientRegistrations() can modify m_registrations, so it's necessary
-    // to make a copy of the transient registrations before operating on them.
-    Vector<MutationObserverRegistration*, 1> transientRegistrations;
     Vector<std::unique_ptr<HashSet<GCReachableRef<Node>>>, 1> nodesToKeepAlive;
     HashSet<GCReachableRef<Node>> pendingTargets;
     pendingTargets.swap(m_pendingTargets);
-    for (auto* registration : m_registrations) {
+    auto registrations = WTF::map(m_registrations, [](auto* registration) { return makeRef(*registration); });
+    for (auto& registration : registrations) {
         if (registration->hasTransientRegistrations())
-            transientRegistrations.append(registration);
+            nodesToKeepAlive.append(registration->takeTransientRegistrations());
     }
-    for (auto& registration : transientRegistrations)
-        nodesToKeepAlive.append(registration->takeTransientRegistrations());
 
     if (m_records.isEmpty()) {
         ASSERT(m_pendingTargets.isEmpty());

Modified: trunk/Source/WebCore/dom/MutationObserverRegistration.cpp (267174 => 267175)


--- trunk/Source/WebCore/dom/MutationObserverRegistration.cpp	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/MutationObserverRegistration.cpp	2020-09-17 01:53:21 UTC (rev 267175)
@@ -37,9 +37,14 @@
 
 namespace WebCore {
 
+Ref<MutationObserverRegistration> MutationObserverRegistration::create(MutationObserver& observer, Node& node, MutationObserverOptions options, const HashSet<AtomString>& attributeFilter)
+{
+    return adoptRef(*new MutationObserverRegistration(observer, node, options, attributeFilter));
+}
+    
 MutationObserverRegistration::MutationObserverRegistration(MutationObserver& observer, Node& node, MutationObserverOptions options, const HashSet<AtomString>& attributeFilter)
     : m_observer(observer)
-    , m_node(node)
+    , m_node(makeWeakPtr(node))
     , m_options(options)
     , m_attributeFilter(attributeFilter)
 {
@@ -67,31 +72,21 @@
     node.registerTransientMutationObserver(*this);
     m_observer->setHasTransientRegistration(node.document());
 
-    if (!m_transientRegistrationNodes) {
+    if (!m_transientRegistrationNodes)
         m_transientRegistrationNodes = makeUnique<HashSet<GCReachableRef<Node>>>();
-
-        ASSERT(!m_nodeKeptAlive);
-        m_nodeKeptAlive = &m_node; // Balanced in takeTransientRegistrations.
-    }
     m_transientRegistrationNodes->add(node);
 }
 
 std::unique_ptr<HashSet<GCReachableRef<Node>>> MutationObserverRegistration::takeTransientRegistrations()
 {
-    if (!m_transientRegistrationNodes) {
-        ASSERT(!m_nodeKeptAlive);
+    if (!m_transientRegistrationNodes)
         return nullptr;
-    }
 
-    for (auto& node : *m_transientRegistrationNodes)
+    auto transientNodes = WTFMove(m_transientRegistrationNodes);
+    for (auto& node : *transientNodes)
         node->unregisterTransientMutationObserver(*this);
 
-    auto returnValue = WTFMove(m_transientRegistrationNodes);
-
-    ASSERT(m_nodeKeptAlive);
-    m_nodeKeptAlive = nullptr; // Balanced in observeSubtreeNodeWillDetach.
-
-    return returnValue;
+    return transientNodes;
 }
 
 bool MutationObserverRegistration::shouldReceiveMutationFrom(Node& node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
@@ -100,7 +95,7 @@
     if (!(m_options & type))
         return false;
 
-    if (&m_node != &node && !isSubtree())
+    if (m_node.get() != &node && !isSubtree())
         return false;
 
     if (type != MutationObserver::Attributes || !(m_options & MutationObserver::AttributeFilter))
@@ -114,7 +109,9 @@
 
 void MutationObserverRegistration::addRegistrationNodesToSet(HashSet<Node*>& nodes) const
 {
-    nodes.add(&m_node);
+    ASSERT(m_node.get() || m_transientRegistrationNodes);
+    if (auto* observedNode = m_node.get())
+        nodes.add(observedNode);
     if (!m_transientRegistrationNodes)
         return;
     for (auto& node : *m_transientRegistrationNodes)

Modified: trunk/Source/WebCore/dom/MutationObserverRegistration.h (267174 => 267175)


--- trunk/Source/WebCore/dom/MutationObserverRegistration.h	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/MutationObserverRegistration.h	2020-09-17 01:53:21 UTC (rev 267175)
@@ -33,6 +33,7 @@
 #include "GCReachableRef.h"
 #include "MutationObserver.h"
 #include <wtf/HashSet.h>
+#include <wtf/WeakPtr.h>
 #include <wtf/text/AtomString.h>
 #include <wtf/text/AtomStringHash.h>
 
@@ -40,10 +41,11 @@
 
 class QualifiedName;
 
-class MutationObserverRegistration {
+class MutationObserverRegistration : public RefCounted<MutationObserverRegistration> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    MutationObserverRegistration(MutationObserver&, Node&, MutationObserverOptions, const HashSet<AtomString>& attributeFilter);
+    static Ref<MutationObserverRegistration> create(MutationObserver&, Node&, MutationObserverOptions, const HashSet<AtomString>& attributeFilter);
+
     ~MutationObserverRegistration();
 
     void resetObservation(MutationObserverOptions, const HashSet<AtomString>& attributeFilter);
@@ -55,7 +57,7 @@
     bool isSubtree() const { return m_options & MutationObserver::Subtree; }
 
     MutationObserver& observer() { return m_observer.get(); }
-    Node& node() { return m_node; }
+    Node* node() { return m_node.get(); }
     MutationRecordDeliveryOptions deliveryOptions() const { return m_options & (MutationObserver::AttributeOldValue | MutationObserver::CharacterDataOldValue); }
     MutationObserverOptions mutationTypes() const { return m_options & MutationObserver::AllMutationTypes; }
 
@@ -62,9 +64,10 @@
     void addRegistrationNodesToSet(HashSet<Node*>&) const;
 
 private:
+    MutationObserverRegistration(MutationObserver&, Node&, MutationObserverOptions, const HashSet<AtomString>& attributeFilter);
+
     Ref<MutationObserver> m_observer;
-    Node& m_node;
-    RefPtr<Node> m_nodeKeptAlive;
+    WeakPtr<Node> m_node;
     std::unique_ptr<HashSet<GCReachableRef<Node>>> m_transientRegistrationNodes;
     MutationObserverOptions m_options;
     HashSet<AtomString> m_attributeFilter;

Modified: trunk/Source/WebCore/dom/Node.cpp (267174 => 267175)


--- trunk/Source/WebCore/dom/Node.cpp	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/Node.cpp	2020-09-17 01:53:21 UTC (rev 267175)
@@ -429,8 +429,7 @@
 void Node::clearRareData()
 {
     ASSERT(hasRareData());
-    ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
-
+    ASSERT(rareData()->transientMutationObserverRegistry().isEmpty());
     m_rareDataWithBitfields.setPointer(nullptr);
 }
 
@@ -2035,19 +2034,15 @@
     oldDocument.decrementReferencingNodeCount();
 
     if (hasRareData()) {
-        if (auto* nodeLists = rareData()->nodeLists())
+        auto* rareData = this->rareData();
+        if (auto* nodeLists = rareData->nodeLists())
             nodeLists->adoptDocument(oldDocument, newDocument);
-        if (auto* registry = mutationObserverRegistry()) {
+        if (auto* registry = rareData->mutationObserverRegistryIfExists()) {
             for (auto& registration : *registry)
                 newDocument.addMutationObserverTypes(registration->mutationTypes());
         }
-        if (auto* transientRegistry = transientMutationObserverRegistry()) {
-            for (auto& registration : *transientRegistry)
-                newDocument.addMutationObserverTypes(registration->mutationTypes());
-        }
-    } else {
-        ASSERT(!mutationObserverRegistry());
-        ASSERT(!transientMutationObserverRegistry());
+        for (auto& registration : rareData->transientMutationObserverRegistry())
+            newDocument.addMutationObserverTypes(registration->mutationTypes());
     }
 
     oldDocument.moveNodeIteratorsToNewDocument(*this, newDocument);
@@ -2247,32 +2242,9 @@
     eventTargetDataMap().remove(this);
 }
 
-Vector<std::unique_ptr<MutationObserverRegistration>>* Node::mutationObserverRegistry()
+template<typename Registry> static inline void collectMatchingObserversForMutation(HashMap<Ref<MutationObserver>, MutationRecordDeliveryOptions>& observers, Registry& registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
 {
-    if (!hasRareData())
-        return nullptr;
-    auto* data = ""
-    if (!data)
-        return nullptr;
-    return &data->registry;
-}
-
-HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry()
-{
-    if (!hasRareData())
-        return nullptr;
-    auto* data = ""
-    if (!data)
-        return nullptr;
-    return &data->transientRegistry;
-}
-
-template<typename Registry> static inline void collectMatchingObserversForMutation(HashMap<Ref<MutationObserver>, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
-{
-    if (!registry)
-        return;
-
-    for (auto& registration : *registry) {
+    for (auto& registration : registry) {
         if (registration->shouldReceiveMutationFrom(target, type, attributeName)) {
             auto deliveryOptions = registration->deliveryOptions();
             auto result = observers.add(registration->observer(), deliveryOptions);
@@ -2286,11 +2258,13 @@
 {
     HashMap<Ref<MutationObserver>, MutationRecordDeliveryOptions> result;
     ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
-    collectMatchingObserversForMutation(result, mutationObserverRegistry(), *this, type, attributeName);
-    collectMatchingObserversForMutation(result, transientMutationObserverRegistry(), *this, type, attributeName);
-    for (Node* node = parentNode(); node; node = node->parentNode()) {
-        collectMatchingObserversForMutation(result, node->mutationObserverRegistry(), *this, type, attributeName);
-        collectMatchingObserversForMutation(result, node->transientMutationObserverRegistry(), *this, type, attributeName);
+    for (auto node = makeRefPtr(this); node; node = node->parentNode()) {
+        if (!node->hasRareData())
+            continue;
+        auto* rareData = node->rareData();
+        if (auto* registry = rareData->mutationObserverRegistryIfExists())
+            collectMatchingObserversForMutation(result, *registry, *this, type, attributeName);
+        collectMatchingObserversForMutation(result, rareData->transientMutationObserverRegistry(), *this, type, attributeName);
     }
     return result;
 }
@@ -2297,50 +2271,40 @@
 
 void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomString>& attributeFilter)
 {
-    MutationObserverRegistration* registration = nullptr;
-    auto& registry = ensureRareData().ensureMutationObserverData().registry;
-
-    for (auto& candidateRegistration : registry) {
-        if (&candidateRegistration->observer() == &observer) {
-            registration = candidateRegistration.get();
-            registration->resetObservation(options, attributeFilter);
-        }
+    auto& registry = ensureRareData().mutationObserverRegistry();
+    auto index = registry.findMatching([&observer](auto& registration) { return &registration->observer() == &observer; });
+    if (index != notFound) {
+        auto registration = registry[index].copyRef();
+        registration->resetObservation(options, attributeFilter);
+        document().addMutationObserverTypes(registration->mutationTypes());
+        return;
     }
-
-    if (!registration) {
-        registry.append(makeUnique<MutationObserverRegistration>(observer, *this, options, attributeFilter));
-        registration = registry.last().get();
-    }
-
-    document().addMutationObserverTypes(registration->mutationTypes());
+    auto newRegistration = MutationObserverRegistration::create(observer, *this, options, attributeFilter);
+    document().addMutationObserverTypes(newRegistration->mutationTypes());
+    registry.append(WTFMove(newRegistration));
 }
 
 void Node::unregisterMutationObserver(MutationObserverRegistration& registration)
 {
-    auto* registry = mutationObserverRegistry();
+    ASSERT(hasRareData());
+    auto* registry = rareData()->mutationObserverRegistryIfExists();
     ASSERT(registry);
-    if (!registry)
-        return;
-
-    registry->removeFirstMatching([&registration] (auto& current) {
-        return current.get() == &registration;
+    auto removed = registry->removeFirstMatching([&registration] (auto& current) {
+        return current.ptr() == &registration;
     });
+    RELEASE_ASSERT(removed);
 }
 
 void Node::registerTransientMutationObserver(MutationObserverRegistration& registration)
 {
-    ensureRareData().ensureMutationObserverData().transientRegistry.add(&registration);
+    ensureRareData().transientMutationObserverRegistry().add(registration);
 }
 
 void Node::unregisterTransientMutationObserver(MutationObserverRegistration& registration)
 {
-    auto* transientRegistry = transientMutationObserverRegistry();
-    ASSERT(transientRegistry);
-    if (!transientRegistry)
-        return;
-
-    ASSERT(transientRegistry->contains(&registration));
-    transientRegistry->remove(&registration);
+    ASSERT(hasRareData());
+    bool removed = rareData()->transientMutationObserverRegistry().remove(&registration);
+    RELEASE_ASSERT(removed);
 }
 
 void Node::notifyMutationObserversNodeWillDetach()
@@ -2349,14 +2313,15 @@
         return;
 
     for (Node* node = parentNode(); node; node = node->parentNode()) {
-        if (auto* registry = node->mutationObserverRegistry()) {
+        if (!node->hasRareData())
+            continue;
+        auto* rareData = node->rareData();
+        if (auto* registry = rareData->mutationObserverRegistryIfExists()) {
             for (auto& registration : *registry)
                 registration->observedSubtreeNodeWillDetach(*this);
         }
-        if (auto* transientRegistry = node->transientMutationObserverRegistry()) {
-            for (auto* registration : *transientRegistry)
-                registration->observedSubtreeNodeWillDetach(*this);
-        }
+        for (auto& registration : rareData->transientMutationObserverRegistry())
+            registration->observedSubtreeNodeWillDetach(*this);
     }
 }
 

Modified: trunk/Source/WebCore/dom/Node.h (267174 => 267175)


--- trunk/Source/WebCore/dom/Node.h	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/Node.h	2020-09-17 01:53:21 UTC (rev 267175)
@@ -699,9 +699,6 @@
     void trackForDebugging();
     void materializeRareData();
 
-    Vector<std::unique_ptr<MutationObserverRegistration>>* mutationObserverRegistry();
-    HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
-
     void adjustStyleValidity(Style::Validity, Style::InvalidationMode);
 
     void* opaqueRootSlow() const;

Modified: trunk/Source/WebCore/dom/NodeRareData.cpp (267174 => 267175)


--- trunk/Source/WebCore/dom/NodeRareData.cpp	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/NodeRareData.cpp	2020-09-17 01:53:21 UTC (rev 267175)
@@ -38,7 +38,10 @@
 struct SameSizeAsNodeRareData {
     uint32_t m_tabIndex;
     uint32_t m_childIndexAndIsElementRareDataFlag;
-    void* m_pointer[2];
+    void* m_pointer[3];
+#if CHECK_HASHTABLE_ITERATORS
+    void* m_hashTableIteratorsAndMutex[2];
+#endif
 };
 
 COMPILE_ASSERT(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData), NodeRareDataShouldStaySmall);

Modified: trunk/Source/WebCore/dom/NodeRareData.h (267174 => 267175)


--- trunk/Source/WebCore/dom/NodeRareData.h	2020-09-17 00:23:46 UTC (rev 267174)
+++ trunk/Source/WebCore/dom/NodeRareData.h	2020-09-17 01:53:21 UTC (rev 267175)
@@ -229,15 +229,6 @@
     CollectionCacheMap m_cachedCollections;
 };
 
-class NodeMutationObserverData {
-    WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); WTF_MAKE_FAST_ALLOCATED;
-public:
-    Vector<std::unique_ptr<MutationObserverRegistration>> registry;
-    HashSet<MutationObserverRegistration*> transientRegistry;
-
-    NodeMutationObserverData() { }
-};
-
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(NodeRareData);
 class NodeRareData {
     WTF_MAKE_NONCOPYABLE(NodeRareData);
@@ -284,13 +275,22 @@
         return *m_nodeLists;
     }
 
-    NodeMutationObserverData* mutationObserverData() { return m_mutationObserverData.get(); }
-    NodeMutationObserverData& ensureMutationObserverData()
+    using MutationObserverRegistryVector = Vector<Ref<MutationObserverRegistration>, 4>;
+
+    MutationObserverRegistryVector& mutationObserverRegistry()
     {
-        if (!m_mutationObserverData)
-            m_mutationObserverData = makeUnique<NodeMutationObserverData>();
-        return *m_mutationObserverData;
+        if (!m_mutationObserverRegistry)
+            m_mutationObserverRegistry = makeUnique<MutationObserverRegistryVector>();
+        return *m_mutationObserverRegistry;
     }
+    MutationObserverRegistryVector* mutationObserverRegistryIfExists()
+    {
+        return m_mutationObserverRegistry.get();
+    }
+    HashSet<Ref<MutationObserverRegistration>>& transientMutationObserverRegistry()
+    {
+        return m_transientMutationObserverRegistry;
+    }
 
 #if DUMP_NODE_STATISTICS
     OptionSet<UseType> useTypes() const
@@ -298,7 +298,7 @@
         OptionSet<UseType> result;
         if (m_nodeLists)
             result.add(UseType::NodeList);
-        if (m_mutationObserverData)
+        if (m_mutationObserverRegistry || m_transientMutationObserverRegistry.capacity())
             result.add(UseType::MutationObserver);
         return result;
     }
@@ -313,7 +313,8 @@
     bool m_isElementRareData;
 
     std::unique_ptr<NodeListsNodeData> m_nodeLists;
-    std::unique_ptr<NodeMutationObserverData> m_mutationObserverData;
+    std::unique_ptr<MutationObserverRegistryVector> m_mutationObserverRegistry;
+    HashSet<Ref<MutationObserverRegistration>> m_transientMutationObserverRegistry;
 };
 
 template<> struct NodeListTypeIdentifier<NameNodeList> {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to