Title: [145446] branches/chromium/1410/Source/WebCore

Diff

Modified: branches/chromium/1410/Source/WebCore/WebCore.exp.in (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/WebCore.exp.in	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/WebCore.exp.in	2013-03-12 01:05:41 UTC (rev 145446)
@@ -1401,7 +1401,6 @@
 __ZN7WebCore4Node12insertBeforeEN3WTF10PassRefPtrIS0_EEPS0_Rib
 __ZNK7WebCore4Node13ownerDocumentEv
 __ZNK7WebCore4Node14isDescendantOfEPKS0_
-__ZNK7WebCore4Node11isTreeScopeEv
 __ZNK7WebCore4Node18getSubresourceURLsERN3WTF11ListHashSetINS_4KURLELm256ENS_8KURLHashEEE
 __ZNK7WebCore4Node31numberOfScopedHTMLStyleChildrenEv
 __ZNK7WebCore4Node9nodeIndexEv

Modified: branches/chromium/1410/Source/WebCore/dom/Document.cpp (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/Document.cpp	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/Document.cpp	2013-03-12 01:05:41 UTC (rev 145446)
@@ -409,7 +409,6 @@
 Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
     : ContainerNode(0, CreateDocument)
     , TreeScope(this)
-    , m_guardRefCount(0)
     , m_styleResolverThrowawayTimer(this, &Document::styleResolverThrowawayTimerFired)
     , m_lastStyleResolverAccessTime(0)
     , m_activeParserCount(0)
@@ -481,8 +480,6 @@
     , m_templateDocumentHost(0)
 #endif
 {
-    setTreeScope(this);
-
     m_printing = false;
     m_paginatedForScreen = false;
 
@@ -582,7 +579,7 @@
     ASSERT(m_ranges.isEmpty());
     ASSERT(!m_styleRecalcTimer.isActive());
     ASSERT(!m_parentTreeScope);
-    ASSERT(!m_guardRefCount);
+    ASSERT(!hasGuardRefCount());
 
 #if ENABLE(TEMPLATE_ELEMENT)
     if (m_templateDocument)
@@ -649,60 +646,40 @@
     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
 }
 
-void Document::removedLastRef()
+void Document::dispose()
 {
-    ASSERT(!m_deletionHasBegun);
-    if (m_guardRefCount) {
-        // If removing a child removes the last self-only ref, we don't
-        // want the scope to be destructed until after
-        // removeDetachedChildren returns, so we guard ourselves with an
-        // extra self-only ref.
-        guardRef();
-
-        // We must make sure not to be retaining any of our children through
-        // these extra pointers or we will create a reference cycle.
-        m_docType = 0;
-        m_focusedNode = 0;
-        m_hoverNode = 0;
-        m_activeElement = 0;
-        m_titleElement = 0;
-        m_documentElement = 0;
-        m_contextFeatures = ContextFeatures::defaultSwitch();
-        m_userActionElements.documentDidRemoveLastRef();
+    // We must make sure not to be retaining any of our children through
+    // these extra pointers or we will create a reference cycle.
+    m_docType = 0;
+    m_focusedNode = 0;
+    m_hoverNode = 0;
+    m_activeElement = 0;
+    m_titleElement = 0;
+    m_documentElement = 0;
+    m_contextFeatures = ContextFeatures::defaultSwitch();
+    m_userActionElements.documentDidRemoveLastRef();
 #if ENABLE(FULLSCREEN_API)
-        m_fullScreenElement = 0;
-        m_fullScreenElementStack.clear();
+    m_fullScreenElement = 0;
+    m_fullScreenElementStack.clear();
 #endif
 
-        detachParser();
+    detachParser();
 
-        // removeDetachedChildren() doesn't always unregister IDs,
-        // so tear down scope information upfront to avoid having stale references in the map.
-        destroyTreeScopeData();
-        removeDetachedChildren();
+    // removeDetachedChildren() doesn't always unregister IDs,
+    // so tear down scope information upfront to avoid having stale references in the map.
+    destroyTreeScopeData();
+    removeDetachedChildren();
 
-        m_markers->detach();
+    m_markers->detach();
 
-        m_cssCanvasElements.clear();
+    m_cssCanvasElements.clear();
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)
-        // FIXME: consider using ActiveDOMObject.
-        if (m_scriptedAnimationController)
-            m_scriptedAnimationController->clearDocumentPointer();
-        m_scriptedAnimationController.clear();
+    // FIXME: consider using ActiveDOMObject.
+    if (m_scriptedAnimationController)
+        m_scriptedAnimationController->clearDocumentPointer();
+    m_scriptedAnimationController.clear();
 #endif
-
-#ifndef NDEBUG
-        m_inRemovedLastRefFunction = false;
-#endif
-
-        guardDeref();
-    } else {
-#ifndef NDEBUG 
-        m_deletionHasBegun = true; 
-#endif 
-        delete this;
-    }
 }
 
 Element* Document::getElementById(const AtomicString& id) const

Modified: branches/chromium/1410/Source/WebCore/dom/Document.h (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/Document.h	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/Document.h	2013-03-12 01:05:41 UTC (rev 145446)
@@ -228,29 +228,6 @@
     using ContainerNode::ref;
     using ContainerNode::deref;
 
-    // Nodes belonging to this document hold guard references -
-    // these are enough to keep the document from being destroyed, but
-    // not enough to keep it from removing its children. This allows a
-    // node that outlives its document to still have a valid document
-    // pointer without introducing reference cycles.
-    void guardRef()
-    {
-        ASSERT(!m_deletionHasBegun);
-        ++m_guardRefCount;
-    }
-
-    void guardDeref()
-    {
-        ASSERT(!m_deletionHasBegun);
-        --m_guardRefCount;
-        if (!m_guardRefCount && !refCount()) {
-#ifndef NDEBUG
-            m_deletionHasBegun = true;
-#endif
-            delete this;
-        }
-    }
-
     Element* getElementById(const AtomicString& id) const;
 
     virtual bool canContainRangeEndPoint() const { return true; }
@@ -1217,8 +1194,8 @@
     friend class Node;
     friend class IgnoreDestructiveWriteCountIncrementer;
 
-    void removedLastRef();
-    
+    virtual void dispose() OVERRIDE;
+
     void detachParser();
 
     typedef void (*ArgumentsCallback)(const String& keyString, const String& valueString, Document*, void* data);
@@ -1286,8 +1263,6 @@
     void addListenerType(ListenerType listenerType) { m_listenerTypes |= listenerType; }
     void addMutationEventListenerTypeIfEnabled(ListenerType);
 
-    int m_guardRefCount;
-
     void styleResolverThrowawayTimerFired(Timer<Document>*);
     Timer<Document> m_styleResolverThrowawayTimer;
     double m_lastStyleResolverAccessTime;
@@ -1603,10 +1578,9 @@
     , m_previous(0)
     , m_next(0)
 {
-    if (document)
-        document->guardRef();
-    else
+    if (!m_treeScope)
         m_treeScope = TreeScope::noDocumentInstance();
+    m_treeScope->guardRef();
 
 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
     trackForDebugging();

Modified: branches/chromium/1410/Source/WebCore/dom/DocumentFragment.cpp (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/DocumentFragment.cpp	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/DocumentFragment.cpp	2013-03-12 01:05:41 UTC (rev 145446)
@@ -34,11 +34,11 @@
 DocumentFragment::DocumentFragment(Document* document, ConstructionType constructionType)
     : ContainerNode(document, constructionType)
 {
-    ASSERT(document);
 }
 
 PassRefPtr<DocumentFragment> DocumentFragment::create(Document* document)
 {
+    ASSERT(document);
     return adoptRef(new DocumentFragment(document, Node::CreateDocumentFragment));
 }
 

Modified: branches/chromium/1410/Source/WebCore/dom/Node.cpp (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/Node.cpp	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/Node.cpp	2013-03-12 01:05:41 UTC (rev 145446)
@@ -437,8 +437,7 @@
     if (m_next)
         m_next->setPreviousSibling(0);
 
-    if (doc)
-        doc->guardDeref();
+    m_treeScope->guardDeref();
 
     InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
 }
@@ -887,11 +886,6 @@
     return true;
 }
 
-bool Node::isTreeScope() const
-{
-    return treeScope()->rootNode() == this;
-}
-
 bool Node::isKeyboardFocusable(KeyboardEvent*) const
 {
     return isFocusable() && tabIndex() >= 0;
@@ -2561,6 +2555,31 @@
 }
 #endif
 
+// This is here for inlining
+inline void TreeScope::removedLastRefToScope()
+{
+    ASSERT(!deletionHasBegun());
+    if (m_guardRefCount) {
+        // If removing a child removes the last self-only ref, we don't
+        // want the scope to be destructed until after
+        // removeDetachedChildren returns, so we guard ourselves with an
+        // extra self-only ref.
+        guardRef();
+        dispose();
+#ifndef NDEBUG
+        // We need to do this right now since guardDeref() can delete this.
+        rootNode()->m_inRemovedLastRefFunction = false;
+#endif
+        guardDeref();
+    } else {
+#ifndef NDEBUG
+        rootNode()->m_inRemovedLastRefFunction = false;
+        beginDeletion();
+#endif
+        delete this;
+    }
+}
+
 // It's important not to inline removedLastRef, because we don't want to inline the code to
 // delete a Node at each deref call site.
 void Node::removedLastRef()
@@ -2568,10 +2587,11 @@
     // An explicit check for Document here is better than a virtual function since it is
     // faster for non-Document nodes, and because the call to removedLastRef that is inlined
     // at all deref call sites is smaller if it's a non-virtual function.
-    if (isDocumentNode()) {
-        static_cast<Document*>(this)->removedLastRef();
+    if (isTreeScope()) {
+        treeScope()->removedLastRefToScope();
         return;
     }
+
 #ifndef NDEBUG
     m_deletionHasBegun = true;
 #endif

Modified: branches/chromium/1410/Source/WebCore/dom/Node.h (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/Node.h	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/Node.h	2013-03-12 01:05:41 UTC (rev 145446)
@@ -248,7 +248,7 @@
     virtual bool isInsertionPointNode() const { return false; }
 
     bool isDocumentNode() const;
-    bool isTreeScope() const;
+    bool isTreeScope() const { return treeScope()->rootNode() == this; }
     bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
     bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
     bool isInsertionPoint() const { return getFlag(NeedsShadowTreeWalkerFlag) && isInsertionPointNode(); }

Modified: branches/chromium/1410/Source/WebCore/dom/ShadowRoot.cpp (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/ShadowRoot.cpp	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/ShadowRoot.cpp	2013-03-12 01:05:41 UTC (rev 145446)
@@ -52,7 +52,7 @@
 };
 
 ShadowRoot::ShadowRoot(Document* document, ShadowRootType type)
-    : DocumentFragment(document, CreateShadowRoot)
+    : DocumentFragment(0, CreateShadowRoot)
     , TreeScope(this, document)
     , m_prev(0)
     , m_next(0)
@@ -63,7 +63,6 @@
     , m_registeredWithParentShadowRoot(false)
 {
     ASSERT(document);
-    setTreeScope(this);
 
 #if PLATFORM(CHROMIUM)
     if (type == ShadowRoot::AuthorShadowRoot) {
@@ -89,6 +88,11 @@
         clearRareData();
 }
 
+void ShadowRoot::dispose()
+{
+    removeDetachedChildren();
+}
+
 PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec)
 {
     ec = DATA_CLONE_ERR;

Modified: branches/chromium/1410/Source/WebCore/dom/ShadowRoot.h (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/ShadowRoot.h	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/ShadowRoot.h	2013-03-12 01:05:41 UTC (rev 145446)
@@ -100,6 +100,7 @@
     ShadowRoot(Document*, ShadowRootType);
     virtual ~ShadowRoot();
 
+    virtual void dispose() OVERRIDE;
     virtual bool childTypeAllowed(NodeType) const OVERRIDE;
     virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
 

Modified: branches/chromium/1410/Source/WebCore/dom/TreeScope.cpp (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/TreeScope.cpp	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/TreeScope.cpp	2013-03-12 01:05:41 UTC (rev 145446)
@@ -59,6 +59,7 @@
 struct SameSizeAsTreeScope {
     virtual ~SameSizeAsTreeScope();
     void* pointers[8];
+    int ints[1];
 };
 
 COMPILE_ASSERT(sizeof(TreeScope) == sizeof(SameSizeAsTreeScope), treescope_should_stay_small);
@@ -69,35 +70,47 @@
     : m_rootNode(rootNode)
     , m_documentScope(document)
     , m_parentTreeScope(document)
+    , m_guardRefCount(0)
     , m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
 {
     ASSERT(rootNode);
     ASSERT(document);
     ASSERT(rootNode != document);
+    m_parentTreeScope->guardRef();
+    m_rootNode->setTreeScope(this);
 }
 
 TreeScope::TreeScope(Document* document)
     : m_rootNode(document)
     , m_documentScope(document)
     , m_parentTreeScope(0)
+    , m_guardRefCount(0)
     , m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
 {
     ASSERT(document);
+    m_rootNode->setTreeScope(this);
 }
 
 TreeScope::TreeScope()
     : m_rootNode(0)
     , m_documentScope(0)
     , m_parentTreeScope(0)
+    , m_guardRefCount(0)
 {
 }
 
 TreeScope::~TreeScope()
 {
+    ASSERT(!m_guardRefCount);
+    m_rootNode->setTreeScope(noDocumentInstance());
+
     if (m_selection) {
         m_selection->clearTreeScope();
         m_selection = 0;
     }
+
+    if (m_parentTreeScope)
+        m_parentTreeScope->guardDeref();
 }
 
 void TreeScope::destroyTreeScopeData()
@@ -120,6 +133,9 @@
     // Every scope other than document needs a parent scope.
     ASSERT(newParentScope);
 
+    newParentScope->guardRef();
+    if (m_parentTreeScope)
+        m_parentTreeScope->guardDeref();
     m_parentTreeScope = newParentScope;
     setDocumentScope(newParentScope->documentScope());
 }
@@ -415,4 +431,24 @@
     return treeScopesA[indexA] == treeScopesB[indexB] ? treeScopesA[indexA] : 0;
 }
 
+#ifndef NDEBUG
+bool TreeScope::deletionHasBegun()
+{
+    return rootNode() && rootNode()->m_deletionHasBegun;
+}
+
+void TreeScope::beginDeletion()
+{
+    ASSERT(this != noDocumentInstance());
+    rootNode()->m_deletionHasBegun = true;
+}
+#endif
+
+int TreeScope::refCount() const
+{
+    if (Node* root = rootNode())
+        return root->refCount();
+    return 0;
+}
+
 } // namespace WebCore

Modified: branches/chromium/1410/Source/WebCore/dom/TreeScope.h (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/TreeScope.h	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/TreeScope.h	2013-03-12 01:05:41 UTC (rev 145446)
@@ -92,7 +92,7 @@
     // Used by the basic DOM mutation methods (e.g., appendChild()).
     void adoptIfNeeded(Node*);
 
-    ContainerNode* rootNode() const { return m_rootNode; }
+    Node* rootNode() const { return m_rootNode; }
 
     IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
 
@@ -104,6 +104,29 @@
         return &instance;
     }
 
+    // Nodes belonging to this scope hold guard references -
+    // these are enough to keep the scope from being destroyed, but
+    // not enough to keep it from removing its children. This allows a
+    // node that outlives its scope to still have a valid document
+    // pointer without introducing reference cycles.
+    void guardRef()
+    {
+        ASSERT(!deletionHasBegun());
+        ++m_guardRefCount;
+    }
+
+    void guardDeref()
+    {
+        ASSERT(!deletionHasBegun());
+        --m_guardRefCount;
+        if (!m_guardRefCount && !refCount() && this != noDocumentInstance()) {
+            beginDeletion();
+            delete this;
+        }
+    }
+
+    void removedLastRefToScope();
+
 protected:
     TreeScope(ContainerNode*, Document*);
     TreeScope(Document*);
@@ -118,12 +141,26 @@
         m_documentScope = document;
     }
 
+    bool hasGuardRefCount() const { return m_guardRefCount; }
+
 private:
     TreeScope();
 
-    ContainerNode* m_rootNode;
+    virtual void dispose() { }
+
+    int refCount() const;
+#ifndef NDEBUG
+    bool deletionHasBegun();
+    void beginDeletion();
+#else
+    bool deletionHasBegun() { return false; }
+    void beginDeletion() { }
+#endif
+
+    Node* m_rootNode;
     Document* m_documentScope;
     TreeScope* m_parentTreeScope;
+    int m_guardRefCount;
 
     OwnPtr<DocumentOrderedMap> m_elementsById;
     OwnPtr<DocumentOrderedMap> m_imageMapsByName;

Modified: branches/chromium/1410/Source/WebCore/dom/TreeScopeAdopter.cpp (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/TreeScopeAdopter.cpp	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/TreeScopeAdopter.cpp	2013-03-12 01:05:41 UTC (rev 145446)
@@ -40,6 +40,8 @@
 {
     ASSERT(needsScopeChange());
 
+    m_oldScope->guardRef();
+
     // If an element is moved from a document and then eventually back again the collection cache for
     // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
     // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
@@ -51,7 +53,7 @@
         oldDocument->incDOMTreeVersion();
 
     for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
-        node->setTreeScope(m_newScope);
+        updateTreeScope(node);
 
         if (willMoveToNewDocument)
             moveNodeToNewDocument(node, oldDocument, newDocument);
@@ -76,6 +78,8 @@
                 moveTreeToNewDocument(shadow, oldDocument, newDocument);
         }
     }
+
+    m_oldScope->guardDeref();
 }
 
 void TreeScopeAdopter::moveTreeToNewDocument(Node* root, Document* oldDocument, Document* newDocument) const
@@ -99,6 +103,15 @@
 }
 #endif
 
+inline void TreeScopeAdopter::updateTreeScope(Node* node) const
+{
+    ASSERT(!node->isTreeScope());
+    ASSERT(node->treeScope() == m_oldScope);
+    m_newScope->guardRef();
+    m_oldScope->guardDeref();
+    node->setTreeScope(m_newScope);
+}
+
 inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDocument, Document* newDocument) const
 {
     ASSERT(!node->inDocument() || oldDocument != newDocument);
@@ -109,7 +122,6 @@
             rareData->nodeLists()->adoptDocument(oldDocument, newDocument);
     }
 
-    newDocument->guardRef();
     if (oldDocument)
         oldDocument->moveNodeIteratorsToNewDocument(node, newDocument);
 
@@ -123,9 +135,6 @@
 
     node->didMoveToNewDocument(oldDocument);
     ASSERT(didMoveToNewDocumentWasCalled);
-    
-    if (oldDocument)
-        oldDocument->guardDeref();
 }
 
 }

Modified: branches/chromium/1410/Source/WebCore/dom/TreeScopeAdopter.h (145445 => 145446)


--- branches/chromium/1410/Source/WebCore/dom/TreeScopeAdopter.h	2013-03-12 00:53:06 UTC (rev 145445)
+++ branches/chromium/1410/Source/WebCore/dom/TreeScopeAdopter.h	2013-03-12 01:05:41 UTC (rev 145446)
@@ -45,6 +45,7 @@
 #endif
 
 private:
+    void updateTreeScope(Node*) const;
     void moveTreeToNewScope(Node*) const;
     void moveTreeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
     void moveNodeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to