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

Changeset 266689 in webkit


Ignore:
Timestamp:
Sep 6, 2020, 5:59:52 PM (6 years ago)
Author:
Wenson Hsieh
Message:

[MotionMark - Multiply] Web process spends ~1% of total samples in PropertyCascade::resolveDirectionAndWritingMode
https://bugs.webkit.org/show_bug.cgi?id=216223

Reviewed by Darin Adler.

A few subtests in MotionMark (Leaves, Focus, Design, and especially Multiply) spend large amounts of time in
style resolution (Document::resolveStyle) due to constant style changes across many elements during every
frame. In Multiply, ~3-4% of the time underneath Document::resolveStyle is spent resolving direction and
writing modes inside PropertyCascade::resolveDirectionAndWritingMode (i.e., ~2.3 million invocations). This
helper function is responsible for computing the text direction and CSS writing mode that is used to resolve
direction-aware CSS properties (which are enumerated in CSSProperty::isDirectionAwareProperty). Resolving the
direction and writing mode involves iterating over all of the matched CSS properties (m_matchResult) in the
property cascade in search of CSS properties for writing and direction, which can be relatively expensive when
there are lots of properties in the cascade.

However, if there are no direction-aware CSS properties in the cascade, this work can actually be elided; to
achieve this, we can store the inherited Direction in m_direction, and then lazily resolve it if needed.

I measured this locally to yield a little under ~1% in the Multiply subtest in MotionMark. Otherwise, there is
no change in behavior; see below for more details.

  • style/PropertyCascade.cpp:

(WebCore::Style::PropertyCascade::PropertyCascade):
(WebCore::Style::PropertyCascade::set):

If we encounter a direction-aware CSS property, then use direction() to ensure that the direction and writing
mode are resolved.

(WebCore::Style::PropertyCascade::direction const):

Make this getter call resolveDirectionAndWritingMode if needed.

  • style/PropertyCascade.h:

Add a new bool member to keep track of whether or not the CSS direction has not yet been resolved. Note that
since this member variable fits within the padding after Direction m_direction;, this class is still the same
size.

(WebCore::Style::PropertyCascade::direction const): Deleted.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r266688 r266689  
     12020-09-06  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [MotionMark - Multiply] Web process spends ~1% of total samples in PropertyCascade::resolveDirectionAndWritingMode
     4        https://bugs.webkit.org/show_bug.cgi?id=216223
     5
     6        Reviewed by Darin Adler.
     7
     8        A few subtests in MotionMark (Leaves, Focus, Design, and especially Multiply) spend large amounts of time in
     9        style resolution (`Document::resolveStyle`) due to constant style changes across many elements during every
     10        frame. In Multiply, ~3-4% of the time underneath `Document::resolveStyle` is spent resolving direction and
     11        writing modes inside `PropertyCascade::resolveDirectionAndWritingMode` (i.e., ~2.3 million invocations). This
     12        helper function is responsible for computing the text direction and CSS writing mode that is used to resolve
     13        direction-aware CSS properties (which are enumerated in `CSSProperty::isDirectionAwareProperty`). Resolving the
     14        direction and writing mode involves iterating over all of the matched CSS properties (`m_matchResult`) in the
     15        property cascade in search of CSS properties for writing and direction, which can be relatively expensive when
     16        there are lots of properties in the cascade.
     17
     18        However, if there are no direction-aware CSS properties in the cascade, this work can actually be elided; to
     19        achieve this, we can store the inherited `Direction` in `m_direction`, and then lazily resolve it if needed.
     20
     21        I measured this locally to yield a little under ~1% in the Multiply subtest in MotionMark. Otherwise, there is
     22        no change in behavior; see below for more details.
     23
     24        * style/PropertyCascade.cpp:
     25        (WebCore::Style::PropertyCascade::PropertyCascade):
     26        (WebCore::Style::PropertyCascade::set):
     27
     28        If we encounter a direction-aware CSS property, then use `direction()` to ensure that the direction and writing
     29        mode are resolved.
     30
     31        (WebCore::Style::PropertyCascade::direction const):
     32
     33        Make this getter call `resolveDirectionAndWritingMode` if needed.
     34
     35        * style/PropertyCascade.h:
     36
     37        Add a new `bool` member to keep track of whether or not the CSS direction has not yet been resolved. Note that
     38        since this member variable fits within the padding after `Direction m_direction;`, this class is still the same
     39        size.
     40
     41        (WebCore::Style::PropertyCascade::direction const): Deleted.
     42
    1432020-09-06  Myles C. Maxfield  <mmaxfield@apple.com>
    244
  • trunk/Source/WebCore/style/PropertyCascade.cpp

    r262922 r266689  
    149149    : m_matchResult(matchResult)
    150150    , m_includedProperties(includedProperties)
    151     , m_direction(resolveDirectionAndWritingMode(direction))
     151    , m_direction(direction)
    152152{
    153153    buildCascade(cascadeLevels);
     
    157157    : m_matchResult(parent.m_matchResult)
    158158    , m_includedProperties(parent.m_includedProperties)
    159     , m_direction(parent.m_direction)
     159    , m_direction(parent.direction())
     160    , m_directionIsUnresolved(false)
    160161{
    161162    buildCascade(cascadeLevels);
     
    197198void PropertyCascade::set(CSSPropertyID id, CSSValue& cssValue, unsigned linkMatchType, CascadeLevel cascadeLevel, ScopeOrdinal styleScopeOrdinal)
    198199{
    199     if (CSSProperty::isDirectionAwareProperty(id))
    200         id = CSSProperty::resolveDirectionAwareProperty(id, m_direction.textDirection, m_direction.writingMode);
     200    if (CSSProperty::isDirectionAwareProperty(id)) {
     201        auto direction = this->direction();
     202        id = CSSProperty::resolveDirectionAwareProperty(id, direction.textDirection, direction.writingMode);
     203    }
    201204
    202205    ASSERT(!shouldApplyPropertyInParseOrder(id));
     
    405408}
    406409
    407 }
    408 }
     410PropertyCascade::Direction PropertyCascade::direction() const
     411{
     412    if (m_directionIsUnresolved) {
     413        m_direction = resolveDirectionAndWritingMode(m_direction);
     414        m_directionIsUnresolved = false;
     415    }
     416    return m_direction;
     417}
     418
     419}
     420}
  • trunk/Source/WebCore/style/PropertyCascade.h

    r252313 r266689  
    6868    const HashMap<AtomString, Property>& customProperties() const { return m_customProperties; }
    6969
    70     Direction direction() const { return m_direction; }
     70    Direction direction() const;
    7171
    7272    const PropertyCascade* propertyCascadeForRollback(CascadeLevel) const;
     
    8686    const MatchResult& m_matchResult;
    8787    const IncludedProperties m_includedProperties;
    88     const Direction m_direction;
     88    mutable Direction m_direction;
     89    mutable bool m_directionIsUnresolved { true };
    8990
    9091    Property m_properties[numCSSProperties + 2];
Note: See TracChangeset for help on using the changeset viewer.