Changeset 138735 in webkit
- Timestamp:
- Jan 3, 2013 1:39:11 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r138731 r138735 1 2013-01-03 Elliott Sprehn <esprehn@gmail.com> 2 3 [Refactoring] Replace Node's Document pointer with a TreeScope pointer 4 https://bugs.webkit.org/show_bug.cgi?id=59816 5 6 Reviewed by Ryosuke Niwa. 7 8 Instead of giving every node in a shadow a rare data, which can be quite 9 large, we replace the Document pointer in Node with a TreeScope pointer 10 and we give TreeScope a pointer to it's document scope. 11 12 This introduces no branches in document() because in the common 13 case document() becomes equivalent to m_treeScope->m_documentScope where 14 the documentScope is actually m_treeScope so this shouldn't introduce a 15 perf regression. 16 17 Note also that TreeScope can never be null after r136328, and the document 18 pointer is only null for DocumentType nodes so we can use a special 19 no-document TreeScope for this case that always returns null from 20 documentScope(). 21 22 My original patch in r137524 for this did not correctly handle the case 23 where the Document is being destroyed and we would then call guardDeref on 24 ourself in the middle of the Document destructor causing asserts. To fix 25 this we need to go back to the original model where Document passes 26 null to it's super constructor for the Document pointer and assigns 27 it's tree scope later, and we also need to clear the tree scope pointer 28 in Document's destructor. 29 30 No new tests, no change in behavior. 31 32 * dom/Document.cpp: 33 (WebCore::Document::Document): 34 (WebCore::Document::~Document): 35 (WebCore::Document::suggestedMIMEType): 36 * dom/Document.h: 37 (WebCore::Node::isDocumentNode): 38 (WebCore::Node::Node): 39 * dom/Element.cpp: 40 (WebCore::Element::createRareData): 41 * dom/ElementRareData.h: 42 (ElementRareData): 43 (WebCore::ElementRareData::ElementRareData): 44 * dom/Node.cpp: 45 (WebCore::Node::~Node): 46 (WebCore::Node::createRareData): 47 (WebCore::Node::attach): 48 (WebCore::Node::reportMemoryUsage): 49 * dom/Node.h: 50 (WebCore::NodeRareDataBase::NodeRareDataBase): 51 (NodeRareDataBase): 52 (WebCore::Node::treeScope): 53 (WebCore::Node::inDocument): 54 (WebCore::Node::documentInternal): 55 (WebCore::Node::setTreeScope): 56 (Node): 57 * dom/NodeRareData.cpp: 58 (SameSizeAsNodeRareData): 59 (WebCore::NodeRareData::reportMemoryUsage): 60 * dom/NodeRareData.h: 61 (WebCore::NodeRareData::NodeRareData): 62 * dom/ShadowRoot.cpp: 63 (WebCore::ShadowRoot::ShadowRoot): 64 * dom/TreeScope.cpp: 65 (SameSizeAsTreeScope): 66 (WebCore::TreeScope::TreeScope): 67 (WebCore::TreeScope::clearDocumentScope): 68 Needed to clear the document scope during Document destruction 69 so the Node destructor does not guardDeref the document that is 70 already being destroyed. 71 (WebCore::TreeScope::setParentTreeScope): 72 * dom/TreeScope.h: 73 (TreeScope): 74 (WebCore::TreeScope::documentScope): 75 (WebCore::TreeScope::noDocumentInstance): 76 Special shared tree scope that has a document scope that is always 77 null. This is needed for DocType nodes, and also for Documents 78 during construction. 79 (WebCore::TreeScope::setDocumentScope): 80 * dom/TreeScopeAdopter.cpp: 81 (WebCore::TreeScopeAdopter::moveTreeToNewScope): 82 (WebCore::TreeScopeAdopter::moveNodeToNewDocument): 83 1 84 2013-01-03 Adam Klein <adamk@chromium.org> 2 85 -
trunk/Source/WebCore/dom/Document.cpp
r138730 r138735 508 508 #endif 509 509 { 510 m_document = this;510 setTreeScope(this); 511 511 512 512 m_printing = false; … … 671 671 ASSERT(!m_nodeListCounts[i]); 672 672 673 m_document = 0;673 clearDocumentScope(); 674 674 675 675 InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter); … … 1347 1347 String Document::suggestedMIMEType() const 1348 1348 { 1349 if ( m_document->isXHTMLDocument())1349 if (isXHTMLDocument()) 1350 1350 return "application/xhtml+xml"; 1351 if ( m_document->isSVGDocument())1351 if (isSVGDocument()) 1352 1352 return "image/svg+xml"; 1353 if ( m_document->xmlStandalone())1353 if (xmlStandalone()) 1354 1354 return "text/xml"; 1355 if ( m_document->isHTMLDocument())1355 if (isHTMLDocument()) 1356 1356 return "text/html"; 1357 1357 -
trunk/Source/WebCore/dom/Document.h
r138730 r138735 1587 1587 inline bool Node::isDocumentNode() const 1588 1588 { 1589 return this == m_document; 1590 } 1591 1592 inline TreeScope* Node::treeScope() const 1593 { 1594 return hasRareData() ? m_data.m_rareData->treeScope() : documentInternal(); 1589 return this == documentInternal(); 1595 1590 } 1596 1591 1597 1592 inline Node::Node(Document* document, ConstructionType type) 1598 1593 : m_nodeFlags(type) 1599 , m_ document(document)1594 , m_treeScope(document) 1600 1595 , m_previous(0) 1601 1596 , m_next(0) … … 1603 1598 if (document) 1604 1599 document->guardRef(); 1600 else 1601 m_treeScope = TreeScope::noDocumentInstance(); 1602 1605 1603 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS) 1606 1604 trackForDebugging(); -
trunk/Source/WebCore/dom/Element.cpp
r138691 r138735 218 218 PassOwnPtr<NodeRareData> Element::createRareData() 219 219 { 220 return adoptPtr(new ElementRareData( documentInternal()));220 return adoptPtr(new ElementRareData()); 221 221 } 222 222 -
trunk/Source/WebCore/dom/ElementRareData.h
r138691 r138735 36 36 class ElementRareData : public NodeRareData { 37 37 public: 38 ElementRareData( Document*);38 ElementRareData(); 39 39 virtual ~ElementRareData(); 40 40 … … 142 142 } 143 143 144 inline ElementRareData::ElementRareData(Document* document) 145 : NodeRareData(document) 146 , m_minimumSizeForResizing(defaultMinimumSizeForResizing()) 144 inline ElementRareData::ElementRareData() 145 : m_minimumSizeForResizing(defaultMinimumSizeForResizing()) 147 146 , m_generatedBefore(0) 148 147 , m_generatedAfter(0) -
trunk/Source/WebCore/dom/Node.cpp
r138730 r138735 415 415 clearRareData(); 416 416 417 Document* doc = documentInternal(); 418 417 419 if (hasEventTargetData()) { 418 420 #if ENABLE(TOUCH_EVENT_TRACKING) 419 if ( m_document)420 m_document->didRemoveEventTargetNode(this);421 if (doc) 422 doc->didRemoveEventTargetNode(this); 421 423 #endif 422 424 clearEventTargetData(); … … 426 428 detach(); 427 429 428 Document* doc = m_document;429 430 if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists() && !isContainerNode()) 430 431 doc->axObjectCache()->remove(this); … … 439 440 440 441 InspectorCounters::decrementCounter(InspectorCounters::NodeCounter); 441 }442 443 void Node::setDocument(Document* document)444 {445 ASSERT(!inDocument() || m_document == document);446 if (inDocument() || m_document == document)447 return;448 449 m_document = document;450 }451 452 void Node::setTreeScope(TreeScope* scope)453 {454 ASSERT(!isShadowRoot());455 456 if (!hasRareData() && scope->rootNode()->isDocumentNode())457 return;458 459 ensureRareData()->setTreeScope(scope);460 442 } 461 443 … … 481 463 PassOwnPtr<NodeRareData> Node::createRareData() 482 464 { 483 return adoptPtr(new NodeRareData( documentInternal()));465 return adoptPtr(new NodeRareData()); 484 466 } 485 467 … … 1106 1088 clearNeedsStyleRecalc(); 1107 1089 1108 Document* doc = m_document;1090 Document* doc = documentInternal(); 1109 1091 if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists()) 1110 1092 doc->axObjectCache()->updateCacheAfterNodeIsAttached(this); … … 2607 2589 TreeShared<Node, ContainerNode>::reportMemoryUsage(memoryObjectInfo); 2608 2590 ScriptWrappable::reportMemoryUsage(memoryObjectInfo); 2609 info.addMember(m_ document);2591 info.addMember(m_treeScope); 2610 2592 info.addMember(m_next); 2611 2593 info.addMember(m_previous); -
trunk/Source/WebCore/dom/Node.h
r138730 r138735 34 34 #include "ScriptWrappable.h" 35 35 #include "SimulatedClickOptions.h" 36 #include "TreeScope.h" 36 37 #include "TreeShared.h" 37 38 #include <wtf/Forward.h> … … 86 87 class ShadowRoot; 87 88 class TagNodeList; 88 class TreeScope;89 89 90 90 #if ENABLE(GESTURE_EVENTS) … … 116 116 void setRenderer(RenderObject* renderer) { m_renderer = renderer; } 117 117 118 TreeScope* treeScope() const { return m_treeScope; }119 void setTreeScope(TreeScope* scope) { m_treeScope = scope; }120 121 118 virtual ~NodeRareDataBase() { } 122 119 protected: 123 NodeRareDataBase(TreeScope* scope) 124 : m_treeScope(scope) 125 { 126 } 120 NodeRareDataBase() { } 127 121 private: 128 122 RenderObject* m_renderer; 129 TreeScope* m_treeScope;130 123 }; 131 124 … … 469 462 } 470 463 471 TreeScope* treeScope() const ;464 TreeScope* treeScope() const { return m_treeScope; } 472 465 473 466 // Returns true if this node is associated with a document and is in its associated document's … … 475 468 bool inDocument() const 476 469 { 477 ASSERT( m_document|| !getFlag(InDocumentFlag));470 ASSERT(documentInternal() || !getFlag(InDocumentFlag)); 478 471 return getFlag(InDocumentFlag); 479 472 } … … 771 764 void setHasCustomCallbacks() { setFlag(true, HasCustomCallbacksFlag); } 772 765 773 Document* documentInternal() const { return m_document; } 766 Document* documentInternal() const { return treeScope()->documentScope(); } 767 void setTreeScope(TreeScope* scope) { m_treeScope = scope; } 774 768 775 769 private: … … 777 771 778 772 void removedLastRef(); 779 780 // These API should be only used for a tree scope migration.781 void setTreeScope(TreeScope*);782 void setDocument(Document*);783 773 784 774 enum EditableLevel { Editable, RichlyEditable }; … … 824 814 825 815 mutable uint32_t m_nodeFlags; 826 Document* m_document;816 TreeScope* m_treeScope; 827 817 Node* m_previous; 828 818 Node* m_next; -
trunk/Source/WebCore/dom/NodeRareData.cpp
r137535 r138735 40 40 41 41 struct SameSizeAsNodeRareData { 42 void* m_pointer[ 4];42 void* m_pointer[3]; 43 43 unsigned m_indicesAndBitfields[2]; 44 44 … … 65 65 { 66 66 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); 67 info.addMember(treeScope());68 67 info.addMember(m_nodeLists); 69 68 -
trunk/Source/WebCore/dom/NodeRareData.h
r137955 r138735 247 247 248 248 public: 249 NodeRareData(Document* document) 250 : NodeRareDataBase(document) 251 , m_tabIndex(0) 249 NodeRareData() 250 : m_tabIndex(0) 252 251 , m_childIndex(0) 253 252 , m_tabIndexWasSetExplicitly(false) -
trunk/Source/WebCore/dom/ShadowRoot.cpp
r138404 r138735 66 66 ShadowRoot::ShadowRoot(Document* document) 67 67 : DocumentFragment(document, CreateShadowRoot) 68 , TreeScope(this )68 , TreeScope(this, document) 69 69 , m_prev(0) 70 70 , m_next(0) … … 76 76 { 77 77 ASSERT(document); 78 79 // Assume document as parent scope. 80 setParentTreeScope(document); 81 // Shadow tree scopes have the scope pointer point to themselves. 82 // This way, direct children will receive the correct scope pointer. 83 ensureRareData()->setTreeScope(this); 78 setTreeScope(this); 84 79 } 85 80 -
trunk/Source/WebCore/dom/TreeScope.cpp
r138379 r138735 59 59 struct SameSizeAsTreeScope { 60 60 virtual ~SameSizeAsTreeScope(); 61 void* pointers[ 7];61 void* pointers[8]; 62 62 }; 63 63 … … 66 66 using namespace HTMLNames; 67 67 68 TreeScope::TreeScope(ContainerNode* rootNode )68 TreeScope::TreeScope(ContainerNode* rootNode, Document* document) 69 69 : m_rootNode(rootNode) 70 , m_documentScope(document) 71 , m_parentTreeScope(document) 72 , m_idTargetObserverRegistry(IdTargetObserverRegistry::create()) 73 { 74 ASSERT(rootNode); 75 ASSERT(document); 76 ASSERT(rootNode != document); 77 } 78 79 TreeScope::TreeScope(Document* document) 80 : m_rootNode(document) 81 , m_documentScope(document) 70 82 , m_parentTreeScope(0) 71 83 , m_idTargetObserverRegistry(IdTargetObserverRegistry::create()) 72 84 { 73 ASSERT(rootNode); 85 ASSERT(document); 86 } 87 88 TreeScope::TreeScope() 89 : m_rootNode(0) 90 , m_documentScope(0) 91 , m_parentTreeScope(0) 92 { 74 93 } 75 94 … … 87 106 m_imageMapsByName.clear(); 88 107 m_labelsByForAttribute.clear(); 108 } 109 110 void TreeScope::clearDocumentScope() 111 { 112 ASSERT(rootNode()->isDocumentNode()); 113 m_documentScope = 0; 89 114 } 90 115 … … 97 122 98 123 m_parentTreeScope = newParentScope; 124 setDocumentScope(newParentScope->documentScope()); 99 125 } 100 126 -
trunk/Source/WebCore/dom/TreeScope.h
r138379 r138735 49 49 class TreeScope { 50 50 friend class Document; 51 friend class TreeScopeAdopter; 51 52 52 53 public: … … 60 61 void addElementById(const AtomicString& elementId, Element*); 61 62 void removeElementById(const AtomicString& elementId, Element*); 63 64 Document* documentScope() const { return m_documentScope; } 62 65 63 66 Node* ancestorInThisScope(Node*) const; … … 96 99 virtual void reportMemoryUsage(MemoryObjectInfo*) const; 97 100 101 static TreeScope* noDocumentInstance() 102 { 103 DEFINE_STATIC_LOCAL(TreeScope, instance, ()); 104 return &instance; 105 } 106 98 107 protected: 99 explicit TreeScope(ContainerNode*); 108 TreeScope(ContainerNode*, Document*); 109 TreeScope(Document*); 100 110 virtual ~TreeScope(); 101 111 102 112 void destroyTreeScopeData(); 113 void clearDocumentScope(); 114 void setDocumentScope(Document* document) 115 { 116 ASSERT(document); 117 ASSERT(this != noDocumentInstance()); 118 m_documentScope = document; 119 } 103 120 104 121 private: 122 TreeScope(); 123 105 124 ContainerNode* m_rootNode; 125 Document* m_documentScope; 106 126 TreeScope* m_parentTreeScope; 107 127 -
trunk/Source/WebCore/dom/TreeScopeAdopter.cpp
r137535 r138735 44 44 // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here 45 45 // we ensure that the collection cache will be invalidated as needed when the element is moved back. 46 Document* oldDocument = m_oldScope ? m_oldScope->rootNode()->document() : 0;47 Document* newDocument = m_newScope-> rootNode()->document();46 Document* oldDocument = m_oldScope->documentScope(); 47 Document* newDocument = m_newScope->documentScope(); 48 48 bool willMoveToNewDocument = oldDocument != newDocument; 49 49 if (oldDocument && willMoveToNewDocument) … … 52 52 for (Node* node = root; node; node = NodeTraversal::next(node, root)) { 53 53 node->setTreeScope(m_newScope); 54 54 55 if (node->hasRareData()) { 55 56 NodeRareData* rareData = node->rareData(); … … 98 99 oldDocument->moveNodeIteratorsToNewDocument(node, newDocument); 99 100 100 node->setDocument(newDocument); 101 if (node->isShadowRoot()) 102 toShadowRoot(node)->setDocumentScope(newDocument); 101 103 102 104 #ifndef NDEBUG
Note: See TracChangeset
for help on using the changeset viewer.