Changeset 78322 in webkit
- Timestamp:
- Feb 11, 2011 12:57:40 AM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r78321 r78322 1 2011-02-10 Antti Koivisto <antti@apple.com> 2 3 Reviewed by Dave Hyatt. 4 5 Enable ancestor identifier filtering for tree building 6 https://bugs.webkit.org/show_bug.cgi?id=54241 7 8 Call CSSStyleSelector::push/popParent() during tree building too, fix up the parent 9 element stack as needed. 10 11 This roughly halves the remaining time in style matching over a typical page load. 12 13 * css/CSSStyleSelector.cpp: 14 (WebCore::CSSStyleSelector::pushParentStackFrame): 15 (WebCore::CSSStyleSelector::popParentStackFrame): 16 (WebCore::CSSStyleSelector::pushParent): 17 (WebCore::CSSStyleSelector::popParent): 18 * css/CSSStyleSelector.h: 19 (WebCore::CSSStyleSelector::ParentStackFrame::ParentStackFrame): 20 * dom/Document.h: 21 (WebCore::Document::styleSelectorIfExists): 22 * dom/Element.cpp: 23 (WebCore::Element::beginParsingChildren): 24 (WebCore::Element::finishParsingChildren): 25 * dom/Element.h: 26 1 27 2011-02-10 Adam Barth <abarth@webkit.org> 2 28 -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r78183 r78322 670 670 } 671 671 672 void CSSStyleSelector::pushParent(Element* parent) 673 { 674 // If we are not invoked consistently for each parent, just pause maintaining the stack. 675 // There are all kinds of wacky special cases where the style recalc may temporarily branch to some random elements. 676 // FIXME: Perhaps we should fix up the stack instead? There is some danger of getting into O(n^2) situations doing that. 677 if (m_parentStack.isEmpty()) { 678 ASSERT(!m_ancestorIdentifierFilter); 679 // We must start from the root. 680 if (parent->parentElement()) 681 return; 682 m_ancestorIdentifierFilter = adoptPtr(new BloomFilter<bloomFilterKeyBits>); 683 } else { 684 ASSERT(m_ancestorIdentifierFilter); 685 if (m_parentStack.last().element != parent->parentElement()) 686 return; 687 } 688 672 void CSSStyleSelector::pushParentStackFrame(Element* parent) 673 { 674 ASSERT(m_ancestorIdentifierFilter); 675 ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentElement()); 676 ASSERT(!m_parentStack.isEmpty() || !parent->parentElement()); 689 677 m_parentStack.append(ParentStackFrame(parent)); 690 678 ParentStackFrame& parentFrame = m_parentStack.last(); … … 697 685 } 698 686 699 void CSSStyleSelector::popParent(Element* parent) 700 { 701 if (m_parentStack.isEmpty() || m_parentStack.last().element != parent) 702 return; 687 void CSSStyleSelector::popParentStackFrame() 688 { 689 ASSERT(!m_parentStack.isEmpty()); 703 690 ASSERT(m_ancestorIdentifierFilter); 704 705 691 const ParentStackFrame& parentFrame = m_parentStack.last(); 706 692 size_t count = parentFrame.identifierHashes.size(); … … 712 698 m_ancestorIdentifierFilter.clear(); 713 699 } 700 } 701 702 void CSSStyleSelector::pushParent(Element* parent) 703 { 704 if (m_parentStack.isEmpty()) { 705 ASSERT(!m_ancestorIdentifierFilter); 706 m_ancestorIdentifierFilter = adoptPtr(new BloomFilter<bloomFilterKeyBits>); 707 // If the element is not the root itself, build the stack starting from the root. 708 if (parent->parentElement()) { 709 Vector<Element*, 30> ancestors; 710 for (Element* ancestor = parent; ancestor; ancestor = ancestor->parentElement()) 711 ancestors.append(ancestor); 712 int count = ancestors.size(); 713 for (int n = count - 1; n >= 0; --n) 714 pushParentStackFrame(ancestors[n]); 715 return; 716 } 717 } else if (!parent->parentElement()) { 718 // We are not always invoked consistently. For example, script execution can cause us to enter 719 // style recalc in the middle of tree building. Reset the stack if we see a new root element. 720 ASSERT(m_ancestorIdentifierFilter); 721 m_ancestorIdentifierFilter->clear(); 722 m_parentStack.resize(0); 723 } else { 724 ASSERT(m_ancestorIdentifierFilter); 725 // We may get invoked for some random elements in some wacky cases during style resolve. 726 // Pause maintaining the stack in this case. 727 if (m_parentStack.last().element != parent->parentElement()) 728 return; 729 } 730 pushParentStackFrame(parent); 731 } 732 733 void CSSStyleSelector::popParent(Element* parent) 734 { 735 if (m_parentStack.isEmpty() || m_parentStack.last().element != parent) 736 return; 737 popParentStackFrame(); 714 738 } 715 739 -
trunk/Source/WebCore/css/CSSStyleSelector.h
r78183 r78322 120 120 Node* findSiblingForStyleSharing(Node*, unsigned& count) const; 121 121 bool canShareStyleWithElement(Node*) const; 122 123 void pushParentStackFrame(Element* parent); 124 void popParentStackFrame(); 122 125 123 126 RenderStyle* style() const { return m_style.get(); } … … 211 214 212 215 struct ParentStackFrame { 216 ParentStackFrame() {} 213 217 ParentStackFrame(Element* element) : element(element) {} 214 218 Element* element; -
trunk/Source/WebCore/dom/Document.h
r78314 r78322 432 432 virtual bool isFrameSet() const { return false; } 433 433 434 CSSStyleSelector* styleSelectorIfExists() const { return m_styleSelector.get(); } 434 435 CSSStyleSelector* styleSelector() 435 436 { -
trunk/Source/WebCore/dom/Element.cpp
r78317 r78322 1261 1261 checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta); 1262 1262 } 1263 1264 void Element::beginParsingChildren() 1265 { 1266 clearIsParsingChildrenFinished(); 1267 CSSStyleSelector* styleSelector = document()->styleSelectorIfExists(); 1268 if (styleSelector && attached()) 1269 styleSelector->pushParent(this); 1270 } 1263 1271 1264 1272 void Element::finishParsingChildren() … … 1267 1275 setIsParsingChildrenFinished(); 1268 1276 checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0); 1277 if (CSSStyleSelector* styleSelector = document()->styleSelectorIfExists()) 1278 styleSelector->popParent(this); 1269 1279 } 1270 1280 -
trunk/Source/WebCore/dom/Element.h
r78317 r78322 277 277 bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); } 278 278 virtual void finishParsingChildren(); 279 virtual void beginParsingChildren() { clearIsParsingChildrenFinished(); }279 virtual void beginParsingChildren(); 280 280 281 281 // ElementTraversal API
Note: See TracChangeset
for help on using the changeset viewer.