Changeset 78322 in webkit


Ignore:
Timestamp:
Feb 11, 2011 12:57:40 AM (13 years ago)
Author:
Antti Koivisto
Message:

Enable ancestor identifier filtering for tree building
https://bugs.webkit.org/show_bug.cgi?id=54241

Reviewed by Dave Hyatt.

Call CSSStyleSelector::push/popParent() during tree building too, fix up the parent
element stack as needed.

This roughly halves the remaining time in style matching over a typical page load.

  • css/CSSStyleSelector.cpp:

(WebCore::CSSStyleSelector::pushParentStackFrame):
(WebCore::CSSStyleSelector::popParentStackFrame):
(WebCore::CSSStyleSelector::pushParent):
(WebCore::CSSStyleSelector::popParent):

  • css/CSSStyleSelector.h:

(WebCore::CSSStyleSelector::ParentStackFrame::ParentStackFrame):

  • dom/Document.h:

(WebCore::Document::styleSelectorIfExists):

  • dom/Element.cpp:

(WebCore::Element::beginParsingChildren):
(WebCore::Element::finishParsingChildren):

  • dom/Element.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r78321 r78322  
     12011-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
    1272011-02-10  Adam Barth  <abarth@webkit.org>
    228
  • trunk/Source/WebCore/css/CSSStyleSelector.cpp

    r78183 r78322  
    670670}
    671671
    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 
     672void 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());
    689677    m_parentStack.append(ParentStackFrame(parent));
    690678    ParentStackFrame& parentFrame = m_parentStack.last();
     
    697685}
    698686
    699 void CSSStyleSelector::popParent(Element* parent)
    700 {
    701     if (m_parentStack.isEmpty() || m_parentStack.last().element != parent)
    702         return;
     687void CSSStyleSelector::popParentStackFrame()
     688{
     689    ASSERT(!m_parentStack.isEmpty());
    703690    ASSERT(m_ancestorIdentifierFilter);
    704 
    705691    const ParentStackFrame& parentFrame = m_parentStack.last();
    706692    size_t count = parentFrame.identifierHashes.size();
     
    712698        m_ancestorIdentifierFilter.clear();
    713699    }
     700}
     701
     702void 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
     733void CSSStyleSelector::popParent(Element* parent)
     734{
     735    if (m_parentStack.isEmpty() || m_parentStack.last().element != parent)
     736        return;
     737    popParentStackFrame();
    714738}
    715739
  • trunk/Source/WebCore/css/CSSStyleSelector.h

    r78183 r78322  
    120120        Node* findSiblingForStyleSharing(Node*, unsigned& count) const;
    121121        bool canShareStyleWithElement(Node*) const;
     122       
     123        void pushParentStackFrame(Element* parent);
     124        void popParentStackFrame();
    122125
    123126        RenderStyle* style() const { return m_style.get(); }
     
    211214       
    212215        struct ParentStackFrame {
     216            ParentStackFrame() {}
    213217            ParentStackFrame(Element* element) : element(element) {}
    214218            Element* element;
  • trunk/Source/WebCore/dom/Document.h

    r78314 r78322  
    432432    virtual bool isFrameSet() const { return false; }
    433433   
     434    CSSStyleSelector* styleSelectorIfExists() const { return m_styleSelector.get(); }
    434435    CSSStyleSelector* styleSelector()
    435436    {
  • trunk/Source/WebCore/dom/Element.cpp

    r78317 r78322  
    12611261        checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
    12621262}
     1263   
     1264void Element::beginParsingChildren()
     1265{
     1266    clearIsParsingChildrenFinished();
     1267    CSSStyleSelector* styleSelector = document()->styleSelectorIfExists();
     1268    if (styleSelector && attached())
     1269        styleSelector->pushParent(this);
     1270}
    12631271
    12641272void Element::finishParsingChildren()
     
    12671275    setIsParsingChildrenFinished();
    12681276    checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
     1277    if (CSSStyleSelector* styleSelector = document()->styleSelectorIfExists())
     1278        styleSelector->popParent(this);
    12691279}
    12701280
  • trunk/Source/WebCore/dom/Element.h

    r78317 r78322  
    277277    bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
    278278    virtual void finishParsingChildren();
    279     virtual void beginParsingChildren() { clearIsParsingChildrenFinished(); }
     279    virtual void beginParsingChildren();
    280280
    281281    // ElementTraversal API
Note: See TracChangeset for help on using the changeset viewer.