Changeset 98542 in webkit


Ignore:
Timestamp:
Oct 27, 2011 2:39:48 AM (12 years ago)
Author:
Antti Koivisto
Message:

Matched declaration cache
https://bugs.webkit.org/show_bug.cgi?id=70931

Reviewed by Darin Adler.

Sets of style declarations are applied repeatedly for different elements when calculating the document style.
The same set of applied declarations results in the same non-inherited style, independent of the element and
its context. We can use this to build a cache to speed up style applying and to share more style data for
reduced memory usage.

The patch reduces RenderStyle memory use ~40% and total memory use by ~7% over HTML5 spec load.
It is also ~10% progression in PerformanceTests/Parser/html5-full-render.html.

  • css/CSSProperty.cpp:

(WebCore::CSSProperty::isInheritedProperty):

  • css/CSSProperty.h:

(WebCore::CSSProperty::CSSProperty):
(WebCore::CSSProperty::isInherited):

We need to know which properties are inherited, something we didn't have available so far.


  • css/CSSStyleSelector.cpp:

(WebCore::CSSStyleSelector::matchAllRules):

A set of declarations is only cacheable if it contains no element specific style. This way we
don't need to worry about cache invalidation. The whole style selector is reconstructed if the
stylesheets change, invalidating the cache too.


(WebCore::CSSStyleSelector::styleForElement):

Trigger image loads bit earlier so cached style will have them too.


(WebCore::CSSStyleSelector::applyDeclaration):
(WebCore::CSSStyleSelector::applyDeclarations):

Allow skipping over non-inherited properties.


(WebCore::CSSStyleSelector::computeDeclarationHash):

Hash function for declartion cache lookups.


(WebCore::operator==):
(WebCore::operator!=):
(WebCore::CSSStyleSelector::findFromMatchedDeclarationCache):

Lookup from cache.


(WebCore::CSSStyleSelector::addToMatchedDeclarationCache):

Add to cache.


(WebCore::CSSStyleSelector::applyMatchedDeclarations):

If cached style is found, copy the non-inherited properties from the cache and apply the inherited properties (if any) only.


Font and zoom changes force full applying as they can affect values of other properties (this can be relaxed later).


  • css/CSSStyleSelector.h:

(WebCore::CSSStyleSelector::MatchResult::MatchResult):

Cacheability bit.


  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::copyNonInheritedFrom):

  • rendering/style/RenderStyle.h:
  • rendering/style/SVGRenderStyle.cpp:

(WebCore::SVGRenderStyle::copyNonInheritedFrom):

  • rendering/style/SVGRenderStyle.h:


Functions for assembling RenderStyle from non-inherited parts of the cached style.

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r98541 r98542  
     12011-10-27  Antti Koivisto  <antti@apple.com>
     2
     3        Matched declaration cache
     4        https://bugs.webkit.org/show_bug.cgi?id=70931
     5
     6        Reviewed by Darin Adler.
     7
     8        Sets of style declarations are applied repeatedly for different elements when calculating the document style.
     9        The same set of applied declarations results in the same non-inherited style, independent of the element and
     10        its context. We can use this to build a cache to speed up style applying and to share more style data for
     11        reduced memory usage.
     12       
     13        The patch reduces RenderStyle memory use ~40% and total memory use by ~7% over HTML5 spec load.
     14        It is also ~10% progression in PerformanceTests/Parser/html5-full-render.html.
     15
     16        * css/CSSProperty.cpp:
     17        (WebCore::CSSProperty::isInheritedProperty):
     18        * css/CSSProperty.h:
     19        (WebCore::CSSProperty::CSSProperty):
     20        (WebCore::CSSProperty::isInherited):
     21       
     22            We need to know which properties are inherited, something we didn't have available so far.
     23       
     24        * css/CSSStyleSelector.cpp:
     25        (WebCore::CSSStyleSelector::matchAllRules):
     26       
     27            A set of declarations is only cacheable if it contains no element specific style. This way we
     28            don't need to worry about cache invalidation. The whole style selector is reconstructed if the
     29            stylesheets change, invalidating the cache too.
     30   
     31        (WebCore::CSSStyleSelector::styleForElement):
     32       
     33            Trigger image loads bit earlier so cached style will have them too.
     34       
     35        (WebCore::CSSStyleSelector::applyDeclaration):
     36        (WebCore::CSSStyleSelector::applyDeclarations):
     37       
     38            Allow skipping over non-inherited properties.
     39       
     40        (WebCore::CSSStyleSelector::computeDeclarationHash):
     41       
     42            Hash function for declartion cache lookups.
     43       
     44        (WebCore::operator==):
     45        (WebCore::operator!=):
     46        (WebCore::CSSStyleSelector::findFromMatchedDeclarationCache):
     47       
     48            Lookup from cache.
     49       
     50        (WebCore::CSSStyleSelector::addToMatchedDeclarationCache):
     51       
     52            Add to cache.
     53       
     54        (WebCore::CSSStyleSelector::applyMatchedDeclarations):
     55       
     56            If cached style is found, copy the non-inherited properties from the cache and apply the inherited properties (if any) only.
     57       
     58            Font and zoom changes force full applying as they can affect values of other properties (this can be relaxed later).
     59       
     60        * css/CSSStyleSelector.h:
     61        (WebCore::CSSStyleSelector::MatchResult::MatchResult):
     62       
     63            Cacheability bit.
     64       
     65        * rendering/style/RenderStyle.cpp:
     66        (WebCore::RenderStyle::copyNonInheritedFrom):
     67        * rendering/style/RenderStyle.h:
     68        * rendering/style/SVGRenderStyle.cpp:
     69        (WebCore::SVGRenderStyle::copyNonInheritedFrom):
     70        * rendering/style/SVGRenderStyle.h:
     71       
     72            Functions for assembling RenderStyle from non-inherited parts of the cached style.
     73
    1742011-10-27  Andrey Kosyakov  <caseq@chromium.org>
    275
  • trunk/Source/WebCore/css/CSSProperty.cpp

    r97854 r98542  
    283283}
    284284
     285bool CSSProperty::isInheritedProperty(unsigned propertyID)
     286{
     287    switch (static_cast<CSSPropertyID>(propertyID)) {
     288    case CSSPropertyBorderCollapse:
     289    case CSSPropertyBorderSpacing:
     290    case CSSPropertyCaptionSide:
     291    case CSSPropertyColor:
     292    case CSSPropertyCursor:
     293    case CSSPropertyDirection:
     294    case CSSPropertyEmptyCells:
     295    case CSSPropertyFont:
     296    case CSSPropertyFontFamily:
     297    case CSSPropertyFontSize:
     298    case CSSPropertyFontStyle:
     299    case CSSPropertyFontVariant:
     300    case CSSPropertyFontWeight:
     301    case CSSPropertyImageRendering:
     302    case CSSPropertyLetterSpacing:
     303    case CSSPropertyLineHeight:
     304    case CSSPropertyListStyle:
     305    case CSSPropertyListStyleImage:
     306    case CSSPropertyListStyleType:
     307    case CSSPropertyListStylePosition:
     308    case CSSPropertyOrphans:
     309    case CSSPropertyPointerEvents:
     310    case CSSPropertyQuotes:
     311    case CSSPropertyResize:
     312    case CSSPropertySpeak:
     313    case CSSPropertyTextAlign:
     314    case CSSPropertyTextDecoration:
     315    case CSSPropertyTextIndent:
     316    case CSSPropertyTextRendering:
     317    case CSSPropertyTextShadow:
     318    case CSSPropertyTextTransform:
     319    case CSSPropertyVisibility:
     320    case CSSPropertyWebkitBorderHorizontalSpacing:
     321    case CSSPropertyWebkitBorderVerticalSpacing:
     322    case CSSPropertyWebkitBoxDirection:
     323    case CSSPropertyWebkitColorCorrection:
     324    case CSSPropertyWebkitLocale:
     325    case CSSPropertyWebkitHighlight:
     326    case CSSPropertyWebkitHyphenateCharacter:
     327    case CSSPropertyWebkitHyphenateLimitAfter:
     328    case CSSPropertyWebkitHyphenateLimitBefore:
     329    case CSSPropertyWebkitHyphenateLimitLines:
     330    case CSSPropertyWebkitHyphens:
     331    case CSSPropertyWebkitLineBoxContain:
     332    case CSSPropertyWebkitLineBreak:
     333    case CSSPropertyWebkitNbspMode:
     334    case CSSPropertyWebkitRtlOrdering:
     335    case CSSPropertyWebkitTextCombine:
     336    case CSSPropertyWebkitTextDecorationsInEffect:
     337    case CSSPropertyWebkitTextEmphasis:
     338    case CSSPropertyWebkitTextEmphasisColor:
     339    case CSSPropertyWebkitTextEmphasisPosition:
     340    case CSSPropertyWebkitTextEmphasisStyle:
     341    case CSSPropertyWebkitTextFillColor:
     342    case CSSPropertyWebkitTextSecurity:
     343    case CSSPropertyWebkitTextSizeAdjust:
     344    case CSSPropertyWebkitTextStroke:
     345    case CSSPropertyWebkitTextStrokeColor:
     346    case CSSPropertyWebkitTextStrokeWidth:
     347    case CSSPropertyWebkitUserModify:
     348    case CSSPropertyWebkitUserSelect:
     349    case CSSPropertyWebkitWritingMode:
     350    case CSSPropertyWhiteSpace:
     351    case CSSPropertyWidows:
     352    case CSSPropertyWordBreak:
     353    case CSSPropertyWordSpacing:
     354    case CSSPropertyWordWrap:
     355#if ENABLE(SVG)
     356    case CSSPropertyClipRule:
     357    case CSSPropertyColorInterpolation:
     358    case CSSPropertyColorInterpolationFilters:
     359    case CSSPropertyColorRendering:
     360    case CSSPropertyFill:
     361    case CSSPropertyFillOpacity:
     362    case CSSPropertyFillRule:
     363    case CSSPropertyGlyphOrientationHorizontal:
     364    case CSSPropertyGlyphOrientationVertical:
     365    case CSSPropertyKerning:
     366    case CSSPropertyMarker:
     367    case CSSPropertyMarkerEnd:
     368    case CSSPropertyMarkerMid:
     369    case CSSPropertyMarkerStart:
     370    case CSSPropertyStroke:
     371    case CSSPropertyStrokeDasharray:
     372    case CSSPropertyStrokeDashoffset:
     373    case CSSPropertyStrokeLinecap:
     374    case CSSPropertyStrokeLinejoin:
     375    case CSSPropertyStrokeMiterlimit:
     376    case CSSPropertyStrokeOpacity:
     377    case CSSPropertyStrokeWidth:
     378    case CSSPropertyShapeRendering:
     379    case CSSPropertyTextAnchor:
     380    case CSSPropertyWritingMode:
     381#endif
     382#if ENABLE(TOUCH_EVENTS)
     383    case CSSPropertyWebkitTapHighlightColor:
     384#endif
     385        return true;
     386    case CSSPropertyDisplay:
     387    case CSSPropertyWebkitFontFeatureSettings:
     388    case CSSPropertyWebkitFontSmoothing:
     389    case CSSPropertyWebkitTextOrientation:
     390    case CSSPropertyZoom:
     391    case CSSPropertyBackground:
     392    case CSSPropertyBackgroundAttachment:
     393    case CSSPropertyBackgroundClip:
     394    case CSSPropertyBackgroundColor:
     395    case CSSPropertyBackgroundImage:
     396    case CSSPropertyBackgroundOrigin:
     397    case CSSPropertyBackgroundPosition:
     398    case CSSPropertyBackgroundPositionX:
     399    case CSSPropertyBackgroundPositionY:
     400    case CSSPropertyBackgroundRepeat:
     401    case CSSPropertyBackgroundRepeatX:
     402    case CSSPropertyBackgroundRepeatY:
     403    case CSSPropertyBackgroundSize:
     404    case CSSPropertyBorder:
     405    case CSSPropertyBorderBottom:
     406    case CSSPropertyBorderBottomColor:
     407    case CSSPropertyBorderBottomLeftRadius:
     408    case CSSPropertyBorderBottomRightRadius:
     409    case CSSPropertyBorderBottomStyle:
     410    case CSSPropertyBorderBottomWidth:
     411    case CSSPropertyBorderColor:
     412    case CSSPropertyBorderImage:
     413    case CSSPropertyBorderImageOutset:
     414    case CSSPropertyBorderImageRepeat:
     415    case CSSPropertyBorderImageSlice:
     416    case CSSPropertyBorderImageSource:
     417    case CSSPropertyBorderImageWidth:
     418    case CSSPropertyBorderLeft:
     419    case CSSPropertyBorderLeftColor:
     420    case CSSPropertyBorderLeftStyle:
     421    case CSSPropertyBorderLeftWidth:
     422    case CSSPropertyBorderRadius:
     423    case CSSPropertyBorderRight:
     424    case CSSPropertyBorderRightColor:
     425    case CSSPropertyBorderRightStyle:
     426    case CSSPropertyBorderRightWidth:
     427    case CSSPropertyBorderStyle:
     428    case CSSPropertyBorderTop:
     429    case CSSPropertyBorderTopColor:
     430    case CSSPropertyBorderTopLeftRadius:
     431    case CSSPropertyBorderTopRightRadius:
     432    case CSSPropertyBorderTopStyle:
     433    case CSSPropertyBorderTopWidth:
     434    case CSSPropertyBorderWidth:
     435    case CSSPropertyBottom:
     436    case CSSPropertyBoxShadow:
     437    case CSSPropertyBoxSizing:
     438    case CSSPropertyClear:
     439    case CSSPropertyClip:
     440    case CSSPropertyContent:
     441    case CSSPropertyCounterIncrement:
     442    case CSSPropertyCounterReset:
     443    case CSSPropertyFloat:
     444    case CSSPropertyFontStretch:
     445    case CSSPropertyHeight:
     446    case CSSPropertyLeft:
     447    case CSSPropertyMargin:
     448    case CSSPropertyMarginBottom:
     449    case CSSPropertyMarginLeft:
     450    case CSSPropertyMarginRight:
     451    case CSSPropertyMarginTop:
     452    case CSSPropertyMaxHeight:
     453    case CSSPropertyMaxWidth:
     454    case CSSPropertyMinHeight:
     455    case CSSPropertyMinWidth:
     456    case CSSPropertyOpacity:
     457    case CSSPropertyOutline:
     458    case CSSPropertyOutlineColor:
     459    case CSSPropertyOutlineOffset:
     460    case CSSPropertyOutlineStyle:
     461    case CSSPropertyOutlineWidth:
     462    case CSSPropertyOverflow:
     463    case CSSPropertyOverflowX:
     464    case CSSPropertyOverflowY:
     465    case CSSPropertyPadding:
     466    case CSSPropertyPaddingBottom:
     467    case CSSPropertyPaddingLeft:
     468    case CSSPropertyPaddingRight:
     469    case CSSPropertyPaddingTop:
     470    case CSSPropertyPage:
     471    case CSSPropertyPageBreakAfter:
     472    case CSSPropertyPageBreakBefore:
     473    case CSSPropertyPageBreakInside:
     474    case CSSPropertyPosition:
     475    case CSSPropertyRight:
     476    case CSSPropertySize:
     477    case CSSPropertySrc:
     478    case CSSPropertyTableLayout:
     479    case CSSPropertyTextLineThrough:
     480    case CSSPropertyTextLineThroughColor:
     481    case CSSPropertyTextLineThroughMode:
     482    case CSSPropertyTextLineThroughStyle:
     483    case CSSPropertyTextLineThroughWidth:
     484    case CSSPropertyTextOverflow:
     485    case CSSPropertyTextOverline:
     486    case CSSPropertyTextOverlineColor:
     487    case CSSPropertyTextOverlineMode:
     488    case CSSPropertyTextOverlineStyle:
     489    case CSSPropertyTextOverlineWidth:
     490    case CSSPropertyTextUnderline:
     491    case CSSPropertyTextUnderlineColor:
     492    case CSSPropertyTextUnderlineMode:
     493    case CSSPropertyTextUnderlineStyle:
     494    case CSSPropertyTextUnderlineWidth:
     495    case CSSPropertyTop:
     496    case CSSPropertyUnicodeBidi:
     497    case CSSPropertyUnicodeRange:
     498    case CSSPropertyVerticalAlign:
     499    case CSSPropertyWidth:
     500    case CSSPropertyZIndex:
     501    case CSSPropertyWebkitAnimation:
     502    case CSSPropertyWebkitAnimationDelay:
     503    case CSSPropertyWebkitAnimationDirection:
     504    case CSSPropertyWebkitAnimationDuration:
     505    case CSSPropertyWebkitAnimationFillMode:
     506    case CSSPropertyWebkitAnimationIterationCount:
     507    case CSSPropertyWebkitAnimationName:
     508    case CSSPropertyWebkitAnimationPlayState:
     509    case CSSPropertyWebkitAnimationTimingFunction:
     510    case CSSPropertyWebkitAppearance:
     511    case CSSPropertyWebkitBackfaceVisibility:
     512    case CSSPropertyWebkitBackgroundClip:
     513    case CSSPropertyWebkitBackgroundComposite:
     514    case CSSPropertyWebkitBackgroundOrigin:
     515    case CSSPropertyWebkitBackgroundSize:
     516    case CSSPropertyWebkitBorderAfter:
     517    case CSSPropertyWebkitBorderAfterColor:
     518    case CSSPropertyWebkitBorderAfterStyle:
     519    case CSSPropertyWebkitBorderAfterWidth:
     520    case CSSPropertyWebkitBorderBefore:
     521    case CSSPropertyWebkitBorderBeforeColor:
     522    case CSSPropertyWebkitBorderBeforeStyle:
     523    case CSSPropertyWebkitBorderBeforeWidth:
     524    case CSSPropertyWebkitBorderEnd:
     525    case CSSPropertyWebkitBorderEndColor:
     526    case CSSPropertyWebkitBorderEndStyle:
     527    case CSSPropertyWebkitBorderEndWidth:
     528    case CSSPropertyWebkitBorderFit:
     529    case CSSPropertyWebkitBorderImage:
     530    case CSSPropertyWebkitBorderRadius:
     531    case CSSPropertyWebkitBorderStart:
     532    case CSSPropertyWebkitBorderStartColor:
     533    case CSSPropertyWebkitBorderStartStyle:
     534    case CSSPropertyWebkitBorderStartWidth:
     535    case CSSPropertyWebkitBoxAlign:
     536    case CSSPropertyWebkitBoxFlex:
     537    case CSSPropertyWebkitBoxFlexGroup:
     538    case CSSPropertyWebkitBoxLines:
     539    case CSSPropertyWebkitBoxOrdinalGroup:
     540    case CSSPropertyWebkitBoxOrient:
     541    case CSSPropertyWebkitBoxPack:
     542    case CSSPropertyWebkitBoxReflect:
     543    case CSSPropertyWebkitBoxShadow:
     544    case CSSPropertyWebkitColumnBreakAfter:
     545    case CSSPropertyWebkitColumnBreakBefore:
     546    case CSSPropertyWebkitColumnBreakInside:
     547    case CSSPropertyWebkitColumnCount:
     548    case CSSPropertyWebkitColumnGap:
     549    case CSSPropertyWebkitColumnRule:
     550    case CSSPropertyWebkitColumnRuleColor:
     551    case CSSPropertyWebkitColumnRuleStyle:
     552    case CSSPropertyWebkitColumnRuleWidth:
     553    case CSSPropertyWebkitColumnSpan:
     554    case CSSPropertyWebkitColumnWidth:
     555    case CSSPropertyWebkitColumns:
     556#if ENABLE(CSS_FILTERS)
     557    case CSSPropertyWebkitFilter:
     558#endif
     559#if ENABLE(CSS3_FLEXBOX)
     560    case CSSPropertyWebkitFlexOrder:
     561    case CSSPropertyWebkitFlexPack:
     562    case CSSPropertyWebkitFlexAlign:
     563    case CSSPropertyWebkitFlexFlow:
     564#endif
     565    case CSSPropertyWebkitFontSizeDelta:
     566    case CSSPropertyWebkitLineClamp:
     567    case CSSPropertyWebkitLogicalWidth:
     568    case CSSPropertyWebkitLogicalHeight:
     569    case CSSPropertyWebkitMarginAfterCollapse:
     570    case CSSPropertyWebkitMarginBeforeCollapse:
     571    case CSSPropertyWebkitMarginBottomCollapse:
     572    case CSSPropertyWebkitMarginTopCollapse:
     573    case CSSPropertyWebkitMarginCollapse:
     574    case CSSPropertyWebkitMarginAfter:
     575    case CSSPropertyWebkitMarginBefore:
     576    case CSSPropertyWebkitMarginEnd:
     577    case CSSPropertyWebkitMarginStart:
     578    case CSSPropertyWebkitMarquee:
     579    case CSSPropertyWebkitMarqueeDirection:
     580    case CSSPropertyWebkitMarqueeIncrement:
     581    case CSSPropertyWebkitMarqueeRepetition:
     582    case CSSPropertyWebkitMarqueeSpeed:
     583    case CSSPropertyWebkitMarqueeStyle:
     584    case CSSPropertyWebkitMask:
     585    case CSSPropertyWebkitMaskAttachment:
     586    case CSSPropertyWebkitMaskBoxImage:
     587    case CSSPropertyWebkitMaskBoxImageOutset:
     588    case CSSPropertyWebkitMaskBoxImageRepeat:
     589    case CSSPropertyWebkitMaskBoxImageSlice:
     590    case CSSPropertyWebkitMaskBoxImageSource:
     591    case CSSPropertyWebkitMaskBoxImageWidth:
     592    case CSSPropertyWebkitMaskClip:
     593    case CSSPropertyWebkitMaskComposite:
     594    case CSSPropertyWebkitMaskImage:
     595    case CSSPropertyWebkitMaskOrigin:
     596    case CSSPropertyWebkitMaskPosition:
     597    case CSSPropertyWebkitMaskPositionX:
     598    case CSSPropertyWebkitMaskPositionY:
     599    case CSSPropertyWebkitMaskRepeat:
     600    case CSSPropertyWebkitMaskRepeatX:
     601    case CSSPropertyWebkitMaskRepeatY:
     602    case CSSPropertyWebkitMaskSize:
     603    case CSSPropertyWebkitMatchNearestMailBlockquoteColor:
     604    case CSSPropertyWebkitMaxLogicalWidth:
     605    case CSSPropertyWebkitMaxLogicalHeight:
     606    case CSSPropertyWebkitMinLogicalWidth:
     607    case CSSPropertyWebkitMinLogicalHeight:
     608    case CSSPropertyWebkitPaddingAfter:
     609    case CSSPropertyWebkitPaddingBefore:
     610    case CSSPropertyWebkitPaddingEnd:
     611    case CSSPropertyWebkitPaddingStart:
     612    case CSSPropertyWebkitPerspective:
     613    case CSSPropertyWebkitPerspectiveOrigin:
     614    case CSSPropertyWebkitPerspectiveOriginX:
     615    case CSSPropertyWebkitPerspectiveOriginY:
     616    case CSSPropertyWebkitTransform:
     617    case CSSPropertyWebkitTransformOrigin:
     618    case CSSPropertyWebkitTransformOriginX:
     619    case CSSPropertyWebkitTransformOriginY:
     620    case CSSPropertyWebkitTransformOriginZ:
     621    case CSSPropertyWebkitTransformStyle:
     622    case CSSPropertyWebkitTransition:
     623    case CSSPropertyWebkitTransitionDelay:
     624    case CSSPropertyWebkitTransitionDuration:
     625    case CSSPropertyWebkitTransitionProperty:
     626    case CSSPropertyWebkitTransitionTimingFunction:
     627    case CSSPropertyWebkitUserDrag:
     628    case CSSPropertyWebkitFlowInto:
     629    case CSSPropertyWebkitFlowFrom:
     630    case CSSPropertyWebkitRegionOverflow:
     631    case CSSPropertyWebkitWrapShape:
     632    case CSSPropertyWebkitRegionBreakAfter:
     633    case CSSPropertyWebkitRegionBreakBefore:
     634    case CSSPropertyWebkitRegionBreakInside:
     635#if ENABLE(SVG)
     636    case CSSPropertyClipPath:
     637    case CSSPropertyMask:
     638    case CSSPropertyEnableBackground:
     639    case CSSPropertyFilter:
     640    case CSSPropertyFloodColor:
     641    case CSSPropertyFloodOpacity:
     642    case CSSPropertyLightingColor:
     643    case CSSPropertyStopColor:
     644    case CSSPropertyStopOpacity:
     645    case CSSPropertyColorProfile:
     646    case CSSPropertyAlignmentBaseline:
     647    case CSSPropertyBaselineShift:
     648    case CSSPropertyDominantBaseline:
     649    case CSSPropertyVectorEffect:
     650    case CSSPropertyWebkitSvgShadow:
     651#endif
     652#if ENABLE(DASHBOARD_SUPPORT)
     653    case CSSPropertyWebkitDashboardRegion:
     654#endif
     655        return false;
     656    case CSSPropertyInvalid:
     657        ASSERT_NOT_REACHED();
     658        return false;
     659    }
     660    ASSERT_NOT_REACHED();
     661    return false;
     662}
     663
    285664} // namespace WebCore
  • trunk/Source/WebCore/css/CSSProperty.h

    r97854 r98542  
    3333    WTF_MAKE_FAST_ALLOCATED;
    3434public:
    35     CSSProperty(int propID, PassRefPtr<CSSValue> value, bool important = false, int shorthandID = 0, bool implicit = false)
     35    CSSProperty(unsigned propID, PassRefPtr<CSSValue> value, bool important = false, int shorthandID = 0, bool implicit = false)
    3636        : m_id(propID)
    3737        , m_shorthandID(shorthandID)
    3838        , m_important(important)
    3939        , m_implicit(implicit)
     40        , m_inherited(isInheritedProperty(propID))
    4041        , m_value(value)
    4142    {
     
    5758    bool isImportant() const { return m_important; }
    5859    bool isImplicit() const { return m_implicit; }
     60    bool isInherited() const { return m_inherited; }
    5961
    6062    CSSValue* value() const { return m_value.get(); }
     
    6365
    6466    static int resolveDirectionAwareProperty(int propertyID, TextDirection, WritingMode);
     67    static bool isInheritedProperty(unsigned propertyID);
    6568
    6669    friend bool operator==(const CSSProperty&, const CSSProperty&);
    6770
    6871    // Make sure the following fits in 4 bytes. Really.
    69     signed m_id : 15;
    70     signed m_shorthandID : 15; // If this property was set as part of a shorthand, gives the shorthand.
     72    unsigned m_id : 14;
     73    unsigned m_shorthandID : 14; // If this property was set as part of a shorthand, gives the shorthand.
    7174    bool m_important : 1;
    7275    bool m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand.
     76    bool m_inherited : 1;
    7377
    7478    RefPtr<CSSValue> m_value;
  • trunk/Source/WebCore/css/CSSStyleSelector.cpp

    r98492 r98542  
    767767                        result.firstAuthorRule = result.lastAuthorRule;
    768768                    addMatchedDeclaration(attr->decl());
     769                    result.isCacheable = false;
    769770                }
    770771            }
     
    784785                for (unsigned i = 0; i < additionalDeclsSize; ++i)
    785786                    addMatchedDeclaration(m_additionalAttributeStyleDecls[i]);
     787                result.isCacheable = false;
    786788            }
    787789        }
     
    806808                result.firstAuthorRule = result.lastAuthorRule;
    807809            addMatchedDeclaration(inlineDecl);
     810            result.isCacheable = false;
    808811        }
    809812    }
     
    12421245    adjustRenderStyle(style(), m_parentStyle, element);
    12431246
    1244     // Start loading images referenced by this style.
    1245     loadPendingImages();
    1246 
    12471247    initElement(0); // Clear out for the next resolve.
    12481248
     
    20812081
    20822082template <bool applyFirst>
    2083 void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclaration, bool isImportant)
     2083void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclaration, bool isImportant, bool inheritedOnly)
    20842084{
    20852085    CSSMutableStyleDeclaration::const_iterator end = styleDeclaration->end();
    20862086    for (CSSMutableStyleDeclaration::const_iterator it = styleDeclaration->begin(); it != end; ++it) {
    20872087        const CSSProperty& current = *it;
    2088 
    20892088        if (isImportant != current.isImportant())
    20902089            continue;
    2091 
     2090        if (inheritedOnly && !current.isInherited() && current.value()->cssValueType() != CSSValue::CSS_INHERIT)
     2091            continue;
    20922092        int property = current.id();
    2093 
    20942093        if (applyFirst) {
    20952094            COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
    20962095            COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 16, CSS_zoom_is_end_of_first_prop_range);
    20972096            COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
    2098 
    20992097            // give special priority to font-xxx, color properties, etc
    21002098            if (property > CSSPropertyLineHeight)
     
    21142112
    21152113template <bool applyFirst>
    2116 void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex)
     2114void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex, bool inheritedOnly)
    21172115{
    21182116    if (startIndex == -1)
     
    21272125            m_applyPropertyToVisitedLinkStyle = linkMatchType & SelectorChecker::MatchVisited;
    21282126
    2129             applyDeclaration<applyFirst>(styleDeclaration, isImportant);
     2127            applyDeclaration<applyFirst>(styleDeclaration, isImportant, inheritedOnly);
    21302128        }
    21312129        m_applyPropertyToRegularStyle = true;
     
    21342132    }
    21352133    for (int i = startIndex; i <= endIndex; ++i)
    2136         applyDeclaration<applyFirst>(m_matchedDecls[i].styleDeclaration, isImportant);
     2134        applyDeclaration<applyFirst>(m_matchedDecls[i].styleDeclaration, isImportant, inheritedOnly);
     2135}
     2136
     2137unsigned CSSStyleSelector::computeDeclarationHash(MatchedStyleDeclaration* declarations, unsigned size)
     2138{
     2139    unsigned hash = 0;
     2140    for (unsigned i = 0; i < size; ++i) {
     2141        unsigned ptrHash = PtrHash<CSSMutableStyleDeclaration*>::hash(declarations[i].styleDeclaration);
     2142        ptrHash ^= IntHash<unsigned>::hash(declarations[i].linkMatchType);
     2143        // Make the position matter.
     2144        hash ^= (ptrHash << i) | (ptrHash >> (32 - i));
     2145    }
     2146    return hash;
     2147}
     2148
     2149bool operator==(const CSSStyleSelector::MatchResult& a, const CSSStyleSelector::MatchResult& b)
     2150{
     2151    return a.firstUARule == b.firstUARule
     2152        && a.lastUARule == b.lastUARule
     2153        && a.firstAuthorRule == b.firstAuthorRule
     2154        && a.lastAuthorRule == b.lastAuthorRule
     2155        && a.firstUserRule == b.firstUserRule
     2156        && a.lastUserRule == b.lastUserRule
     2157        && a.isCacheable == b.isCacheable;
     2158}
     2159
     2160bool operator!=(const CSSStyleSelector::MatchResult& a, const CSSStyleSelector::MatchResult& b)
     2161{
     2162    return !(a == b);
     2163}
     2164
     2165bool operator==(const CSSStyleSelector::MatchedStyleDeclaration& a, const CSSStyleSelector::MatchedStyleDeclaration& b)
     2166{
     2167    return a.styleDeclaration == b.styleDeclaration && a.linkMatchType == b.linkMatchType;
     2168}
     2169
     2170bool operator!=(const CSSStyleSelector::MatchedStyleDeclaration& a, const CSSStyleSelector::MatchedStyleDeclaration& b)
     2171{
     2172    return !(a == b);
     2173}
     2174
     2175const RenderStyle* CSSStyleSelector::findFromMatchedDeclarationCache(unsigned hash, const MatchResult& matchResult)
     2176{
     2177    ASSERT(hash);
     2178
     2179    MatchedStyleDeclarationCache::iterator it = m_matchStyleDeclarationCache.find(hash);
     2180    if (it == m_matchStyleDeclarationCache.end())
     2181        return 0;
     2182    MatchedStyleDeclarationCacheItem& cacheItem = it->second;
     2183    ASSERT(cacheItem.matchResult.isCacheable);
     2184   
     2185    size_t size = m_matchedDecls.size();
     2186    if (size != cacheItem.matchedStyleDeclarations.size())
     2187        return 0;
     2188    for (size_t i = 0; i < size; ++i) {
     2189        if (m_matchedDecls[i] != cacheItem.matchedStyleDeclarations[i])
     2190            return 0;
     2191    }
     2192    if (cacheItem.matchResult != matchResult)
     2193        return 0;
     2194    return cacheItem.renderStyle.get();
     2195}
     2196
     2197void CSSStyleSelector::addToMatchedDeclarationCache(const RenderStyle* style, unsigned hash, const MatchResult& matchResult)
     2198{
     2199    ASSERT(hash);
     2200    MatchedStyleDeclarationCacheItem cacheItem;
     2201    cacheItem.matchedStyleDeclarations.append(m_matchedDecls);
     2202    cacheItem.matchResult = matchResult;
     2203    // Note that we don't cache the original RenderStyle instance. It may be further modified.
     2204    // The RenderStyle in the cache is really just a holder for the non-inherited substructures and never used as-is.
     2205    cacheItem.renderStyle = RenderStyle::clone(style);
     2206    m_matchStyleDeclarationCache.add(hash, cacheItem);
     2207}
     2208
     2209static bool isCacheableInMatchedDeclarationCache(const RenderStyle* style, const RenderStyle* parentStyle)
     2210{
     2211    if (style->unique() || (style->styleType() != NOPSEUDO && parentStyle->unique()))
     2212        return false;
     2213    if (style->hasAppearance())
     2214        return false;
     2215    if (style->zoom() != RenderStyle::initialZoom())
     2216        return false;
     2217    return true;
    21372218}
    21382219
    21392220void CSSStyleSelector::applyMatchedDeclarations(const MatchResult& matchResult)
    21402221{
     2222    unsigned cacheHash = matchResult.isCacheable ? computeDeclarationHash(m_matchedDecls.data(), m_matchedDecls.size()) : 0;
     2223    bool applyInheritedOnly = false;
     2224    const RenderStyle* cachedStyle = 0;
     2225    if (cacheHash && (cachedStyle = findFromMatchedDeclarationCache(cacheHash, matchResult))) {
     2226        // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact
     2227        // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the
     2228        // element context. This is fast and saves memory by reusing the style data structures.
     2229        m_style->copyNonInheritedFrom(cachedStyle);
     2230        applyInheritedOnly = true;
     2231    }
    21412232    // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
    21422233    // high-priority properties first, i.e., those properties that other properties depend on.
     
    21442235    // and (4) normal important.
    21452236    m_lineHeightValue = 0;
    2146     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
    2147     applyDeclarations<true>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule);
    2148     applyDeclarations<true>(true, matchResult.firstUserRule, matchResult.lastUserRule);
    2149     applyDeclarations<true>(true, matchResult.firstUARule, matchResult.lastUARule);
    2150    
     2237    applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1, applyInheritedOnly);
     2238    applyDeclarations<true>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule, applyInheritedOnly);
     2239    applyDeclarations<true>(true, matchResult.firstUserRule, matchResult.lastUserRule, applyInheritedOnly);
     2240    applyDeclarations<true>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
     2241
     2242    if (cachedStyle && cachedStyle->effectiveZoom() != m_style->effectiveZoom()) {
     2243        m_fontDirty = true;
     2244        applyInheritedOnly = false;
     2245    }
     2246
    21512247    // If our font got dirtied, go ahead and update it now.
    21522248    updateFont();
     
    21552251    if (m_lineHeightValue)
    21562252        applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
    2157        
     2253
     2254    // Many properties depend on the font. If it changes we just apply all properties.
     2255    if (cachedStyle && cachedStyle->fontDescription() != m_style->fontDescription())
     2256        applyInheritedOnly = false;
     2257
    21582258    // Now do the normal priority UA properties.
    2159     applyDeclarations<false>(false, matchResult.firstUARule, matchResult.lastUARule);
     2259    applyDeclarations<false>(false, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
    21602260   
    21612261    // Cache our border and background so that we can examine them later.
     
    21632263   
    21642264    // Now do the author and user normal priority properties and all the !important properties.
    2165     applyDeclarations<false>(false, matchResult.lastUARule + 1, m_matchedDecls.size() - 1);
    2166     applyDeclarations<false>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule);
    2167     applyDeclarations<false>(true, matchResult.firstUserRule, matchResult.lastUserRule);
    2168     applyDeclarations<false>(true, matchResult.firstUARule, matchResult.lastUARule);
     2265    applyDeclarations<false>(false, matchResult.lastUARule + 1, m_matchedDecls.size() - 1, applyInheritedOnly);
     2266    applyDeclarations<false>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule, applyInheritedOnly);
     2267    applyDeclarations<false>(true, matchResult.firstUserRule, matchResult.lastUserRule, applyInheritedOnly);
     2268    applyDeclarations<false>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
    21692269   
     2270    loadPendingImages();
     2271       
    21702272    ASSERT(!m_fontDirty);
     2273   
     2274    if (cachedStyle || !cacheHash)
     2275        return;
     2276    if (!isCacheableInMatchedDeclarationCache(m_style.get(), m_parentStyle))
     2277        return;
     2278    addToMatchedDeclarationCache(m_style.get(), cacheHash, matchResult);
    21712279}
    21722280
  • trunk/Source/WebCore/css/CSSStyleSelector.h

    r97962 r98542  
    227227
    228228    struct MatchResult {
    229         MatchResult() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
     229        MatchResult() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1), isCacheable(true) { }
    230230        int firstUARule;
    231231        int lastUARule;
     
    234234        int firstUserRule;
    235235        int lastUserRule;
     236        bool isCacheable;
    236237    };
    237238    void matchAllRules(MatchResult&);
     
    246247    void applyMatchedDeclarations(const MatchResult&);
    247248    template <bool firstPass>
    248     void applyDeclarations(bool important, int startIndex, int endIndex);
     249    void applyDeclarations(bool important, int startIndex, int endIndex, bool inheritedOnly = false);
    249250    template <bool firstPass>
    250     void applyDeclaration(CSSMutableStyleDeclaration*, bool isImportant);
     251    void applyDeclaration(CSSMutableStyleDeclaration*, bool isImportant, bool inheritedOnly);
    251252
    252253    void matchPageRules(RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
     
    272273    typedef Vector<RefPtr<CSSRegionStyleRule> > RegionStyleRules;
    273274    RegionStyleRules m_regionStyleRules;
     275
    274276public:
    275277    static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
     
    326328    void loadPendingImages();
    327329
     330    struct MatchedStyleDeclaration {
     331        MatchedStyleDeclaration(CSSMutableStyleDeclaration* decl, unsigned type) : styleDeclaration(decl), linkMatchType(type) { }
     332        CSSMutableStyleDeclaration* styleDeclaration;
     333        unsigned linkMatchType;
     334    };
     335    static unsigned computeDeclarationHash(MatchedStyleDeclaration*, unsigned size);
     336    const RenderStyle* findFromMatchedDeclarationCache(unsigned hash, const MatchResult&);   
     337    void addToMatchedDeclarationCache(const RenderStyle*, unsigned hash, const MatchResult&);
     338
    328339    // We collect the set of decls that match in |m_matchedDecls|. We then walk the
    329340    // set of matched decls four times, once for those properties that others depend on (like font-size),
    330341    // and then a second time for all the remaining properties. We then do the same two passes
    331342    // for any !important rules.
    332     struct MatchedStyleDeclaration {
    333         MatchedStyleDeclaration(CSSMutableStyleDeclaration* decl, unsigned type) : styleDeclaration(decl), linkMatchType(type) { }
    334         CSSMutableStyleDeclaration* styleDeclaration;
    335         unsigned linkMatchType;
    336     };
    337343    Vector<MatchedStyleDeclaration, 64> m_matchedDecls;
     344   
     345    struct MatchedStyleDeclarationCacheItem {
     346        Vector<MatchedStyleDeclaration> matchedStyleDeclarations;
     347        MatchResult matchResult;
     348        RefPtr<RenderStyle> renderStyle;
     349    };
     350    typedef HashMap<unsigned, MatchedStyleDeclarationCacheItem> MatchedStyleDeclarationCache;
     351    MatchedStyleDeclarationCache m_matchStyleDeclarationCache;
    338352
    339353    // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
     
    373387
    374388    friend class CSSStyleApplyProperty;
     389    friend bool operator==(const MatchedStyleDeclaration&, const MatchedStyleDeclaration&);
     390    friend bool operator!=(const MatchedStyleDeclaration&, const MatchedStyleDeclaration&);
     391    friend bool operator==(const MatchResult&, const MatchResult&);
     392    friend bool operator!=(const MatchResult&, const MatchResult&);
    375393};
    376394
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r98492 r98542  
    180180        m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
    181181#endif
     182}
     183
     184void RenderStyle::copyNonInheritedFrom(const RenderStyle* other)
     185{
     186    m_box = other->m_box;
     187    visual = other->visual;
     188    m_background = other->m_background;
     189    surround = other->surround;
     190    rareNonInheritedData = other->rareNonInheritedData;
     191    // The flags are copied one-by-one because noninherited_flags contains a bunch of stuff other than real style data.
     192    noninherited_flags._effectiveDisplay = other->noninherited_flags._effectiveDisplay;
     193    noninherited_flags._originalDisplay = other->noninherited_flags._originalDisplay;
     194    noninherited_flags._overflowX = other->noninherited_flags._overflowX;
     195    noninherited_flags._overflowY = other->noninherited_flags._overflowY;
     196    noninherited_flags._vertical_align = other->noninherited_flags._vertical_align;
     197    noninherited_flags._clear = other->noninherited_flags._clear;
     198    noninherited_flags._position = other->noninherited_flags._position;
     199    noninherited_flags._floating = other->noninherited_flags._floating;
     200    noninherited_flags._table_layout = other->noninherited_flags._table_layout;
     201    noninherited_flags._page_break_before = other->noninherited_flags._page_break_before;
     202    noninherited_flags._page_break_after = other->noninherited_flags._page_break_after;
     203    noninherited_flags._page_break_inside = other->noninherited_flags._page_break_inside;
     204    noninherited_flags._unicodeBidi = other->noninherited_flags._unicodeBidi;
     205#if ENABLE(SVG)
     206    if (m_svgStyle != other->m_svgStyle)
     207        m_svgStyle.access()->copyNonInheritedFrom(other->m_svgStyle.get());
     208#endif
     209    ASSERT(zoom() == initialZoom());
    182210}
    183211
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r98492 r98542  
    267267        unsigned char _unicodeBidi : 3; // EUnicodeBidi
    268268        bool _isLink : 1;
     269        // If you add more style bits here, you will also need to update RenderStyle::copyNonInheritedFrom()
    269270        // 53 bits
    270271    } noninherited_flags;
     
    329330
    330331    void inheritFrom(const RenderStyle* inheritParent);
     332    void copyNonInheritedFrom(const RenderStyle*);
    331333
    332334    PseudoId styleType() const { return static_cast<PseudoId>(noninherited_flags._styleType); }
  • trunk/Source/WebCore/rendering/style/SVGRenderStyle.cpp

    r87121 r98542  
    127127}
    128128
     129void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other)
     130{
     131    svg_noninherited_flags = other->svg_noninherited_flags;
     132    stops = other->stops;
     133    misc = other->misc;
     134    shadowSVG = other->shadowSVG;
     135    resources = other->resources;
     136}
     137
    129138StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
    130139{
  • trunk/Source/WebCore/rendering/style/SVGRenderStyle.h

    r97638 r98542  
    4747    bool inheritedNotEqual(const SVGRenderStyle*) const;
    4848    void inheritFrom(const SVGRenderStyle*);
     49    void copyNonInheritedFrom(const SVGRenderStyle*);
    4950
    5051    StyleDifference diff(const SVGRenderStyle*) const;
Note: See TracChangeset for help on using the changeset viewer.