Changeset 253971 in webkit


Ignore:
Timestamp:
Jan 1, 2020 1:22:53 PM (4 years ago)
Author:
Antti Koivisto
Message:

Make SelectorCompiler interface use CompiledSelector type
https://bugs.webkit.org/show_bug.cgi?id=205673

Reviewed by Sam Weinig.

SelectorCompiler interface is currently rather low-level, taking void* code references.
Expand use of CompiledSelector type to simplify clients.

  • cssjit/CompiledSelector.h:

(WebCore::CompiledSelector::wasUsed):

  • cssjit/SelectorCompiler.cpp:

(WebCore::SelectorCompiler::compileSelector):

Generate code directory to a CompiledSelector.

  • cssjit/SelectorCompiler.h:

(WebCore::SelectorCompiler::ruleCollectorSimpleSelectorCheckerFunction):
(WebCore::SelectorCompiler::querySelectorSimpleSelectorCheckerFunction):
(WebCore::SelectorCompiler::ruleCollectorSelectorCheckerFunctionWithCheckingContext):
(WebCore::SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext):

Take CompiledSelector.

  • dom/SelectorQuery.cpp:

(WebCore::SelectorDataList::SelectorDataList):
(WebCore::SelectorDataList::executeCompiledSimpleSelectorChecker const):
(WebCore::SelectorDataList::executeCompiledSelectorCheckerWithCheckingContext const):
(WebCore::SelectorDataList::executeCompiledSingleMultiSelectorData const):
(WebCore::SelectorDataList::compileSelector):
(WebCore::SelectorDataList::execute const):
(WebCore::isCompiledSelector): Deleted.

  • dom/SelectorQuery.h:

(WebCore::SelectorDataList::SelectorData::SelectorData): Deleted.
(WebCore::SelectorDataList::SelectorData::~SelectorData): Deleted.
(WebCore::SelectorDataList::SelectorData::compiledSelectorUsed const): Deleted.

Replace SelectorData fields with a CompiledSelector member.

  • style/ElementRuleCollector.cpp:

(WebCore::Style::ElementRuleCollector::ruleMatches):

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r253970 r253971  
     12020-01-01  Antti Koivisto  <antti@apple.com>
     2
     3        Make SelectorCompiler interface use CompiledSelector type
     4        https://bugs.webkit.org/show_bug.cgi?id=205673
     5
     6        Reviewed by Sam Weinig.
     7
     8        SelectorCompiler interface is currently rather low-level, taking void* code references.
     9        Expand use of CompiledSelector type to simplify clients.
     10
     11        * cssjit/CompiledSelector.h:
     12        (WebCore::CompiledSelector::wasUsed):
     13        * cssjit/SelectorCompiler.cpp:
     14        (WebCore::SelectorCompiler::compileSelector):
     15
     16        Generate code directory to a CompiledSelector.
     17
     18        * cssjit/SelectorCompiler.h:
     19        (WebCore::SelectorCompiler::ruleCollectorSimpleSelectorCheckerFunction):
     20        (WebCore::SelectorCompiler::querySelectorSimpleSelectorCheckerFunction):
     21        (WebCore::SelectorCompiler::ruleCollectorSelectorCheckerFunctionWithCheckingContext):
     22        (WebCore::SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext):
     23
     24        Take CompiledSelector.
     25
     26        * dom/SelectorQuery.cpp:
     27        (WebCore::SelectorDataList::SelectorDataList):
     28        (WebCore::SelectorDataList::executeCompiledSimpleSelectorChecker const):
     29        (WebCore::SelectorDataList::executeCompiledSelectorCheckerWithCheckingContext const):
     30        (WebCore::SelectorDataList::executeCompiledSingleMultiSelectorData const):
     31        (WebCore::SelectorDataList::compileSelector):
     32        (WebCore::SelectorDataList::execute const):
     33        (WebCore::isCompiledSelector): Deleted.
     34        * dom/SelectorQuery.h:
     35        (WebCore::SelectorDataList::SelectorData::SelectorData): Deleted.
     36        (WebCore::SelectorDataList::SelectorData::~SelectorData): Deleted.
     37        (WebCore::SelectorDataList::SelectorData::compiledSelectorUsed const): Deleted.
     38
     39        Replace SelectorData fields with a CompiledSelector member.
     40
     41        * style/ElementRuleCollector.cpp:
     42        (WebCore::Style::ElementRuleCollector::ruleMatches):
     43
    1442020-01-01  Zalan Bujtas  <zalan@apple.com>
    245
  • trunk/Source/WebCore/cssjit/CompiledSelector.h

    r253959 r253971  
    2929
    3030#include "CSSPtrTag.h"
     31#include "CSSSelector.h"
    3132#include <JavaScriptCore/MacroAssemblerCodeRef.h>
     33
     34#define CSS_SELECTOR_JIT_PROFILING 0
    3235
    3336namespace WebCore {
    3437
    35 enum class SelectorCompilationStatus {
     38enum class SelectorCompilationStatus : uint8_t {
    3639    NotCompiled,
    3740    CannotCompile,
     
    4447    SelectorCompilationStatus status { SelectorCompilationStatus::NotCompiled };
    4548    JSC::MacroAssemblerCodeRef<CSSSelectorPtrTag> codeRef;
     49
    4650#if defined(CSS_SELECTOR_JIT_PROFILING) && CSS_SELECTOR_JIT_PROFILING
    4751    unsigned useCount { 0 };
     52    const CSSSelector* selector { nullptr };
     53    void wasUsed() { ++useCount; }
     54
     55    ~CompiledSelector()
     56    {
     57        if (codeRef.code().executableAddress())
     58            dataLogF("CompiledSelector %d \"%s\"\n", useCount, selector->selectorText().utf8().data());
     59    }
     60#else
     61    void wasUsed() { }
    4862#endif
    4963};
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r252330 r253971  
    397397static void computeBacktrackingInformation(SelectorFragmentList& selectorFragments, unsigned level = 0);
    398398
    399 SelectorCompilationStatus compileSelector(const CSSSelector* lastSelector, SelectorContext selectorContext, JSC::MacroAssemblerCodeRef<CSSSelectorPtrTag>& codeRef)
    400 {
    401     if (!JSC::VM::canUseJIT())
    402         return SelectorCompilationStatus::CannotCompile;
    403     SelectorCodeGenerator codeGenerator(lastSelector, selectorContext);
    404     return codeGenerator.compile(codeRef);
     399void compileSelector(CompiledSelector& compiledSelector, const CSSSelector* selector, SelectorContext selectorContext)
     400{
     401    ASSERT(compiledSelector.status == SelectorCompilationStatus::NotCompiled);
     402
     403    if (!JSC::VM::canUseJIT()) {
     404        compiledSelector.status = SelectorCompilationStatus::CannotCompile;
     405        return;
     406    }
     407   
     408    SelectorCodeGenerator codeGenerator(selector, selectorContext);
     409    compiledSelector.status = codeGenerator.compile(compiledSelector.codeRef);
     410
     411#if defined(CSS_SELECTOR_JIT_PROFILING) && CSS_SELECTOR_JIT_PROFILING
     412    compiledSelector.selector = selector;
     413#endif
     414
     415    ASSERT(compiledSelector.status != SelectorCompilationStatus::NotCompiled);
    405416}
    406417
  • trunk/Source/WebCore/cssjit/SelectorCompiler.h

    r231027 r253971  
    3131#include "SelectorChecker.h"
    3232
    33 #define CSS_SELECTOR_JIT_PROFILING 0
    34 
    3533namespace WebCore {
    3634
     
    5452typedef unsigned (*QuerySelectorSelectorCheckerWithCheckingContext)(const Element*, const SelectorChecker::CheckingContext*);
    5553
    56 SelectorCompilationStatus compileSelector(const CSSSelector*, SelectorContext, JSC::MacroAssemblerCodeRef<CSSSelectorPtrTag>& outputCodeRef);
     54void compileSelector(CompiledSelector&, const CSSSelector*, SelectorContext);
    5755
    58 inline RuleCollectorSimpleSelectorChecker ruleCollectorSimpleSelectorCheckerFunction(void* executableAddress, SelectorCompilationStatus compilationStatus)
     56inline RuleCollectorSimpleSelectorChecker ruleCollectorSimpleSelectorCheckerFunction(CompiledSelector& compiledSelector)
    5957{
    60     ASSERT_UNUSED(compilationStatus, compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker);
    61     return WTF::untagCFunctionPtr<RuleCollectorSimpleSelectorChecker, CSSSelectorPtrTag>(executableAddress);
     58    ASSERT(compiledSelector.status == SelectorCompilationStatus::SimpleSelectorChecker);
     59    return WTF::untagCFunctionPtr<RuleCollectorSimpleSelectorChecker, CSSSelectorPtrTag>(compiledSelector.codeRef.code().executableAddress());
    6260}
    6361
    64 inline QuerySelectorSimpleSelectorChecker querySelectorSimpleSelectorCheckerFunction(void* executableAddress, SelectorCompilationStatus compilationStatus)
     62inline QuerySelectorSimpleSelectorChecker querySelectorSimpleSelectorCheckerFunction(CompiledSelector& compiledSelector)
    6563{
    66     ASSERT_UNUSED(compilationStatus, compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker);
    67     return WTF::untagCFunctionPtr<QuerySelectorSimpleSelectorChecker, CSSSelectorPtrTag>(executableAddress);
     64    ASSERT(compiledSelector.status == SelectorCompilationStatus::SimpleSelectorChecker);
     65    return WTF::untagCFunctionPtr<QuerySelectorSimpleSelectorChecker, CSSSelectorPtrTag>(compiledSelector.codeRef.code().executableAddress());
    6866}
    6967
    70 inline RuleCollectorSelectorCheckerWithCheckingContext ruleCollectorSelectorCheckerFunctionWithCheckingContext(void* executableAddress, SelectorCompilationStatus compilationStatus)
     68inline RuleCollectorSelectorCheckerWithCheckingContext ruleCollectorSelectorCheckerFunctionWithCheckingContext(CompiledSelector& compiledSelector)
    7169{
    72     ASSERT_UNUSED(compilationStatus, compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
    73     return WTF::untagCFunctionPtr<RuleCollectorSelectorCheckerWithCheckingContext, CSSSelectorPtrTag>(executableAddress);
     70    ASSERT(compiledSelector.status == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
     71    return WTF::untagCFunctionPtr<RuleCollectorSelectorCheckerWithCheckingContext, CSSSelectorPtrTag>(compiledSelector.codeRef.code().executableAddress());
    7472}
    7573
    76 inline QuerySelectorSelectorCheckerWithCheckingContext querySelectorSelectorCheckerFunctionWithCheckingContext(void* executableAddress, SelectorCompilationStatus compilationStatus)
     74inline QuerySelectorSelectorCheckerWithCheckingContext querySelectorSelectorCheckerFunctionWithCheckingContext(CompiledSelector& compiledSelector)
    7775{
    78     ASSERT_UNUSED(compilationStatus, compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
    79     return WTF::untagCFunctionPtr<QuerySelectorSelectorCheckerWithCheckingContext, CSSSelectorPtrTag>(executableAddress);
     76    ASSERT(compiledSelector.status == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
     77    return WTF::untagCFunctionPtr<QuerySelectorSelectorCheckerWithCheckingContext, CSSSelectorPtrTag>(compiledSelector.codeRef.code().executableAddress());
    8078}
    8179
  • trunk/Source/WebCore/dom/SelectorQuery.cpp

    r248846 r253971  
    8484    m_selectors.reserveInitialCapacity(selectorCount);
    8585    for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
    86         m_selectors.uncheckedAppend(SelectorData(selector));
     86        m_selectors.uncheckedAppend({ selector });
    8787
    8888    if (selectorCount == 1) {
     
    406406{
    407407    for (auto& element : elementDescendants(const_cast<ContainerNode&>(searchRootNode))) {
    408 #if CSS_SELECTOR_JIT_PROFILING
    409         selectorData.compiledSelectorUsed();
    410 #else
    411         UNUSED_PARAM(selectorData);
    412 #endif
     408        selectorData.compiledSelector.wasUsed();
     409
    413410        if (selectorChecker(&element)) {
    414411            SelectorQueryTrait::appendOutputForElement(output, &element);
     
    426423
    427424    for (auto& element : elementDescendants(const_cast<ContainerNode&>(searchRootNode))) {
    428 #if CSS_SELECTOR_JIT_PROFILING
    429         selectorData.compiledSelectorUsed();
    430 #else
    431         UNUSED_PARAM(selectorData);
    432 #endif
     425        selectorData.compiledSelector.wasUsed();
     426
    433427        if (selectorChecker(&element, &checkingContext)) {
    434428            SelectorQueryTrait::appendOutputForElement(output, &element);
     
    446440    for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
    447441        for (auto& selector : m_selectors) {
    448 #if CSS_SELECTOR_JIT_PROFILING
    449             selector.compiledSelectorUsed();
    450 #endif
     442            selector.compiledSelector.wasUsed();
     443
    451444            bool matched = false;
    452             void* compiledSelectorChecker = selector.compiledSelectorCodeRef.code().executableAddress();
    453             if (selector.compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker) {
    454                 auto selectorChecker = SelectorCompiler::querySelectorSimpleSelectorCheckerFunction(compiledSelectorChecker, selector.compilationStatus);
     445            if (selector.compiledSelector.status == SelectorCompilationStatus::SimpleSelectorChecker) {
     446                auto selectorChecker = SelectorCompiler::querySelectorSimpleSelectorCheckerFunction(selector.compiledSelector);
    455447                matched = selectorChecker(&element);
    456448            } else {
    457                 ASSERT(selector.compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
    458                 auto selectorChecker = SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, selector.compilationStatus);
     449                ASSERT(selector.compiledSelector.status == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
     450                auto selectorChecker = SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext(selector.compiledSelector);
    459451                matched = selectorChecker(&element, &checkingContext);
    460452            }
     
    469461}
    470462
    471 static bool isCompiledSelector(SelectorCompilationStatus compilationStatus)
    472 {
    473     return compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker || compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext;
    474 }
    475 
    476463bool SelectorDataList::compileSelector(const SelectorData& selectorData)
    477464{
    478     if (selectorData.compilationStatus != SelectorCompilationStatus::NotCompiled)
    479         return isCompiledSelector(selectorData.compilationStatus);
    480 
    481     selectorData.compilationStatus = SelectorCompiler::compileSelector(selectorData.selector, SelectorCompiler::SelectorContext::QuerySelector, selectorData.compiledSelectorCodeRef);
    482     return isCompiledSelector(selectorData.compilationStatus);
    483 }
    484 
     465    auto& compiledSelector = selectorData.compiledSelector;
     466   
     467    if (compiledSelector.status == SelectorCompilationStatus::NotCompiled)
     468        SelectorCompiler::compileSelector(compiledSelector, selectorData.selector, SelectorCompiler::SelectorContext::QuerySelector);
     469
     470    return compiledSelector.status != SelectorCompilationStatus::CannotCompile;
     471}
    485472
    486473#endif // ENABLE(CSS_SELECTOR_JIT)
     
    511498#if ENABLE(CSS_SELECTOR_JIT)
    512499        const SelectorData& selectorData = m_selectors.first();
    513         ASSERT(selectorData.compilationStatus == SelectorCompilationStatus::NotCompiled);
     500        ASSERT(selectorData.compiledSelector.status == SelectorCompilationStatus::NotCompiled);
    514501        ASSERT(m_matchType == CompilableSingle || m_matchType == CompilableSingleWithRootFilter);
    515502        if (compileSelector(selectorData)) {
     
    542529        CompiledSingleCase:
    543530        const SelectorData& selectorData = m_selectors.first();
    544         void* compiledSelectorChecker = selectorData.compiledSelectorCodeRef.code().executableAddress();
    545         if (selectorData.compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker) {
    546             SelectorCompiler::QuerySelectorSimpleSelectorChecker selectorChecker = SelectorCompiler::querySelectorSimpleSelectorCheckerFunction(compiledSelectorChecker, selectorData.compilationStatus);
     531        if (selectorData.compiledSelector.status == SelectorCompilationStatus::SimpleSelectorChecker) {
     532            auto selectorChecker = SelectorCompiler::querySelectorSimpleSelectorCheckerFunction(selectorData.compiledSelector);
    547533            executeCompiledSimpleSelectorChecker<SelectorQueryTrait>(*searchRootNode, selectorChecker, output, selectorData);
    548534        } else {
    549             ASSERT(selectorData.compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
    550             SelectorCompiler::QuerySelectorSelectorCheckerWithCheckingContext selectorChecker = SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, selectorData.compilationStatus);
     535            ASSERT(selectorData.compiledSelector.status == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
     536            auto selectorChecker = SelectorCompiler::querySelectorSelectorCheckerFunctionWithCheckingContext(selectorData.compiledSelector);
    551537            executeCompiledSelectorCheckerWithCheckingContext<SelectorQueryTrait>(rootNode, *searchRootNode, selectorChecker, output, selectorData);
    552538        }
  • trunk/Source/WebCore/dom/SelectorQuery.h

    r253959 r253971  
    5151private:
    5252    struct SelectorData {
    53         SelectorData(const CSSSelector* selector)
    54             : selector(selector)
    55         {
    56         }
    57 
    5853        const CSSSelector* selector;
    5954#if ENABLE(CSS_SELECTOR_JIT)
    60         mutable JSC::MacroAssemblerCodeRef<CSSSelectorPtrTag> compiledSelectorCodeRef;
    61         mutable SelectorCompilationStatus compilationStatus { SelectorCompilationStatus::NotCompiled };
    62 #if CSS_SELECTOR_JIT_PROFILING
    63         ~SelectorData()
    64         {
    65             if (compiledSelectorCodeRef.code().executableAddress())
    66                 dataLogF("SelectorData compiled selector %d \"%s\"\n", m_compiledSelectorUseCount, selector->selectorText().utf8().data());
    67         }
    68         mutable unsigned m_compiledSelectorUseCount { 0 };
    69         void compiledSelectorUsed() const { m_compiledSelectorUseCount++; }
     55        mutable CompiledSelector compiledSelector { };
    7056#endif
    71 #endif // ENABLE(CSS_SELECTOR_JIT)
    7257    };
    7358
  • trunk/Source/WebCore/style/ElementRuleCollector.cpp

    r253959 r253971  
    450450#if ENABLE(CSS_SELECTOR_JIT)
    451451    auto& compiledSelector = ruleData.compiledSelector();
    452     void* compiledSelectorChecker = compiledSelector.codeRef.code().executableAddress();
    453     if (!compiledSelectorChecker && compiledSelector.status == SelectorCompilationStatus::NotCompiled) {
    454         compiledSelector.status = SelectorCompiler::compileSelector(ruleData.selector(), SelectorCompiler::SelectorContext::RuleCollector, compiledSelector.codeRef);
    455 
    456         compiledSelectorChecker = compiledSelector.codeRef.code().executableAddress();
    457     }
    458 
    459     if (compiledSelectorChecker && compiledSelector.status == SelectorCompilationStatus::SimpleSelectorChecker) {
    460         auto selectorChecker = SelectorCompiler::ruleCollectorSimpleSelectorCheckerFunction(compiledSelectorChecker, compiledSelector.status);
     452
     453    if (compiledSelector.status == SelectorCompilationStatus::NotCompiled)
     454        SelectorCompiler::compileSelector(compiledSelector, ruleData.selector(), SelectorCompiler::SelectorContext::RuleCollector);
     455
     456    if (compiledSelector.status == SelectorCompilationStatus::SimpleSelectorChecker) {
     457        compiledSelector.wasUsed();
     458
     459        auto selectorChecker = SelectorCompiler::ruleCollectorSimpleSelectorCheckerFunction(compiledSelector);
    461460#if !ASSERT_MSG_DISABLED
    462461        unsigned ignoreSpecificity;
    463462        ASSERT_WITH_MESSAGE(!selectorChecker(&element(), &ignoreSpecificity) || m_pseudoElementRequest.pseudoId == PseudoId::None, "When matching pseudo elements, we should never compile a selector checker without context unless it cannot match anything.");
    464 #endif
    465 #if CSS_SELECTOR_JIT_PROFILING
    466         ruleData.compiledSelectorUsed();
    467463#endif
    468464        bool selectorMatches = selectorChecker(&element(), &specificity);
     
    484480    bool selectorMatches;
    485481#if ENABLE(CSS_SELECTOR_JIT)
    486     if (compiledSelectorChecker) {
    487         ASSERT(compiledSelector.status == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
    488 
    489         auto selectorChecker = SelectorCompiler::ruleCollectorSelectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, compiledSelector.status);
    490 
    491 #if CSS_SELECTOR_JIT_PROFILING
    492         compiledSelector.useCount++;
    493 #endif
     482    if (compiledSelector.status == SelectorCompilationStatus::SelectorCheckerWithCheckingContext) {
     483        compiledSelector.wasUsed();
     484
     485        auto selectorChecker = SelectorCompiler::ruleCollectorSelectorCheckerFunctionWithCheckingContext(compiledSelector);
    494486        selectorMatches = selectorChecker(&element(), &context, &specificity);
    495487    } else
Note: See TracChangeset for help on using the changeset viewer.