Changeset 184615 in webkit


Ignore:
Timestamp:
May 19, 2015 10:28:02 PM (9 years ago)
Author:
Antti Koivisto
Message:

Crash under WebCore::invalidateStyleRecursively
https://bugs.webkit.org/show_bug.cgi?id=145186
rdar://problem/19736838

Reviewed by Andreas Kling

We have seen crashes where we run out of stack under invalidateStyleRecursively in StyleInvalidationAnalysis
on some devices.

Switch to iterative algorithm.

  • css/StyleInvalidationAnalysis.cpp:

(WebCore::StyleInvalidationAnalysis::StyleInvalidationAnalysis):
(WebCore::invalidateIfNeeded):
(WebCore::invalidateStyleForTree):
(WebCore::StyleInvalidationAnalysis::invalidateStyle):
(WebCore::invalidateStyleRecursively): Deleted.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r184612 r184615  
     12015-05-19  Antti Koivisto  <antti@apple.com>
     2
     3        Crash under WebCore::invalidateStyleRecursively
     4        https://bugs.webkit.org/show_bug.cgi?id=145186
     5        rdar://problem/19736838
     6
     7        Reviewed by Andreas Kling
     8
     9        We have seen crashes where we run out of stack under invalidateStyleRecursively in StyleInvalidationAnalysis
     10        on some devices.
     11
     12        Switch to iterative algorithm.
     13
     14        * css/StyleInvalidationAnalysis.cpp:
     15        (WebCore::StyleInvalidationAnalysis::StyleInvalidationAnalysis):
     16        (WebCore::invalidateIfNeeded):
     17        (WebCore::invalidateStyleForTree):
     18        (WebCore::StyleInvalidationAnalysis::invalidateStyle):
     19        (WebCore::invalidateStyleRecursively): Deleted.
     20
    1212015-05-19  Yusuke Suzuki  <utatane.tea@gmail.com>
    222
  • trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp

    r177228 r184615  
    8989}
    9090
    91 static void invalidateStyleRecursively(Element& element, SelectorFilter& filter, const DocumentRuleSets& ruleSets)
     91enum class CheckDescendants { Yes, No };
     92static CheckDescendants invalidateIfNeeded(Element& element, SelectorFilter& filter, const DocumentRuleSets& ruleSets)
    9293{
    93     if (element.styleChangeType() > InlineStyleChange)
    94         return;
    95     if (element.styleChangeType() == NoStyleChange) {
     94    switch (element.styleChangeType()) {
     95    case NoStyleChange: {
    9696        ElementRuleCollector ruleCollector(element, nullptr, ruleSets, filter);
    9797        ruleCollector.setMode(SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements);
     
    100100        if (ruleCollector.hasMatchedRules())
    101101            element.setNeedsStyleRecalc(InlineStyleChange);
     102        return CheckDescendants::Yes;
     103    }
     104    case InlineStyleChange:
     105        return CheckDescendants::Yes;
     106    case FullStyleChange:
     107    case SyntheticStyleChange:
     108    case ReconstructRenderTree:
     109        return CheckDescendants::No;
     110    }
     111    ASSERT_NOT_REACHED();
     112    return CheckDescendants::Yes;
     113}
     114
     115static void invalidateStyleForTree(Element& root, SelectorFilter& filter, const DocumentRuleSets& ruleSets)
     116{
     117    if (invalidateIfNeeded(root, filter, ruleSets) == CheckDescendants::No)
     118        return;
     119
     120    Vector<Element*, 20> parentStack;
     121    Element* previousElement = &root;
     122    auto descendants = descendantsOfType<Element>(root);
     123    for (auto it = descendants.begin(), end = descendants.end(); it != end;) {
     124        auto& descendant = *it;
     125        auto* parent = descendant.parentElement();
     126        if (parentStack.isEmpty() || parentStack.last() != parent) {
     127            if (parent == previousElement) {
     128                parentStack.append(parent);
     129                filter.pushParent(parent);
     130            } else {
     131                while (parentStack.last() != parent) {
     132                    parentStack.removeLast();
     133                    filter.popParent();
     134                }
     135            }
     136        }
     137        previousElement = &descendant;
     138
     139        if (invalidateIfNeeded(descendant, filter, ruleSets) == CheckDescendants::Yes)
     140            it.traverseNext();
     141        else
     142            it.traverseNextSkippingChildren();
    102143    }
    103144
    104     auto children = childrenOfType<Element>(element);
    105     if (!children.first())
    106         return;
    107     filter.pushParent(&element);
    108     for (auto& child : children)
    109         invalidateStyleRecursively(child, filter, ruleSets);
    110     filter.popParent();
     145    while (!parentStack.isEmpty()) {
     146        parentStack.removeLast();
     147        filter.popParent();
     148    }
    111149}
    112150
     
    123161    SelectorFilter filter;
    124162    filter.setupParentStack(documentElement);
    125     invalidateStyleRecursively(*documentElement, filter, m_ruleSets);
     163    invalidateStyleForTree(*documentElement, filter, m_ruleSets);
    126164}
    127165
Note: See TracChangeset for help on using the changeset viewer.