Skip to content

Commit

Permalink
Merge r228729 - Use selector filter when invalidating descendants
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=182839
<rdar://problem/37581072>

Reviewed by Zalan Bujtas.

We can make descendant invalidation faster by enabling filtering.

* css/SelectorFilter.cpp:
(WebCore::SelectorFilter::initializeParentStack):

    Traverse and reverse the ancestor chain, and push it.

(WebCore::SelectorFilter::pushParent):
(WebCore::SelectorFilter::pushParentInitializingIfNeeded):

    Add a version of pushParent that can initialize the stack.

(WebCore::SelectorFilter::popParent):
(WebCore::SelectorFilter::popParentsUntil):

    Pop until a given parent element.

(WebCore::SelectorFilter::pushParentStackFrame): Deleted.
(WebCore::SelectorFilter::popParentStackFrame): Deleted.

    These were the same as push/popParent.

* css/SelectorFilter.h:
(WebCore::SelectorFilter::popParent): Deleted.
* style/StyleInvalidator.cpp:
(WebCore::Style::Invalidator::invalidateStyleForDescendants):

    Use pushParentInitializingIfNeeded.

(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):

    Use selector filter when doing descendant tree invalidation.
    Make sure to pop it until the parent when reusing.
  • Loading branch information
anttijk authored and carlosgcampos committed Feb 26, 2018
1 parent 2084e19 commit b5261c1
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 13 deletions.
42 changes: 42 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,45 @@
2018-02-19 Antti Koivisto <antti@apple.com>

Use selector filter when invalidating descendants
https://bugs.webkit.org/show_bug.cgi?id=182839
<rdar://problem/37581072>

Reviewed by Zalan Bujtas.

We can make descendant invalidation faster by enabling filtering.

* css/SelectorFilter.cpp:
(WebCore::SelectorFilter::initializeParentStack):

Traverse and reverse the ancestor chain, and push it.

(WebCore::SelectorFilter::pushParent):
(WebCore::SelectorFilter::pushParentInitializingIfNeeded):

Add a version of pushParent that can initialize the stack.

(WebCore::SelectorFilter::popParent):
(WebCore::SelectorFilter::popParentsUntil):

Pop until a given parent element.

(WebCore::SelectorFilter::pushParentStackFrame): Deleted.
(WebCore::SelectorFilter::popParentStackFrame): Deleted.

These were the same as push/popParent.

* css/SelectorFilter.h:
(WebCore::SelectorFilter::popParent): Deleted.
* style/StyleInvalidator.cpp:
(WebCore::Style::Invalidator::invalidateStyleForDescendants):

Use pushParentInitializingIfNeeded.

(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):

Use selector filter when doing descendant tree invalidation.
Make sure to pop it until the parent when reusing.

2018-02-19 Fujii Hironori <Hironori.Fujii@sony.com>

null m_lastNodeInserted dereference at ReplaceSelectionCommand::InsertedNodes::lastLeafInserted
Expand Down
30 changes: 26 additions & 4 deletions Source/WebCore/css/SelectorFilter.cpp
Expand Up @@ -63,7 +63,16 @@ bool SelectorFilter::parentStackIsConsistent(const ContainerNode* parentNode) co
return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode;
}

void SelectorFilter::pushParentStackFrame(Element* parent)
void SelectorFilter::initializeParentStack(Element& parent)
{
Vector<Element*, 20> ancestors;
for (auto* ancestor = &parent; ancestor; ancestor = ancestor->parentElement())
ancestors.append(ancestor);
for (unsigned i = ancestors.size(); i--;)
pushParent(ancestors[i]);
}

void SelectorFilter::pushParent(Element* parent)
{
ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentElement());
ASSERT(!m_parentStack.isEmpty() || !parent->parentElement());
Expand All @@ -77,7 +86,16 @@ void SelectorFilter::pushParentStackFrame(Element* parent)
m_ancestorIdentifierFilter.add(parentFrame.identifierHashes[i]);
}

void SelectorFilter::popParentStackFrame()
void SelectorFilter::pushParentInitializingIfNeeded(Element& parent)
{
if (UNLIKELY(m_parentStack.isEmpty())) {
initializeParentStack(parent);
return;
}
pushParent(&parent);
}

void SelectorFilter::popParent()
{
ASSERT(!m_parentStack.isEmpty());
const ParentStackFrame& parentFrame = m_parentStack.last();
Expand All @@ -91,9 +109,13 @@ void SelectorFilter::popParentStackFrame()
}
}

void SelectorFilter::pushParent(Element* parent)
void SelectorFilter::popParentsUntil(Element* parent)
{
pushParentStackFrame(parent);
while (!m_parentStack.isEmpty()) {
if (parent && m_parentStack.last().element == parent)
return;
popParent();
}
}

struct CollectedSelectorHashes {
Expand Down
9 changes: 5 additions & 4 deletions Source/WebCore/css/SelectorFilter.h
Expand Up @@ -39,11 +39,10 @@ class CSSSelector;

class SelectorFilter {
public:
void pushParentStackFrame(Element* parent);
void popParentStackFrame();

void pushParent(Element* parent);
void popParent() { popParentStackFrame(); }
void pushParentInitializingIfNeeded(Element& parent);
void popParent();
void popParentsUntil(Element* parent);
bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
bool parentStackIsConsistent(const ContainerNode* parentNode) const;

Expand All @@ -52,6 +51,8 @@ class SelectorFilter {
static Hashes collectHashes(const CSSSelector&);

private:
void initializeParentStack(Element& parent);

struct ParentStackFrame {
ParentStackFrame() : element(0) { }
ParentStackFrame(Element* element) : element(element) { }
Expand Down
15 changes: 10 additions & 5 deletions Source/WebCore/style/StyleInvalidator.cpp
Expand Up @@ -158,7 +158,7 @@ void Invalidator::invalidateStyleForDescendants(Element& root, SelectorFilter* f
if (parent == previousElement) {
parentStack.append(parent);
if (filter)
filter->pushParent(parent);
filter->pushParentInitializingIfNeeded(*parent);
} else {
while (parentStack.last() != parent) {
parentStack.removeLast();
Expand Down Expand Up @@ -223,7 +223,8 @@ void Invalidator::invalidateStyleWithMatchElement(Element& element, MatchElement
break;
}
case MatchElement::Ancestor: {
invalidateStyleForDescendants(element, nullptr);
SelectorFilter filter;
invalidateStyleForDescendants(element, &filter);
break;
}
case MatchElement::DirectSibling:
Expand All @@ -247,10 +248,14 @@ void Invalidator::invalidateStyleWithMatchElement(Element& element, MatchElement
invalidateIfNeeded(siblingChild, nullptr);
}
break;
case MatchElement::AncestorSibling:
for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling())
invalidateStyleForDescendants(*sibling, nullptr);
case MatchElement::AncestorSibling: {
SelectorFilter filter;
for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
filter.popParentsUntil(element.parentElement());
invalidateStyleForDescendants(*sibling, &filter);
}
break;
}
case MatchElement::Host:
// FIXME: Handle this here as well.
break;
Expand Down

0 comments on commit b5261c1

Please sign in to comment.