Avoid traversing too much when doing class change invalidation
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Jan 2018 16:13:15 +0000 (16:13 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Jan 2018 16:13:15 +0000 (16:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181604

Reviewed by Zalan Bujtas.

We are now collecting information about which part of the tree a change in class can potentially affect.
Use the information to traverse only the required elements in Style::Invalidator.

The same mechanism can be later used for attribute and id change invalidation.

* css/DocumentRuleSets.cpp:
(WebCore::DocumentRuleSets::collectFeatures const):
(WebCore::DocumentRuleSets::classInvalidationRuleSets const):
(WebCore::DocumentRuleSets::subjectClassRules const): Deleted.
(WebCore::DocumentRuleSets::ancestorClassRules const): Deleted.

    Remove separate subject and ancestor invalidation RuleSets. Instead collect all invalidation rulesets
    to a vector along with their MatchElements.

* css/DocumentRuleSets.h:
* css/RuleFeature.cpp:
(WebCore::RuleFeatureSet::computeNextMatchElement):
(WebCore::RuleFeatureSet::computeSubSelectorMatchElement):
(WebCore::RuleFeatureSet::collectFeatures):

    Similarly collect all class invalidation RuleFeatures to a general HashMap along with the MatchElement.

(WebCore::RuleFeatureSet::add):
(WebCore::RuleFeatureSet::clear):
(WebCore::RuleFeatureSet::shrinkToFit):
* css/RuleFeature.h:
(WebCore::RuleFeature::RuleFeature):
* style/ClassChangeInvalidation.cpp:
(WebCore::Style::ClassChangeInvalidation::computeInvalidation):

    Find out InvalidationRuleSets to use.

(WebCore::Style::ClassChangeInvalidation::invalidateStyleWithRuleSets):

    Pass them to Style::Invalidator.

* style/ClassChangeInvalidation.h:
* style/StyleInvalidator.cpp:
(WebCore::Style::Invalidator::invalidateStyleForTree):
(WebCore::Style::Invalidator::invalidateStyleForDescendants):
(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):

    Traverse only the part of the tree needed by the given MatchElement.

* style/StyleInvalidator.h:
* style/StyleSharingResolver.cpp:
(WebCore::Style::SharingResolver::classNamesAffectedByRules const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227787 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/css/DocumentRuleSets.cpp
Source/WebCore/css/DocumentRuleSets.h
Source/WebCore/css/RuleFeature.cpp
Source/WebCore/css/RuleFeature.h
Source/WebCore/style/ClassChangeInvalidation.cpp
Source/WebCore/style/ClassChangeInvalidation.h
Source/WebCore/style/StyleInvalidator.cpp
Source/WebCore/style/StyleInvalidator.h
Source/WebCore/style/StyleSharingResolver.cpp

index ceeabda..a6585f2 100644 (file)
@@ -1,3 +1,58 @@
+2018-01-30  Antti Koivisto  <antti@apple.com>
+
+        Avoid traversing too much when doing class change invalidation
+        https://bugs.webkit.org/show_bug.cgi?id=181604
+
+        Reviewed by Zalan Bujtas.
+
+        We are now collecting information about which part of the tree a change in class can potentially affect.
+        Use the information to traverse only the required elements in Style::Invalidator.
+
+        The same mechanism can be later used for attribute and id change invalidation.
+
+        * css/DocumentRuleSets.cpp:
+        (WebCore::DocumentRuleSets::collectFeatures const):
+        (WebCore::DocumentRuleSets::classInvalidationRuleSets const):
+        (WebCore::DocumentRuleSets::subjectClassRules const): Deleted.
+        (WebCore::DocumentRuleSets::ancestorClassRules const): Deleted.
+
+            Remove separate subject and ancestor invalidation RuleSets. Instead collect all invalidation rulesets
+            to a vector along with their MatchElements.
+
+        * css/DocumentRuleSets.h:
+        * css/RuleFeature.cpp:
+        (WebCore::RuleFeatureSet::computeNextMatchElement):
+        (WebCore::RuleFeatureSet::computeSubSelectorMatchElement):
+        (WebCore::RuleFeatureSet::collectFeatures):
+
+            Similarly collect all class invalidation RuleFeatures to a general HashMap along with the MatchElement.
+
+        (WebCore::RuleFeatureSet::add):
+        (WebCore::RuleFeatureSet::clear):
+        (WebCore::RuleFeatureSet::shrinkToFit):
+        * css/RuleFeature.h:
+        (WebCore::RuleFeature::RuleFeature):
+        * style/ClassChangeInvalidation.cpp:
+        (WebCore::Style::ClassChangeInvalidation::computeInvalidation):
+
+            Find out InvalidationRuleSets to use.
+
+        (WebCore::Style::ClassChangeInvalidation::invalidateStyleWithRuleSets):
+
+            Pass them to Style::Invalidator.
+
+        * style/ClassChangeInvalidation.h:
+        * style/StyleInvalidator.cpp:
+        (WebCore::Style::Invalidator::invalidateStyleForTree):
+        (WebCore::Style::Invalidator::invalidateStyleForDescendants):
+        (WebCore::Style::Invalidator::invalidateStyleWithMatchElement):
+
+            Traverse only the part of the tree needed by the given MatchElement.
+
+        * style/StyleInvalidator.h:
+        * style/StyleSharingResolver.cpp:
+        (WebCore::Style::SharingResolver::classNamesAffectedByRules const):
+
 2018-01-30  Javier Fernandez  <jfernandez@igalia.com>
 
         [css-align] The 'baseline' value must be invalid for the 'justify-content' property
index 5d2ab75..900e125 100644 (file)
@@ -167,26 +167,31 @@ void DocumentRuleSets::collectFeatures() const
     m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
     m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
 
-    m_subjectClassRuleSets.clear();
-    m_ancestorClassRuleSets.clear();
+    m_classInvalidationRuleSets.clear();
     m_ancestorAttributeRuleSetsForHTML.clear();
 
     m_features.shrinkToFit();
 }
 
-RuleSet* DocumentRuleSets::subjectClassRules(const AtomicString& className) const
+const Vector<InvalidationRuleSet>* DocumentRuleSets::classInvalidationRuleSets(const AtomicString& className) const
 {
-    return m_subjectClassRuleSets.ensure(className, [&] {
-        auto* rules = m_features.subjectClassRules.get(className);
-        return rules ? makeRuleSet(*rules) : nullptr;
-    }).iterator->value.get();
-}
-
-RuleSet* DocumentRuleSets::ancestorClassRules(const AtomicString& className) const
-{
-    return m_ancestorClassRuleSets.ensure(className, [&] {
-        auto* rules = m_features.ancestorClassRules.get(className);
-        return rules ? makeRuleSet(*rules) : nullptr;
+    return m_classInvalidationRuleSets.ensure(className, [&] () -> std::unique_ptr<Vector<InvalidationRuleSet>> {
+        auto* features = m_features.classRules.get(className);
+        if (!features)
+            return nullptr;
+        std::array<std::unique_ptr<RuleSet>, matchElementCount> matchElementArray;
+        for (auto& feature : *features) {
+            auto& ruleSet = matchElementArray[static_cast<unsigned>(*feature.matchElement)];
+            if (!ruleSet)
+                ruleSet = std::make_unique<RuleSet>();
+            ruleSet->addRule(feature.rule, feature.selectorIndex);
+        }
+        auto invalidationRuleSets = std::make_unique<Vector<InvalidationRuleSet>>();
+        for (unsigned i = 0; i < matchElementArray.size(); ++i) {
+            if (matchElementArray[i])
+                invalidationRuleSets->append({ static_cast<MatchElement>(i), WTFMove(matchElementArray[i]) });
+        }
+        return invalidationRuleSets;
     }).iterator->value.get();
 }
 
index eece22f..fb5bad2 100644 (file)
@@ -38,6 +38,13 @@ class ExtensionStyleSheets;
 class InspectorCSSOMWrappers;
 class MediaQueryEvaluator;
 
+struct InvalidationRuleSet {
+    MatchElement matchElement;
+    std::unique_ptr<RuleSet> ruleSet;
+
+    WTF_MAKE_FAST_ALLOCATED;
+};
+
 class DocumentRuleSets {
 public:
     DocumentRuleSets(StyleResolver&);
@@ -50,8 +57,8 @@ public:
     const RuleFeatureSet& features() const;
     RuleSet* sibling() const { return m_siblingRuleSet.get(); }
     RuleSet* uncommonAttribute() const { return m_uncommonAttributeRuleSet.get(); }
-    RuleSet* subjectClassRules(const AtomicString& className) const;
-    RuleSet* ancestorClassRules(const AtomicString& className) const;
+
+    const Vector<InvalidationRuleSet>* classInvalidationRuleSets(const AtomicString& className) const;
 
     struct AttributeRules {
         WTF_MAKE_FAST_ALLOCATED;
@@ -91,8 +98,7 @@ private:
     mutable unsigned m_userAgentMediaQueryRuleCountOnUpdate { 0 };
     mutable std::unique_ptr<RuleSet> m_siblingRuleSet;
     mutable std::unique_ptr<RuleSet> m_uncommonAttributeRuleSet;
-    mutable HashMap<AtomicString, std::unique_ptr<RuleSet>> m_subjectClassRuleSets;
-    mutable HashMap<AtomicString, std::unique_ptr<RuleSet>> m_ancestorClassRuleSets;
+    mutable HashMap<AtomicString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_classInvalidationRuleSets;
     mutable HashMap<AtomicString, std::unique_ptr<AttributeRules>> m_ancestorAttributeRuleSetsForHTML;
 };
 
index 99ab5f7..05ebcad 100644 (file)
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-RuleFeatureSet::MatchElement RuleFeatureSet::computeNextMatchElement(MatchElement matchElement, CSSSelector::RelationType relation)
+MatchElement RuleFeatureSet::computeNextMatchElement(MatchElement matchElement, CSSSelector::RelationType relation)
 {
     if (matchElement == MatchElement::Subject || matchElement == MatchElement::IndirectSibling || matchElement == MatchElement::DirectSibling) {
         switch (relation) {
@@ -69,7 +69,7 @@ RuleFeatureSet::MatchElement RuleFeatureSet::computeNextMatchElement(MatchElemen
     return matchElement;
 };
 
-RuleFeatureSet::MatchElement RuleFeatureSet::computeSubSelectorMatchElement(MatchElement matchElement, const CSSSelector& selector)
+MatchElement RuleFeatureSet::computeSubSelectorMatchElement(MatchElement matchElement, const CSSSelector& selector)
 {
     ASSERT(selector.selectorList());
 
@@ -157,28 +157,12 @@ void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
         siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
     if (ruleData.containsUncommonAttributeSelector())
         uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
-    for (auto& classNameAndMatchElement : selectorFeatures.classes) {
-        auto& className = classNameAndMatchElement.first;
-        switch (classNameAndMatchElement.second) {
-        case MatchElement::Subject:
-            subjectClassRules.ensure(className, [] {
-                return std::make_unique<Vector<RuleFeature>>();
-            }).iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
-            break;
-        case MatchElement::Parent:
-        case MatchElement::Ancestor:
-            ancestorClassRules.ensure(className, [] {
-                return std::make_unique<Vector<RuleFeature>>();
-            }).iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex()));
-            break;
-        case MatchElement::DirectSibling:
-        case MatchElement::IndirectSibling:
-        case MatchElement::ParentSibling:
-        case MatchElement::AncestorSibling:
-        case MatchElement::Host:
-            otherClassesInRules.add(className);
-            break;
-        };
+    for (auto& nameAndMatch : selectorFeatures.classes) {
+        classRules.ensure(nameAndMatch.first, [] {
+            return std::make_unique<Vector<RuleFeature>>();
+        }).iterator->value->append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), nameAndMatch.second));
+        if (nameAndMatch.second == MatchElement::Host)
+            classesAffectingHost.add(nameAndMatch.first);
     }
     for (auto* selector : selectorFeatures.attributeSelectorsMatchingAncestors) {
         // Hashing by attributeCanonicalLocalName makes this HTML specific.
@@ -196,21 +180,16 @@ void RuleFeatureSet::add(const RuleFeatureSet& other)
 {
     idsInRules.add(other.idsInRules.begin(), other.idsInRules.end());
     idsMatchingAncestorsInRules.add(other.idsMatchingAncestorsInRules.begin(), other.idsMatchingAncestorsInRules.end());
-    otherClassesInRules.add(other.otherClassesInRules.begin(), other.otherClassesInRules.end());
     attributeCanonicalLocalNamesInRules.add(other.attributeCanonicalLocalNamesInRules.begin(), other.attributeCanonicalLocalNamesInRules.end());
     attributeLocalNamesInRules.add(other.attributeLocalNamesInRules.begin(), other.attributeLocalNamesInRules.end());
     siblingRules.appendVector(other.siblingRules);
     uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
-    for (auto& keyValuePair : other.ancestorClassRules) {
-        ancestorClassRules.ensure(keyValuePair.key, [] {
-            return std::make_unique<Vector<RuleFeature>>();
-        }).iterator->value->appendVector(*keyValuePair.value);
-    }
-    for (auto& keyValuePair : other.subjectClassRules) {
-        subjectClassRules.ensure(keyValuePair.key, [] {
+    for (auto& keyValuePair : other.classRules) {
+        classRules.ensure(keyValuePair.key, [] {
             return std::make_unique<Vector<RuleFeature>>();
         }).iterator->value->appendVector(*keyValuePair.value);
     }
+    classesAffectingHost.add(other.classesAffectingHost.begin(), other.classesAffectingHost.end());
 
     for (auto& keyValuePair : other.ancestorAttributeRulesForHTML) {
         auto addResult = ancestorAttributeRulesForHTML.ensure(keyValuePair.key, [] {
@@ -229,13 +208,12 @@ void RuleFeatureSet::clear()
 {
     idsInRules.clear();
     idsMatchingAncestorsInRules.clear();
-    otherClassesInRules.clear();
     attributeCanonicalLocalNamesInRules.clear();
     attributeLocalNamesInRules.clear();
     siblingRules.clear();
     uncommonAttributeRules.clear();
-    ancestorClassRules.clear();
-    subjectClassRules.clear();
+    classRules.clear();
+    classesAffectingHost.clear();
     ancestorAttributeRulesForHTML.clear();
     usesFirstLineRules = false;
     usesFirstLetterRules = false;
@@ -245,9 +223,7 @@ void RuleFeatureSet::shrinkToFit()
 {
     siblingRules.shrinkToFit();
     uncommonAttributeRules.shrinkToFit();
-    for (auto& rules : ancestorClassRules.values())
-        rules->shrinkToFit();
-    for (auto& rules : subjectClassRules.values())
+    for (auto& rules : classRules.values())
         rules->shrinkToFit();
     for (auto& rules : ancestorAttributeRulesForHTML.values())
         rules->features.shrinkToFit();
index a4ff079..bac341c 100644 (file)
@@ -33,14 +33,19 @@ namespace WebCore {
 class RuleData;
 class StyleRule;
 
+enum class MatchElement { Subject, Parent, Ancestor, DirectSibling, IndirectSibling, ParentSibling, AncestorSibling, Host };
+constexpr unsigned matchElementCount = static_cast<unsigned>(MatchElement::Host) + 1;
+
 struct RuleFeature {
-    RuleFeature(StyleRule* rule, unsigned selectorIndex)
+    RuleFeature(StyleRule* rule, unsigned selectorIndex, std::optional<MatchElement> matchElement = std::nullopt)
         : rule(rule)
         , selectorIndex(selectorIndex)
+        , matchElement(matchElement)
     {
     }
     StyleRule* rule;
     unsigned selectorIndex;
+    std::optional<MatchElement> matchElement;
 };
 
 struct RuleFeatureSet {
@@ -55,9 +60,9 @@ struct RuleFeatureSet {
     HashSet<AtomicString> attributeLocalNamesInRules;
     Vector<RuleFeature> siblingRules;
     Vector<RuleFeature> uncommonAttributeRules;
-    HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> ancestorClassRules;
-    HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> subjectClassRules;
-    HashSet<AtomicString> otherClassesInRules;
+    
+    HashMap<AtomicString, std::unique_ptr<Vector<RuleFeature>>> classRules;
+    HashSet<AtomicString> classesAffectingHost;
 
     struct AttributeRules {
         WTF_MAKE_FAST_ALLOCATED;
@@ -71,8 +76,6 @@ struct RuleFeatureSet {
     bool usesFirstLetterRules { false };
 
 private:
-    enum class MatchElement { Subject, Parent, Ancestor, DirectSibling, IndirectSibling, ParentSibling, AncestorSibling, Host };
-
     static MatchElement computeNextMatchElement(MatchElement, CSSSelector::RelationType);
     static MatchElement computeSubSelectorMatchElement(MatchElement, const CSSSelector&);
 
index 5d11a3b..ed7827a 100644 (file)
@@ -89,26 +89,13 @@ void ClassChangeInvalidation::computeInvalidation(const SpaceSplitString& oldCla
 
     bool shouldInvalidateCurrent = false;
     bool mayAffectStyleInShadowTree = false;
-    ClassChangeVector classesAffectingDescendant;
-    ClassChangeVector classesAffectingCurrent;
 
     traverseRuleFeatures(m_element, [&] (const RuleFeatureSet& features, bool mayAffectShadowTree) {
         for (auto* changedClass : changedClasses) {
-            bool mayAffectStyle = false;
-            if (features.otherClassesInRules.contains(changedClass)) {
-                shouldInvalidateCurrent = true;
-                mayAffectStyle = true;
-            }
-            if (features.ancestorClassRules.contains(changedClass)) {
-                classesAffectingDescendant.append(changedClass);
-                mayAffectStyle = true;
-            }
-            if (features.subjectClassRules.contains(changedClass)) {
-                classesAffectingCurrent.append(changedClass);
-                mayAffectStyle = true;
-            }
-            if (mayAffectStyle && mayAffectShadowTree)
+            if (mayAffectShadowTree && features.classRules.contains(changedClass))
                 mayAffectStyleInShadowTree = true;
+            if (features.classesAffectingHost.contains(changedClass))
+                shouldInvalidateCurrent = true;
         }
     });
 
@@ -118,31 +105,24 @@ void ClassChangeInvalidation::computeInvalidation(const SpaceSplitString& oldCla
         return;
     }
 
+    if (shouldInvalidateCurrent)
+        m_element.invalidateStyle();
+
     auto& ruleSets = m_element.styleResolver().ruleSets();
 
-    if (childrenOfType<Element>(m_element).first()) {
-        for (auto* changedClass : classesAffectingDescendant) {
-            if (auto* rules = ruleSets.ancestorClassRules(changedClass))
-                m_invalidationRuleSets.append(rules);
+    for (auto* changedClass : changedClasses) {
+        if (auto* invalidationRuleSets = ruleSets.classInvalidationRuleSets(changedClass)) {
+            for (auto& invalidationRuleSet : *invalidationRuleSets)
+                m_invalidationRuleSets.append(&invalidationRuleSet);
         }
     }
-
-    if (shouldInvalidateCurrent) {
-        m_element.invalidateStyle();
-        return;
-    }
-
-    for (auto* changedClass : classesAffectingCurrent) {
-        if (auto* rules = ruleSets.subjectClassRules(changedClass))
-            m_invalidationRuleSets.append(rules);
-    }
 }
 
 void ClassChangeInvalidation::invalidateStyleWithRuleSets()
 {
-    for (auto* rules : m_invalidationRuleSets) {
-        Invalidator invalidator(*rules);
-        invalidator.invalidateStyle(m_element);
+    for (auto* invalidationRuleSet : m_invalidationRuleSets) {
+        Invalidator invalidator(*invalidationRuleSet->ruleSet);
+        invalidator.invalidateStyleWithMatchElement(m_element, invalidationRuleSet->matchElement);
     }
 }
 
index c1c474e..9078808 100644 (file)
@@ -33,6 +33,7 @@ namespace WebCore {
 class DocumentRuleSets;
 class RuleSet;
 class SpaceSplitString;
+struct InvalidationRuleSet;
 
 namespace Style {
 
@@ -48,7 +49,7 @@ private:
     const bool m_isEnabled;
     Element& m_element;
 
-    Vector<const RuleSet*, 4> m_invalidationRuleSets;
+    Vector<const InvalidationRuleSet*, 4> m_invalidationRuleSets;
 };
 
 inline ClassChangeInvalidation::ClassChangeInvalidation(Element& element, const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
index 31432ba..0846dd4 100644 (file)
@@ -143,7 +143,11 @@ void Invalidator::invalidateStyleForTree(Element& root, SelectorFilter* filter)
 {
     if (invalidateIfNeeded(root, filter) == CheckDescendants::No)
         return;
+    invalidateStyleForDescendants(root, filter);
+}
 
+void Invalidator::invalidateStyleForDescendants(Element& root, SelectorFilter* filter)
+{
     Vector<Element*, 20> parentStack;
     Element* previousElement = &root;
     auto descendants = descendantsOfType<Element>(root);
@@ -205,5 +209,35 @@ void Invalidator::invalidateStyle(Element& element)
     invalidateStyleForTree(element, nullptr);
 }
 
+void Invalidator::invalidateStyleWithMatchElement(Element& element, MatchElement matchElement)
+{
+    switch (matchElement) {
+    case MatchElement::Subject: {
+        invalidateIfNeeded(element, nullptr);
+        break;
+    }
+    case MatchElement::Parent: {
+        auto children = childrenOfType<Element>(element);
+        for (auto& child : children)
+            invalidateIfNeeded(child, nullptr);
+        break;
+    }
+    case MatchElement::Ancestor: {
+        invalidateStyleForDescendants(element, nullptr);
+        break;
+    }
+    case MatchElement::DirectSibling:
+    case MatchElement::IndirectSibling:
+    case MatchElement::ParentSibling:
+    case MatchElement::AncestorSibling:
+        // FIXME: Currently sibling invalidation happens during style resolution tree walk. It should be done here too.
+        element.invalidateStyle();
+        break;
+    case MatchElement::Host:
+        // FIXME: Handle this here as well.
+        break;
+    }
+}
+
 }
 }
index 7ec5ea0..6468e85 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "RuleFeature.h"
 #include <wtf/Forward.h>
 
 namespace WebCore {
@@ -49,11 +50,13 @@ public:
     void invalidateStyle(Document&);
     void invalidateStyle(ShadowRoot&);
     void invalidateStyle(Element&);
+    void invalidateStyleWithMatchElement(Element&, MatchElement);
 
 private:
     enum class CheckDescendants { Yes, No };
     CheckDescendants invalidateIfNeeded(Element&, const SelectorFilter*);
     void invalidateStyleForTree(Element&, SelectorFilter*);
+    void invalidateStyleForDescendants(Element&, SelectorFilter*);
 
     std::unique_ptr<RuleSet> m_ownedRuleSet;
     const RuleSet& m_ruleSet;
index af3c761..d8e8224 100644 (file)
@@ -340,13 +340,8 @@ bool SharingResolver::sharingCandidateHasIdenticalStyleAffectingAttributes(const
 bool SharingResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const
 {
     for (unsigned i = 0; i < classNames.size(); ++i) {
-        if (m_ruleSets.features().otherClassesInRules.contains(classNames[i]))
+        if (m_ruleSets.features().classRules.contains(classNames[i]))
             return true;
-        if (m_ruleSets.features().ancestorClassRules.contains(classNames[i]))
-            return true;
-        if (m_ruleSets.features().subjectClassRules.contains(classNames[i]))
-            return true;
-
     }
     return false;
 }