Changeset 217972 in webkit
- Timestamp:
- Jun 9, 2017 1:59:22 AM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r217971 r217972 1 2017-06-08 Ryosuke Niwa <rniwa@webkit.org> 2 3 Move TreeScope::adoptIfNeeded to Node and rename it to setTreeScopeRecursively 4 https://bugs.webkit.org/show_bug.cgi?id=173129 5 6 Reviewed by Antti Koivisto. 7 8 Renamed TreeScope::adoptIfNeeded to setTreeScopeRecursively and moved to Node. 9 10 The old name was really confusing because due to the existence of Document::adoptNode, a DOM API, 11 which removes the adopted node from its parent if there was one before adopting the node. 12 Most confusingly, this function called TreeScope::adoptIfNeeded. 13 14 Also inlined the tree scope check to avoid calling to moveTreeToNewScope when there is nothing to do. 15 16 This patch effectively reverts r104528. 17 18 No new tests. Existing tests cover this. 19 20 * dom/Attr.cpp: 21 (WebCore::Attr::detachFromElementWithValue): 22 (WebCore::Attr::attachToElement): 23 * dom/ContainerNode.cpp: 24 (WebCore::ContainerNode::takeAllChildrenFrom): 25 (WebCore::ContainerNode::insertBefore): 26 (WebCore::ContainerNode::replaceChild): 27 (WebCore::ContainerNode::removeBetween): 28 (WebCore::ContainerNode::replaceAllChildren): 29 (WebCore::ContainerNode::appendChildWithoutPreInsertionValidityCheck): 30 (WebCore::ContainerNode::parserAppendChild): 31 * dom/ContainerNodeAlgorithms.cpp: 32 (WebCore::addChildNodesToDeletionQueue): 33 * dom/Document.cpp: 34 (WebCore::Document::adoptNode): 35 * dom/Element.cpp: 36 (WebCore::Element::ensureAttr): 37 * dom/Node.cpp: 38 (WebCore::DidMoveToNewDocumentAssertionScope): Added. The old assertion wasn't sufficient when 39 HTMLTemplateElement made a recursive call to setTreeScopeRecursively. 40 (WebCore::DidMoveToNewDocumentAssertionScope::DidMoveToNewDocumentAssertionScope): 41 (WebCore::DidMoveToNewDocumentAssertionScope::~DidMoveToNewDocumentAssertionScope): 42 (WebCore::DidMoveToNewDocumentAssertionScope::didRecieveCall): 43 (WebCore::moveNodeToNewDocument): Moved from TreeScope. Calls to incrementReferencingNodeCount 44 and decrementReferencingNodeCount to Node::didMoveToNewDocument. This function is now eliminated 45 in a release build. 46 (WebCore::moveShadowTreeToNewDocument): Moved from TreeScope. 47 (WebCore::Node::moveTreeToNewScope): Ditto. 48 (WebCore::Node::didMoveToNewDocument): See the description for moveNodeToNewDocument above. 49 * dom/Node.h: 50 (WebCore::Node::isParsingChildrenFinished): Moved to avoid having its own protected section. 51 (WebCore::Node::setIsParsingChildrenFinished): Ditto. 52 (WebCore::Node::clearIsParsingChildrenFinished): Ditto. 53 (WebCore::Node::setTreeScopeRecursively): Moved from TreeScope::adoptIfNeeded. 54 * dom/ShadowRoot.cpp: 55 (WebCore::ShadowRoot::~ShadowRoot): 56 * dom/TreeScope.cpp: 57 (WebCore::TreeScope::adoptIfNeeded): Deleted. 58 (WebCore::TreeScope::moveTreeToNewScope): Deleted. 59 (WebCore::TreeScope::ensureDidMoveToNewDocumentWasCalled): Deleted. 60 (WebCore::TreeScope::moveNodeToNewDocument): Deleted. 61 (WebCore::TreeScope::moveShadowTreeToNewDocument): Deleted. 62 * dom/TreeScope.h: 63 * html/HTMLTemplateElement.cpp: 64 (WebCore::HTMLTemplateElement::didMoveToNewDocument): 65 1 66 2017-06-09 Adrien Plazas <aplazas@igalia.com> 2 67 -
trunk/Source/WebCore/dom/Attr.cpp
r217957 r217972 136 136 m_standaloneValue = value; 137 137 m_element = nullptr; 138 document().adoptIfNeeded(*this);138 setTreeScopeRecursively(document()); 139 139 } 140 140 … … 144 144 m_element = &element; 145 145 m_standaloneValue = nullAtom; 146 element.treeScope().adoptIfNeeded(*this);146 setTreeScopeRecursively(element.treeScope()); 147 147 } 148 148 -
trunk/Source/WebCore/dom/ContainerNode.cpp
r217794 r217972 151 151 RELEASE_ASSERT(!child->parentNode() && &child->treeScope() == &treeScope()); 152 152 ASSERT(!ensurePreInsertionValidity(child, nullptr).hasException()); 153 treeScope().adoptIfNeeded(child);153 child->setTreeScopeRecursively(treeScope()); 154 154 parserAppendChild(child); 155 155 } … … 291 291 NoEventDispatchAssertion assertNoEventDispatch; 292 292 293 treeScope().adoptIfNeeded(child);293 child->setTreeScopeRecursively(treeScope()); 294 294 insertBeforeCommon(next, child); 295 295 } … … 467 467 { 468 468 NoEventDispatchAssertion assertNoEventDispatch; 469 treeScope().adoptIfNeeded(child);469 child->setTreeScopeRecursively(treeScope()); 470 470 if (refChild) 471 471 insertBeforeCommon(*refChild, child.get()); … … 588 588 oldChild.setParentNode(nullptr); 589 589 590 document().adoptIfNeeded(oldChild);590 oldChild.setTreeScopeRecursively(document()); 591 591 } 592 592 … … 642 642 643 643 // If node is not null, adopt node into parent's node document. 644 treeScope().adoptIfNeeded(node);644 node->setTreeScopeRecursively(treeScope()); 645 645 646 646 // Remove all parent's children, in tree order. … … 757 757 { 758 758 NoEventDispatchAssertion assertNoEventDispatch; 759 treeScope().adoptIfNeeded(child);759 child->setTreeScopeRecursively(treeScope()); 760 760 appendChildCommon(child); 761 761 } … … 781 781 782 782 appendChildCommon(newChild); 783 treeScope().adoptIfNeeded(newChild);783 newChild.setTreeScopeRecursively(treeScope()); 784 784 } 785 785 -
trunk/Source/WebCore/dom/ContainerNodeAlgorithms.cpp
r217926 r217972 180 180 } else { 181 181 Ref<Node> protect(*node); // removedFromDocument may remove remove all references to this node. 182 container.document().adoptIfNeeded(*node);182 node->setTreeScopeRecursively(container.document()); 183 183 if (node->isInTreeScope()) 184 184 notifyChildNodeRemoved(container, *node); -
trunk/Source/WebCore/dom/Document.cpp
r217864 r217972 992 992 } 993 993 994 adoptIfNeeded(source);994 source.setTreeScopeRecursively(*this); 995 995 996 996 return Ref<Node> { source }; -
trunk/Source/WebCore/dom/Element.cpp
r217957 r217972 3413 3413 if (!attrNode) { 3414 3414 attrNode = Attr::create(*this, name); 3415 treeScope().adoptIfNeeded(*attrNode);3415 attrNode->setTreeScopeRecursively(treeScope()); 3416 3416 attrNodeList.append(attrNode); 3417 3417 } -
trunk/Source/WebCore/dom/Node.cpp
r217926 r217972 1923 1923 } 1924 1924 1925 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS) 1926 class DidMoveToNewDocumentAssertionScope { 1927 public: 1928 DidMoveToNewDocumentAssertionScope(Node& node, Document& oldDocument, Document& newDocument) 1929 : m_node(node) 1930 , m_oldDocument(oldDocument) 1931 , m_newDocument(newDocument) 1932 , m_previousScope(s_scope) 1933 { 1934 s_scope = this; 1935 } 1936 1937 ~DidMoveToNewDocumentAssertionScope() 1938 { 1939 ASSERT_WITH_SECURITY_IMPLICATION(m_called); 1940 s_scope = m_previousScope; 1941 } 1942 1943 static void didRecieveCall(Node& node, Document& oldDocument, Document& newDocument) 1944 { 1945 ASSERT_WITH_SECURITY_IMPLICATION(s_scope); 1946 ASSERT_WITH_SECURITY_IMPLICATION(!s_scope->m_called); 1947 ASSERT_WITH_SECURITY_IMPLICATION(&s_scope->m_node == &node); 1948 ASSERT_WITH_SECURITY_IMPLICATION(&s_scope->m_oldDocument == &oldDocument); 1949 ASSERT_WITH_SECURITY_IMPLICATION(&s_scope->m_newDocument == &newDocument); 1950 s_scope->m_called = true; 1951 } 1952 1953 private: 1954 Node& m_node; 1955 Document& m_oldDocument; 1956 Document& m_newDocument; 1957 bool m_called { false }; 1958 DidMoveToNewDocumentAssertionScope* m_previousScope; 1959 1960 static DidMoveToNewDocumentAssertionScope* s_scope; 1961 }; 1962 1963 DidMoveToNewDocumentAssertionScope* DidMoveToNewDocumentAssertionScope::s_scope = nullptr; 1964 1965 #else 1966 class DidMoveToNewDocumentAssertionScope { 1967 public: 1968 DidMoveToNewDocumentAssertionScope(Node&, Document&, Document&) { } 1969 static void didRecieveCall(Node&, Document&, Document&) { } 1970 }; 1971 #endif 1972 1973 static ALWAYS_INLINE void moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument) 1974 { 1975 ASSERT(!node.isConnected() || &oldDocument != &newDocument); 1976 DidMoveToNewDocumentAssertionScope scope(node, oldDocument, newDocument); 1977 node.didMoveToNewDocument(oldDocument, newDocument); 1978 } 1979 1980 static void moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument) 1981 { 1982 for (Node* node = &shadowRoot; node; node = NodeTraversal::next(*node, &shadowRoot)) { 1983 moveNodeToNewDocument(*node, oldDocument, newDocument); 1984 if (auto* shadow = node->shadowRoot()) 1985 moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument); 1986 } 1987 } 1988 1989 void Node::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newScope) 1990 { 1991 ASSERT(&oldScope != &newScope); 1992 ASSERT_WITH_SECURITY_IMPLICATION(&root.treeScope() == &oldScope); 1993 1994 // If an element is moved from a document and then eventually back again the collection cache for 1995 // that element may contain stale data as changes made to it will have updated the DOMTreeVersion 1996 // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here 1997 // we ensure that the collection cache will be invalidated as needed when the element is moved back. 1998 Document& oldDocument = oldScope.documentScope(); 1999 Document& newDocument = newScope.documentScope(); 2000 bool shouldUpdateDocumentScope = &oldDocument != &newDocument; 2001 if (shouldUpdateDocumentScope) { 2002 oldDocument.incrementReferencingNodeCount(); 2003 oldDocument.incDOMTreeVersion(); 2004 } 2005 2006 for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) { 2007 ASSERT(!node->isTreeScope()); 2008 ASSERT(&node->treeScope() == &oldScope); 2009 node->setTreeScope(newScope); 2010 2011 if (shouldUpdateDocumentScope) 2012 moveNodeToNewDocument(*node, oldDocument, newDocument); 2013 else if (node->hasRareData()) { 2014 if (auto* nodeLists = node->rareData()->nodeLists()) 2015 nodeLists->adoptTreeScope(); 2016 } 2017 2018 if (!is<Element>(*node)) 2019 continue; 2020 Element& element = downcast<Element>(*node); 2021 2022 if (element.hasSyntheticAttrChildNodes()) { 2023 for (auto& attr : element.attrNodeList()) 2024 moveTreeToNewScope(*attr, oldScope, newScope); 2025 } 2026 2027 if (auto* shadow = element.shadowRoot()) { 2028 ASSERT_WITH_SECURITY_IMPLICATION(&shadow->document() == &oldDocument); 2029 shadow->setParentTreeScope(newScope); 2030 if (shouldUpdateDocumentScope) 2031 moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument); 2032 } 2033 } 2034 2035 if (shouldUpdateDocumentScope) 2036 oldDocument.decrementReferencingNodeCount(); 2037 } 2038 1925 2039 void Node::didMoveToNewDocument(Document& oldDocument, Document& newDocument) 1926 2040 { 1927 2041 ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument); 1928 TreeScope::ensureDidMoveToNewDocumentWasCalled(oldDocument); 2042 DidMoveToNewDocumentAssertionScope::didRecieveCall(*this, oldDocument, newDocument); 2043 2044 newDocument.incrementReferencingNodeCount(); 2045 oldDocument.decrementReferencingNodeCount(); 1929 2046 1930 2047 if (hasRareData()) { -
trunk/Source/WebCore/dom/Node.h
r217904 r217972 370 370 return *m_treeScope; 371 371 } 372 void setTreeScopeRecursively(TreeScope&); 372 373 static ptrdiff_t treeScopeMemoryOffset() { return OBJECT_OFFSETOF(Node, m_treeScope); } 373 374 … … 491 492 ScriptExecutionContext* scriptExecutionContext() const final; // Implemented in Document.h 492 493 494 virtual void didMoveToNewDocument(Document& oldDocument, Document& newDocument); 495 493 496 bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override; 494 497 bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override; … … 614 617 void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; } 615 618 void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; } 619 620 bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); } 621 void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); } 622 void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); } 616 623 617 624 enum ConstructionType { … … 632 639 Node(Document&, ConstructionType); 633 640 634 virtual void didMoveToNewDocument(Document& oldDocument, Document& newDocument);635 636 641 virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const { } 637 642 … … 672 677 673 678 void adjustStyleValidity(Style::Validity, Style::InvalidationMode); 674 679 675 680 void* opaqueRootSlow() const; 681 682 static void moveTreeToNewScope(Node&, TreeScope& oldScope, TreeScope& newScope); 676 683 677 684 int m_refCount; … … 687 694 NodeRareDataBase* m_rareData; 688 695 } m_data { nullptr }; 689 690 protected:691 bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }692 void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }693 void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }694 696 }; 695 697 … … 791 793 } 792 794 795 inline void Node::setTreeScopeRecursively(TreeScope& newTreeScope) 796 { 797 ASSERT(!isDocumentNode()); 798 ASSERT(!m_deletionHasBegun); 799 if (m_treeScope != &newTreeScope) 800 moveTreeToNewScope(*this, *m_treeScope, newTreeScope); 801 } 802 793 803 } // namespace WebCore 794 804 -
trunk/Source/WebCore/dom/ShadowRoot.cpp
r217876 r217972 82 82 83 83 // We must remove all of our children first before the TreeScope destructor 84 // runs so we don't go through TreeScope::adoptIfNeededfor each child with a84 // runs so we don't go through Node::setTreeScopeRecursively for each child with a 85 85 // destructed tree scope in each descendant. 86 86 removeDetachedChildren(); -
trunk/Source/WebCore/dom/TreeScope.cpp
r217876 r217972 369 369 } 370 370 371 void TreeScope::adoptIfNeeded(Node& node)372 {373 ASSERT(!node.isDocumentNode());374 ASSERT(!node.m_deletionHasBegun);375 TreeScope& treeScopeOfNode = node.treeScope();376 if (this != &treeScopeOfNode)377 moveTreeToNewScope(node, treeScopeOfNode, *this);378 }379 380 void TreeScope::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newScope)381 {382 ASSERT(&oldScope != &newScope);383 ASSERT_WITH_SECURITY_IMPLICATION(&root.treeScope() == &oldScope);384 385 // If an element is moved from a document and then eventually back again the collection cache for386 // that element may contain stale data as changes made to it will have updated the DOMTreeVersion387 // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here388 // we ensure that the collection cache will be invalidated as needed when the element is moved back.389 Document& oldDocument = oldScope.documentScope();390 Document& newDocument = newScope.documentScope();391 bool willMoveToNewDocument = &oldDocument != &newDocument;392 if (willMoveToNewDocument) {393 oldDocument.incrementReferencingNodeCount();394 oldDocument.incDOMTreeVersion();395 }396 397 for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {398 ASSERT(!node->isTreeScope());399 ASSERT(&node->treeScope() == &oldScope);400 node->setTreeScope(newScope);401 402 if (willMoveToNewDocument)403 moveNodeToNewDocument(*node, oldDocument, newDocument);404 else if (node->hasRareData()) {405 if (auto* nodeLists = node->rareData()->nodeLists())406 nodeLists->adoptTreeScope();407 }408 409 if (!is<Element>(*node))410 continue;411 412 if (node->hasSyntheticAttrChildNodes()) {413 for (auto& attr : downcast<Element>(*node).attrNodeList())414 moveTreeToNewScope(*attr, oldScope, newScope);415 }416 417 if (auto* shadow = node->shadowRoot()) {418 ASSERT_WITH_SECURITY_IMPLICATION(&shadow->document() == &oldDocument);419 shadow->setParentTreeScope(newScope);420 if (willMoveToNewDocument)421 moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument);422 }423 }424 425 if (willMoveToNewDocument)426 oldDocument.decrementReferencingNodeCount();427 }428 429 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)430 static bool didMoveToNewDocumentWasCalled = false;431 static Document* oldDocumentDidMoveToNewDocumentWasCalledWith = nullptr;432 433 void TreeScope::ensureDidMoveToNewDocumentWasCalled(Document& oldDocument)434 {435 ASSERT_WITH_SECURITY_IMPLICATION(!didMoveToNewDocumentWasCalled);436 ASSERT_WITH_SECURITY_IMPLICATION(&oldDocument == oldDocumentDidMoveToNewDocumentWasCalledWith);437 didMoveToNewDocumentWasCalled = true;438 }439 #endif440 441 void TreeScope::moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument)442 {443 ASSERT(!node.isConnected() || &oldDocument != &newDocument);444 445 newDocument.incrementReferencingNodeCount();446 oldDocument.decrementReferencingNodeCount();447 448 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)449 didMoveToNewDocumentWasCalled = false;450 oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument;451 #endif452 453 node.didMoveToNewDocument(oldDocument, newDocument);454 ASSERT_WITH_SECURITY_IMPLICATION(didMoveToNewDocumentWasCalled);455 }456 457 void TreeScope::moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument)458 {459 for (Node* node = &shadowRoot; node; node = NodeTraversal::next(*node, &shadowRoot)) {460 moveNodeToNewDocument(*node, oldDocument, newDocument);461 if (auto* shadow = node->shadowRoot())462 moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument);463 }464 }465 466 371 static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame) 467 372 { -
trunk/Source/WebCore/dom/TreeScope.h
r217876 r217972 97 97 Element* findAnchor(const String& name); 98 98 99 // Used by the basic DOM mutation methods (e.g., appendChild()).100 void adoptIfNeeded(Node&);101 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)102 static void ensureDidMoveToNewDocumentWasCalled(Document& oldDocument);103 #else104 static void ensureDidMoveToNewDocumentWasCalled(Document&) { }105 #endif106 107 99 ContainerNode& rootNode() const { return m_rootNode; } 108 100 … … 123 115 124 116 private: 125 void moveTreeToNewScope(Node&, TreeScope& oldScope, TreeScope& newScope);126 void moveNodeToNewDocument(Node&, Document& oldDocument, Document& newDocument);127 void moveShadowTreeToNewDocument(ShadowRoot&, Document& oldDocument, Document& newDocument);128 117 129 118 ContainerNode& m_rootNode; -
trunk/Source/WebCore/html/HTMLTemplateElement.cpp
r217876 r217972 89 89 return; 90 90 ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument); 91 newDocument.ensureTemplateDocument().adoptIfNeeded(*m_content);91 m_content->setTreeScopeRecursively(newDocument.ensureTemplateDocument()); 92 92 } 93 93
Note: See TracChangeset
for help on using the changeset viewer.