Changeset 143940 in webkit
- Timestamp:
- Feb 25, 2013 10:02:42 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r143939 r143940 1 2013-02-25 Dimitri Glazkov <dglazkov@chromium.org> 2 3 Revert r143840 because it caused flaky crashes. 4 https://bugs.webkit.org/show_bug.cgi?id=110766 5 1 6 2013-02-25 Alexey Proskuryakov <ap@apple.com> 2 7 -
trunk/Source/WebCore/WebCore.exp.in
r143840 r143940 1414 1414 __ZNK7WebCore4Node13ownerDocumentEv 1415 1415 __ZNK7WebCore4Node14isDescendantOfEPKS0_ 1416 __ZNK7WebCore4Node11isTreeScopeEv 1416 1417 __ZNK7WebCore4Node18getSubresourceURLsERN3WTF11ListHashSetINS_4KURLELm256ENS_8KURLHashEEE 1417 1418 __ZNK7WebCore4Node31numberOfScopedHTMLStyleChildrenEv -
trunk/Source/WebCore/dom/Document.cpp
r143926 r143940 418 418 : ContainerNode(0, CreateDocument) 419 419 , TreeScope(this) 420 , m_guardRefCount(0) 420 421 , m_styleResolverThrowawayTimer(this, &Document::styleResolverThrowawayTimerFired) 421 422 , m_lastStyleResolverAccessTime(0) … … 489 490 #endif 490 491 { 492 setTreeScope(this); 493 491 494 m_printing = false; 492 495 m_paginatedForScreen = false; … … 588 591 ASSERT(!m_styleRecalcTimer.isActive()); 589 592 ASSERT(!m_parentTreeScope); 590 ASSERT(! hasGuardRefCount());593 ASSERT(!m_guardRefCount); 591 594 592 595 #if ENABLE(TEMPLATE_ELEMENT) … … 655 658 } 656 659 657 void Document::dispose() 658 { 659 // We must make sure not to be retaining any of our children through 660 // these extra pointers or we will create a reference cycle. 661 m_docType = 0; 662 m_focusedNode = 0; 663 m_hoverNode = 0; 664 m_activeElement = 0; 665 m_titleElement = 0; 666 m_documentElement = 0; 667 m_contextFeatures = ContextFeatures::defaultSwitch(); 668 m_userActionElements.documentDidRemoveLastRef(); 660 void Document::removedLastRef() 661 { 662 ASSERT(!m_deletionHasBegun); 663 if (m_guardRefCount) { 664 // If removing a child removes the last self-only ref, we don't 665 // want the scope to be destructed until after 666 // removeDetachedChildren returns, so we guard ourselves with an 667 // extra self-only ref. 668 guardRef(); 669 670 // We must make sure not to be retaining any of our children through 671 // these extra pointers or we will create a reference cycle. 672 m_docType = 0; 673 m_focusedNode = 0; 674 m_hoverNode = 0; 675 m_activeElement = 0; 676 m_titleElement = 0; 677 m_documentElement = 0; 678 m_contextFeatures = ContextFeatures::defaultSwitch(); 679 m_userActionElements.documentDidRemoveLastRef(); 669 680 #if ENABLE(FULLSCREEN_API) 670 m_fullScreenElement = 0;671 m_fullScreenElementStack.clear();672 #endif 673 674 detachParser();681 m_fullScreenElement = 0; 682 m_fullScreenElementStack.clear(); 683 #endif 684 685 detachParser(); 675 686 676 687 #if ENABLE(CUSTOM_ELEMENTS) … … 678 689 #endif 679 690 680 // removeDetachedChildren() doesn't always unregister IDs,681 // so tear down scope information upfront to avoid having stale references in the map.682 destroyTreeScopeData();683 removeDetachedChildren();684 685 m_markers->detach();686 687 m_cssCanvasElements.clear();691 // removeDetachedChildren() doesn't always unregister IDs, 692 // so tear down scope information upfront to avoid having stale references in the map. 693 destroyTreeScopeData(); 694 removeDetachedChildren(); 695 696 m_markers->detach(); 697 698 m_cssCanvasElements.clear(); 688 699 689 700 #if ENABLE(REQUEST_ANIMATION_FRAME) 690 // FIXME: consider using ActiveDOMObject. 691 if (m_scriptedAnimationController) 692 m_scriptedAnimationController->clearDocumentPointer(); 693 m_scriptedAnimationController.clear(); 694 #endif 701 // FIXME: consider using ActiveDOMObject. 702 if (m_scriptedAnimationController) 703 m_scriptedAnimationController->clearDocumentPointer(); 704 m_scriptedAnimationController.clear(); 705 #endif 706 707 #ifndef NDEBUG 708 m_inRemovedLastRefFunction = false; 709 #endif 710 711 guardDeref(); 712 } else { 713 #ifndef NDEBUG 714 m_deletionHasBegun = true; 715 #endif 716 delete this; 717 } 695 718 } 696 719 -
trunk/Source/WebCore/dom/Document.h
r143865 r143940 232 232 using ContainerNode::deref; 233 233 234 // Nodes belonging to this document hold guard references - 235 // these are enough to keep the document from being destroyed, but 236 // not enough to keep it from removing its children. This allows a 237 // node that outlives its document to still have a valid document 238 // pointer without introducing reference cycles. 239 void guardRef() 240 { 241 ASSERT(!m_deletionHasBegun); 242 ++m_guardRefCount; 243 } 244 245 void guardDeref() 246 { 247 ASSERT(!m_deletionHasBegun); 248 --m_guardRefCount; 249 if (!m_guardRefCount && !refCount()) { 250 #ifndef NDEBUG 251 m_deletionHasBegun = true; 252 #endif 253 delete this; 254 } 255 } 256 234 257 Element* getElementById(const AtomicString& id) const; 235 258 … … 1203 1226 friend class IgnoreDestructiveWriteCountIncrementer; 1204 1227 1205 v irtual void dispose() OVERRIDE;1206 1228 void removedLastRef(); 1229 1207 1230 void detachParser(); 1208 1231 … … 1271 1294 void addListenerType(ListenerType listenerType) { m_listenerTypes |= listenerType; } 1272 1295 void addMutationEventListenerTypeIfEnabled(ListenerType); 1296 1297 int m_guardRefCount; 1273 1298 1274 1299 void styleResolverThrowawayTimerFired(Timer<Document>*); … … 1591 1616 , m_next(0) 1592 1617 { 1593 if (!m_treeScope) 1618 if (document) 1619 document->guardRef(); 1620 else 1594 1621 m_treeScope = TreeScope::noDocumentInstance(); 1595 m_treeScope->guardRef();1596 1622 1597 1623 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS) -
trunk/Source/WebCore/dom/DocumentFragment.cpp
r143840 r143940 35 35 : ContainerNode(document, constructionType) 36 36 { 37 ASSERT(document); 37 38 } 38 39 39 40 PassRefPtr<DocumentFragment> DocumentFragment::create(Document* document) 40 41 { 41 ASSERT(document);42 42 return adoptRef(new DocumentFragment(document, Node::CreateDocumentFragment)); 43 43 } -
trunk/Source/WebCore/dom/Node.cpp
r143840 r143940 443 443 m_next->setPreviousSibling(0); 444 444 445 m_treeScope->guardDeref(); 445 if (doc) 446 doc->guardDeref(); 446 447 447 448 InspectorCounters::decrementCounter(InspectorCounters::NodeCounter); … … 890 891 891 892 return true; 893 } 894 895 bool Node::isTreeScope() const 896 { 897 return treeScope()->rootNode() == this; 892 898 } 893 899 … … 2556 2562 #endif 2557 2563 2558 // This is here for inlining2559 inline void TreeScope::removedLastRefToScope()2560 {2561 ASSERT(!deletionHasBegun());2562 if (m_guardRefCount) {2563 // If removing a child removes the last self-only ref, we don't2564 // want the scope to be destructed until after2565 // removeDetachedChildren returns, so we guard ourselves with an2566 // extra self-only ref.2567 guardRef();2568 dispose();2569 #ifndef NDEBUG2570 // We need to do this right now since guardDeref() can delete this.2571 rootNode()->m_inRemovedLastRefFunction = false;2572 #endif2573 guardDeref();2574 } else {2575 #ifndef NDEBUG2576 rootNode()->m_inRemovedLastRefFunction = false;2577 beginDeletion();2578 #endif2579 delete this;2580 }2581 }2582 2583 2564 // It's important not to inline removedLastRef, because we don't want to inline the code to 2584 2565 // delete a Node at each deref call site. … … 2588 2569 // faster for non-Document nodes, and because the call to removedLastRef that is inlined 2589 2570 // at all deref call sites is smaller if it's a non-virtual function. 2590 if (is TreeScope()) {2591 treeScope()->removedLastRefToScope();2571 if (isDocumentNode()) { 2572 static_cast<Document*>(this)->removedLastRef(); 2592 2573 return; 2593 2574 } 2594 2595 2575 #ifndef NDEBUG 2596 2576 m_deletionHasBegun = true; -
trunk/Source/WebCore/dom/Node.h
r143840 r143940 249 249 250 250 bool isDocumentNode() const; 251 bool isTreeScope() const { return treeScope()->rootNode() == this; }251 bool isTreeScope() const; 252 252 bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); } 253 253 bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); } -
trunk/Source/WebCore/dom/ShadowRoot.cpp
r143840 r143940 53 53 54 54 ShadowRoot::ShadowRoot(Document* document, ShadowRootType type) 55 : DocumentFragment( 0, CreateShadowRoot)55 : DocumentFragment(document, CreateShadowRoot) 56 56 , TreeScope(this, document) 57 57 , m_prev(0) … … 64 64 { 65 65 ASSERT(document); 66 setTreeScope(this); 66 67 67 68 #if PLATFORM(CHROMIUM) … … 87 88 if (hasRareData()) 88 89 clearRareData(); 89 }90 91 void ShadowRoot::dispose()92 {93 removeDetachedChildren();94 90 } 95 91 -
trunk/Source/WebCore/dom/ShadowRoot.h
r143840 r143940 101 101 virtual ~ShadowRoot(); 102 102 103 virtual void dispose() OVERRIDE;104 103 virtual bool childTypeAllowed(NodeType) const OVERRIDE; 105 104 virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE; -
trunk/Source/WebCore/dom/TreeScope.cpp
r143840 r143940 60 60 virtual ~SameSizeAsTreeScope(); 61 61 void* pointers[8]; 62 int ints[1];63 62 }; 64 63 … … 71 70 , m_documentScope(document) 72 71 , m_parentTreeScope(document) 73 , m_guardRefCount(0)74 72 , m_idTargetObserverRegistry(IdTargetObserverRegistry::create()) 75 73 { … … 77 75 ASSERT(document); 78 76 ASSERT(rootNode != document); 79 m_parentTreeScope->guardRef();80 m_rootNode->setTreeScope(this);81 77 } 82 78 … … 85 81 , m_documentScope(document) 86 82 , m_parentTreeScope(0) 87 , m_guardRefCount(0)88 83 , m_idTargetObserverRegistry(IdTargetObserverRegistry::create()) 89 84 { 90 85 ASSERT(document); 91 m_rootNode->setTreeScope(this);92 86 } 93 87 … … 96 90 , m_documentScope(0) 97 91 , m_parentTreeScope(0) 98 , m_guardRefCount(0)99 92 { 100 93 } … … 102 95 TreeScope::~TreeScope() 103 96 { 104 ASSERT(!m_guardRefCount);105 m_rootNode->setTreeScope(noDocumentInstance());106 107 97 if (m_selection) { 108 98 m_selection->clearTreeScope(); 109 99 m_selection = 0; 110 100 } 111 112 if (m_parentTreeScope)113 m_parentTreeScope->guardDeref();114 101 } 115 102 … … 134 121 ASSERT(newParentScope); 135 122 136 newParentScope->guardRef();137 if (m_parentTreeScope)138 m_parentTreeScope->guardDeref();139 123 m_parentTreeScope = newParentScope; 140 124 setDocumentScope(newParentScope->documentScope()); … … 432 416 } 433 417 434 #ifndef NDEBUG435 bool TreeScope::deletionHasBegun()436 {437 return rootNode() && rootNode()->m_deletionHasBegun;438 }439 440 void TreeScope::beginDeletion()441 {442 ASSERT(this != noDocumentInstance());443 rootNode()->m_deletionHasBegun = true;444 }445 #endif446 447 int TreeScope::refCount() const448 {449 if (Node* root = rootNode())450 return root->refCount();451 return 0;452 }453 454 418 } // namespace WebCore -
trunk/Source/WebCore/dom/TreeScope.h
r143840 r143940 93 93 void adoptIfNeeded(Node*); 94 94 95 Node* rootNode() const { return m_rootNode; }95 ContainerNode* rootNode() const { return m_rootNode; } 96 96 97 97 IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); } … … 104 104 return &instance; 105 105 } 106 107 // Nodes belonging to this scope hold guard references -108 // these are enough to keep the scope from being destroyed, but109 // not enough to keep it from removing its children. This allows a110 // node that outlives its scope to still have a valid document111 // pointer without introducing reference cycles.112 void guardRef()113 {114 ASSERT(!deletionHasBegun());115 ++m_guardRefCount;116 }117 118 void guardDeref()119 {120 ASSERT(!deletionHasBegun());121 --m_guardRefCount;122 if (!m_guardRefCount && !refCount() && this != noDocumentInstance()) {123 beginDeletion();124 delete this;125 }126 }127 128 void removedLastRefToScope();129 106 130 107 protected: … … 142 119 } 143 120 144 bool hasGuardRefCount() const { return m_guardRefCount; }145 146 121 private: 147 122 TreeScope(); 148 123 149 virtual void dispose() { } 150 151 int refCount() const; 152 #ifndef NDEBUG 153 bool deletionHasBegun(); 154 void beginDeletion(); 155 #else 156 bool deletionHasBegun() { return false; } 157 void beginDeletion() { } 158 #endif 159 160 Node* m_rootNode; 124 ContainerNode* m_rootNode; 161 125 Document* m_documentScope; 162 126 TreeScope* m_parentTreeScope; 163 int m_guardRefCount;164 127 165 128 OwnPtr<DocumentOrderedMap> m_elementsById; -
trunk/Source/WebCore/dom/TreeScopeAdopter.cpp
r143840 r143940 41 41 ASSERT(needsScopeChange()); 42 42 43 m_oldScope->guardRef();44 45 43 // If an element is moved from a document and then eventually back again the collection cache for 46 44 // that element may contain stale data as changes made to it will have updated the DOMTreeVersion … … 54 52 55 53 for (Node* node = root; node; node = NodeTraversal::next(node, root)) { 56 updateTreeScope(node);54 node->setTreeScope(m_newScope); 57 55 58 56 if (willMoveToNewDocument) … … 79 77 } 80 78 } 81 82 m_oldScope->guardDeref();83 79 } 84 80 … … 104 100 #endif 105 101 106 inline void TreeScopeAdopter::updateTreeScope(Node* node) const107 {108 ASSERT(!node->isTreeScope());109 ASSERT(node->treeScope() == m_oldScope);110 m_newScope->guardRef();111 m_oldScope->guardDeref();112 node->setTreeScope(m_newScope);113 }114 115 102 inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDocument, Document* newDocument) const 116 103 { … … 123 110 } 124 111 112 newDocument->guardRef(); 125 113 if (oldDocument) 126 114 oldDocument->moveNodeIteratorsToNewDocument(node, newDocument); … … 136 124 node->didMoveToNewDocument(oldDocument); 137 125 ASSERT(didMoveToNewDocumentWasCalled); 126 127 if (oldDocument) 128 oldDocument->guardDeref(); 138 129 } 139 130 -
trunk/Source/WebCore/dom/TreeScopeAdopter.h
r143840 r143940 46 46 47 47 private: 48 void updateTreeScope(Node*) const;49 48 void moveTreeToNewScope(Node*) const; 50 49 void moveTreeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
Note: See TracChangeset
for help on using the changeset viewer.