⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 203211 in webkit


Ignore:
Timestamp:
Jul 13, 2016, 8:45:13 PM (10 years ago)
Author:
benjamin@webkit.org
Message:

[CSS][ARMv7] :nth-child() do not reserve enough registers if it is in backtracking chain
https://bugs.webkit.org/show_bug.cgi?id=159746
rdar://problem/26156169

Reviewed by Andreas Kling.

The generator generateElementIsNthChild() requires 6 registers in style resolution
to mark previous siblings with generateAddStyleRelationIfResolvingStyle() in the loop.

We were only reserving 5, which is a problem is the sixth is taken by the backtracking
register. x86_64 was already requiring 6 for unrelated reasons and ARM64 has so many registers
that you cannot possibly run out of them in CSS JIT.

I generalized the x86_64 path to all architectures.
I did not limit this case to style resolution because the extra register is irrelevant
in most cases. The only difference is one extra push/pop on ARMv7 if you use querySelector
with :nth-child in a backtracking chain.

This problem is covered by the existing test fast/selectors/nth-child-with-backtracking.html

  • cssjit/SelectorCompiler.cpp:

(WebCore::SelectorCompiler::minimumRegisterRequirements): Deleted.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r203210 r203211  
     12016-07-13  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        [CSS][ARMv7] :nth-child() do not reserve enough registers if it is in backtracking chain
     4        https://bugs.webkit.org/show_bug.cgi?id=159746
     5        rdar://problem/26156169
     6
     7        Reviewed by Andreas Kling.
     8
     9        The generator generateElementIsNthChild() requires 6 registers in style resolution
     10        to mark previous siblings with generateAddStyleRelationIfResolvingStyle() in the loop.
     11
     12        We were only reserving 5, which is a problem is the sixth is taken by the backtracking
     13        register. x86_64 was already requiring 6 for unrelated reasons and ARM64 has so many registers
     14        that you cannot possibly run out of them in CSS JIT.
     15
     16        I generalized the x86_64 path to all architectures.
     17        I did not limit this case to style resolution because the extra register is irrelevant
     18        in most cases. The only difference is one extra push/pop on ARMv7 if you use querySelector
     19        with :nth-child in a backtracking chain.
     20
     21        This problem is covered by the existing test fast/selectors/nth-child-with-backtracking.html
     22
     23        * cssjit/SelectorCompiler.cpp:
     24        (WebCore::SelectorCompiler::minimumRegisterRequirements): Deleted.
     25
    1262016-07-13  Chris Dumez  <cdumez@apple.com>
    227
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r202358 r203211  
    10671067// Element + ElementData + scratchRegister + attributeArrayPointer + expectedLocalName + (qualifiedNameImpl && expectedValue).
    10681068static const unsigned minimumRequiredRegisterCountForAttributeFilter = 6;
    1069 #if CPU(X86_64)
    1070 // Element + SiblingCounter + SiblingCounterCopy + divisor + dividend + remainder.
     1069// On x86, we always need 6 registers: Element + SiblingCounter + SiblingCounterCopy + divisor + dividend + remainder.
     1070// On other architectures, we need 6 registers for style resolution:
     1071//     Element + elementCounter + previousSibling + checkingContext + lastRelation + nextSiblingElement.
    10711072static const unsigned minimumRequiredRegisterCountForNthChildFilter = 6;
    1072 #endif
    10731073
    10741074static unsigned minimumRegisterRequirements(const SelectorFragment& selectorFragment)
     
    10941094    }
    10951095
    1096 #if CPU(X86_64)
    10971096    if (!selectorFragment.nthChildFilters.isEmpty() || !selectorFragment.nthChildOfFilters.isEmpty() || !selectorFragment.nthLastChildFilters.isEmpty() || !selectorFragment.nthLastChildOfFilters.isEmpty())
    10981097        minimum = std::max(minimum, minimumRequiredRegisterCountForNthChildFilter);
    1099 #endif
    11001098
    11011099    // :any pseudo class filters cause some register pressure.
Note: See TracChangeset for help on using the changeset viewer.