Changeset 133286 in webkit
- Timestamp:
- Nov 2, 2012 5:09:27 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r133284 r133286 1 2012-11-02 Andreas Kling <kling@webkit.org> 2 3 Only resolve attribute-derived style once per shared ElementAttributeData. 4 <http://webkit.org/b/100990> 5 6 Reviewed by Antti Koivisto. 7 8 Track the serialization of the "style" attribute, and the dirtiness of the presentation attribute style 9 on ElementAttributeData instead of in Node flags. 10 11 This allows us to avoid duplicate work for ElementAttributeData that are shared between multiple elements, 12 since the state is no longer per-Element. 13 14 I've left the presentation attribute cache in there for now, since it covers two additional cases: 15 16 - Elements with the same attributes in different order. 17 - Elements with the same presentation attributes, but with differing non-presentation attributes. 18 19 It's likely that we're not gaining much from it anymore, but that's a topic for another patch. 20 21 * dom/Node.h: 22 * dom/ElementAttributeData.h: 23 (WebCore::ElementAttributeData::presentationAttributeStyle): 24 (WebCore::ElementAttributeData::setPresentationAttributeStyle): 25 (WebCore::ElementAttributeData::styleAttributeIsDirty): 26 (WebCore::ElementAttributeData::setStyleAttributeIsDirty): 27 (WebCore::ElementAttributeData::presentationAttributeStyleIsDirty): 28 (WebCore::ElementAttributeData::setPresentationAttributeStyleIsDirty): 29 (ElementAttributeData): 30 (WebCore::ElementAttributeData::ElementAttributeData): 31 * dom/Element.cpp: 32 (WebCore::Element::getAttribute): 33 * dom/Element.h: 34 (WebCore::Element::styleAttributeIsDirty): 35 (WebCore::Element::updateInvalidAttributes): 36 * dom/StyledElement.cpp: 37 (WebCore::StyledElement::updateStyleAttribute): 38 (WebCore::StyledElement::attributeChanged): 39 (WebCore::StyledElement::styleAttributeChanged): 40 (WebCore::StyledElement::inlineStyleChanged): 41 * dom/StyledElement.h: 42 (WebCore::StyledElement::invalidateStyleAttribute): 43 44 Move the "attribute style dirty" and "style attribute valid" node flags to ElementAttributeData 45 and change them to both use dirty semantics. 46 47 * dom/ElementAttributeData.cpp: 48 (WebCore::ElementAttributeData::cloneDataFrom): 49 50 Share the presentation attribute style between cloned elements initially. 51 52 * dom/StyledElement.h: 53 (WebCore::StyledElement::presentationAttributeStyle): 54 * css/StyleResolver.cpp: 55 (WebCore::StyleResolver::sweepMatchedPropertiesCache): 56 (WebCore::StyleResolver::matchAllRules): 57 (WebCore::StyleResolver::canShareStyleWithElement): 58 * dom/ElementAttributeData.cpp: 59 (WebCore::MutableElementAttributeData::MutableElementAttributeData): 60 (WebCore::ElementAttributeData::reportMemoryUsage): 61 * inspector/InspectorCSSAgent.cpp: 62 (WebCore::InspectorCSSAgent::buildObjectForAttributesStyle): 63 64 Renamed StyledElement::attributeStyle() to presentationAttributeStyle(). The old name was too 65 easily confused with "style attribute". 66 67 * dom/StyledElement.cpp: 68 (WebCore::StyledElement::rebuildPresentationAttributeStyle): 69 70 Renamed from updateAttributeStyle(). 71 1 72 2012-11-01 Kent Tamura <tkent@chromium.org> 2 73 -
trunk/Source/WebCore/css/StyleResolver.cpp
r133227 r133286 479 479 { 480 480 // Look for cache entries containing a style declaration with a single ref and remove them. 481 // This may happen when an element attribute mutation causes it to generate a new attributeStyle(),481 // This may happen when an element attribute mutation causes it to generate a new presentationAttributeStyle(), 482 482 // potentially leaving this cache with the last ref on the old one. 483 483 Vector<unsigned, 16> toRemove; … … 928 928 // Now check author rules, beginning first with presentational attributes mapped from HTML. 929 929 if (m_styledElement) { 930 addElementStyleProperties(result, m_styledElement-> attributeStyle());930 addElementStyleProperties(result, m_styledElement->presentationAttributeStyle()); 931 931 932 932 // Now we check additional mapped declarations. … … 1180 1180 return false; 1181 1181 #endif 1182 if (!!element-> attributeStyle() != !!m_styledElement->attributeStyle())1182 if (!!element->presentationAttributeStyle() != !!m_styledElement->presentationAttributeStyle()) 1183 1183 return false; 1184 1184 const StylePropertySet* additionalAttributeStyleA = element->additionalAttributeStyle(); … … 1271 1271 } 1272 1272 1273 if (element-> attributeStyle() && !attributeStylesEqual(element->attributeStyle(), m_styledElement->attributeStyle()))1273 if (element->presentationAttributeStyle() && !attributeStylesEqual(element->presentationAttributeStyle(), m_styledElement->presentationAttributeStyle())) 1274 1274 return false; 1275 1275 -
trunk/Source/WebCore/dom/Element.cpp
r133275 r133286 262 262 const AtomicString& Element::getAttribute(const QualifiedName& name) const 263 263 { 264 if (UNLIKELY(name == styleAttr) && !isStyleAttributeValid())264 if (UNLIKELY(name == styleAttr) && styleAttributeIsDirty()) 265 265 updateStyleAttribute(); 266 266 … … 620 620 621 621 // Update the 'style' attribute if it's invalid and being requested: 622 if ( !isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))622 if (styleAttributeIsDirty() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase)) 623 623 updateStyleAttribute(); 624 624 -
trunk/Source/WebCore/dom/Element.h
r133275 r133286 4 4 * (C) 2001 Peter Kelly (pmk@post.com) 5 5 * (C) 2001 Dirk Mueller (mueller@kde.org) 6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 7 7 * 8 8 * This library is free software; you can redistribute it and/or … … 466 466 void classAttributeChanged(const AtomicString& newClassString); 467 467 468 bool styleAttributeIsDirty() const; 469 468 470 private: 469 471 // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute. … … 729 731 } 730 732 733 inline bool Element::styleAttributeIsDirty() const 734 { 735 return m_attributeData && m_attributeData->styleAttributeIsDirty(); 736 } 737 731 738 inline void Element::updateInvalidAttributes() const 732 739 { 733 if ( !isStyleAttributeValid())740 if (styleAttributeIsDirty()) 734 741 updateStyleAttribute(); 735 742 -
trunk/Source/WebCore/dom/ElementAttributeData.cpp
r133160 r133286 64 64 65 65 m_inlineStyleDecl = baseOther.m_inlineStyleDecl; 66 m_ attributeStyle = baseOther.m_attributeStyle;66 m_presentationAttributeStyle = baseOther.m_presentationAttributeStyle; 67 67 m_classNames = baseOther.m_classNames; 68 68 m_idForStyleResolution = baseOther.m_idForStyleResolution; … … 278 278 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM, actualSize); 279 279 info.addMember(m_inlineStyleDecl); 280 info.addMember(m_ attributeStyle);280 info.addMember(m_presentationAttributeStyle); 281 281 info.addMember(m_classNames); 282 282 info.addMember(m_idForStyleResolution); … … 342 342 } 343 343 344 if (targetElement.isStyledElement() && sourceData.m_inlineStyleDecl) { 344 if (!targetElement.isStyledElement()) 345 return; 346 347 m_styleAttributeIsDirty = sourceData.m_styleAttributeIsDirty; 348 m_presentationAttributeStyleIsDirty = sourceData.m_presentationAttributeStyleIsDirty; 349 350 // Clone the source element's inline style unless it's immutable. 351 if (sourceData.m_inlineStyleDecl) 345 352 m_inlineStyleDecl = sourceData.m_inlineStyleDecl->immutableCopyIfNeeded(); 346 targetElement.setIsStyleAttributeValid(sourceElement.isStyleAttributeValid()); 347 } 353 354 // Share the presentation attribute style (no need for cloning since it's not accessible via CSSOM.) 355 m_presentationAttributeStyle = sourceData.m_presentationAttributeStyle; 348 356 } 349 357 -
trunk/Source/WebCore/dom/ElementAttributeData.h
r133021 r133286 64 64 void detachCSSOMWrapperIfNeeded(StyledElement*); 65 65 66 const StylePropertySet* attributeStyle() const { return m_attributeStyle.get(); }67 void set AttributeStyle(PassRefPtr<StylePropertySet> style) const { m_attributeStyle= style; }66 const StylePropertySet* presentationAttributeStyle() const { return m_presentationAttributeStyle.get(); } 67 void setPresentationAttributeStyle(PassRefPtr<StylePropertySet> style) const { m_presentationAttributeStyle= style; } 68 68 69 69 size_t length() const; … … 96 96 void detachAttrObjectsFromElement(Element*) const; 97 97 98 bool styleAttributeIsDirty() const { return m_styleAttributeIsDirty; } 99 void setStyleAttributeIsDirty(bool f) const { m_styleAttributeIsDirty = f; } 100 bool presentationAttributeStyleIsDirty() const { return m_presentationAttributeStyleIsDirty; } 101 void setPresentationAttributeStyleIsDirty(bool f) const { m_presentationAttributeStyleIsDirty = f; } 102 98 103 void reportMemoryUsage(MemoryObjectInfo*) const; 99 104 … … 104 109 ElementAttributeData() 105 110 : m_isMutable(true) 111 , m_styleAttributeIsDirty(false) 112 , m_presentationAttributeStyleIsDirty(false) 106 113 , m_arraySize(0) 107 114 { } … … 109 116 ElementAttributeData(unsigned arraySize) 110 117 : m_isMutable(false) 118 , m_styleAttributeIsDirty(false) 119 , m_presentationAttributeStyleIsDirty(false) 111 120 , m_arraySize(arraySize) 112 121 { } 113 122 114 123 unsigned m_isMutable : 1; 124 mutable unsigned m_styleAttributeIsDirty : 1; 125 mutable unsigned m_presentationAttributeStyleIsDirty : 1; 115 126 unsigned m_arraySize : 31; 116 127 117 128 mutable RefPtr<StylePropertySet> m_inlineStyleDecl; 118 mutable RefPtr<StylePropertySet> m_ attributeStyle;129 mutable RefPtr<StylePropertySet> m_presentationAttributeStyle; 119 130 mutable SpaceSplitString m_classNames; 120 131 mutable AtomicString m_idForStyleResolution; -
trunk/Source/WebCore/dom/Node.h
r133224 r133286 100 100 typedef int ExceptionCode; 101 101 102 const int nodeStyleChangeShift = 20;102 const int nodeStyleChangeShift = 19; 103 103 104 104 // SyntheticStyleChange means that we need to go through the entire style change logic even though … … 308 308 virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); } 309 309 310 bool attributeStyleDirty() const { return getFlag(AttributeStyleDirtyFlag); }311 310 bool hasName() const { return getFlag(HasNameFlag); } 312 311 bool hasID() const; … … 323 322 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); } 324 323 bool isLink() const { return getFlag(IsLinkFlag); } 325 326 void setAttributeStyleDirty() { setFlag(AttributeStyleDirtyFlag); }327 void clearAttributeStyleDirty() { clearFlag(AttributeStyleDirtyFlag); }328 324 329 325 void setHasName(bool f) { setFlag(f, HasNameFlag); } … … 695 691 // be stored in the same memory word as the Node bits above. 696 692 IsParsingChildrenFinishedFlag = 1 << 15, // Element 697 IsStyleAttributeValidFlag = 1 << 16, // StyledElement698 693 #if ENABLE(SVG) 699 AreSVGAttributesValidFlag = 1 << 1 7, // Element700 IsSynchronizingSVGAttributesFlag = 1 << 1 8, // SVGElement701 HasSVGRareDataFlag = 1 << 1 9, // SVGElement694 AreSVGAttributesValidFlag = 1 << 16, // Element 695 IsSynchronizingSVGAttributesFlag = 1 << 17, // SVGElement 696 HasSVGRareDataFlag = 1 << 18, // SVGElement 702 697 #endif 703 698 704 699 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1), 705 700 706 SelfOrAncestorHasDirAutoFlag = 1 << 22, 707 708 HasNameFlag = 1 << 23, 709 710 AttributeStyleDirtyFlag = 1 << 24, 701 SelfOrAncestorHasDirAutoFlag = 1 << 21, 702 703 HasNameFlag = 1 << 22, 704 711 705 712 706 #if ENABLE(SVG) 713 DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag |AreSVGAttributesValidFlag,707 DefaultNodeFlags = IsParsingChildrenFinishedFlag | AreSVGAttributesValidFlag, 714 708 #else 715 DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag,716 #endif 717 InNamedFlowFlag = 1 << 2 6,718 HasAttrListFlag = 1 << 2 7,719 HasCustomCallbacksFlag = 1 << 2 8,720 HasScopedHTMLStyleChildFlag = 1 << 2 9,721 HasEventTargetDataFlag = 1 << 30,709 DefaultNodeFlags = IsParsingChildrenFinishedFlag, 710 #endif 711 InNamedFlowFlag = 1 << 23, 712 HasAttrListFlag = 1 << 24, 713 HasCustomCallbacksFlag = 1 << 25, 714 HasScopedHTMLStyleChildFlag = 1 << 26, 715 HasEventTargetDataFlag = 1 << 27, 722 716 }; 723 717 724 // 2bits remaining718 // 4 bits remaining 725 719 726 720 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } … … 818 812 RenderObject* m_renderer; 819 813 820 public:821 bool isStyleAttributeValid() const { return getFlag(IsStyleAttributeValidFlag); }822 void setIsStyleAttributeValid(bool f) { setFlag(f, IsStyleAttributeValidFlag); }823 void setIsStyleAttributeValid() const { setFlag(IsStyleAttributeValidFlag); }824 void clearIsStyleAttributeValid() { clearFlag(IsStyleAttributeValidFlag); }825 826 814 protected: 827 815 bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); } -
trunk/Source/WebCore/dom/StyledElement.cpp
r132141 r133286 127 127 void StyledElement::updateStyleAttribute() const 128 128 { 129 ASSERT(!isStyleAttributeValid()); 130 setIsStyleAttributeValid(); 131 if (const StylePropertySet* inlineStyle = this->inlineStyle()) 132 const_cast<StyledElement*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle->asText()); 129 ASSERT(styleAttributeIsDirty()); 130 ASSERT(attributeData()); 131 attributeData()->setStyleAttributeIsDirty(false); 132 if (inlineStyle()) 133 const_cast<StyledElement*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle()->asText()); 133 134 } 134 135 … … 152 153 { 153 154 if (isPresentationAttribute(name)) { 154 setAttributeStyleDirty();155 attributeData()->setPresentationAttributeStyleIsDirty(true); 155 156 setNeedsStyleRecalc(InlineStyleChange); 156 157 } … … 169 170 else if (document()->contentSecurityPolicy()->allowInlineStyle(document()->url(), startLineNumber)) 170 171 ensureAttributeData()->updateInlineStyleAvoidingMutation(this, newStyleString); 171 setIsStyleAttributeValid(); 172 173 attributeData()->setStyleAttributeIsDirty(false); 172 174 } 173 175 setNeedsStyleRecalc(); … … 186 188 { 187 189 setNeedsStyleRecalc(InlineStyleChange); 188 setIsStyleAttributeValid(false);190 attributeData()->setStyleAttributeIsDirty(true); 189 191 InspectorInstrumentation::didInvalidateStyleAttr(document(), this); 190 192 } … … 271 273 } 272 274 273 void StyledElement:: updateAttributeStyle()275 void StyledElement::rebuildPresentationAttributeStyle() 274 276 { 275 277 PresentationAttributeCacheKey cacheKey; … … 298 300 } 299 301 } 300 clearAttributeStyleDirty(); 301 302 attributeData()->set AttributeStyle(style->isEmpty() ? 0 : style);302 303 attributeData()->setPresentationAttributeStyleIsDirty(false); 304 attributeData()->setPresentationAttributeStyle(style->isEmpty() ? 0 : style); 303 305 304 306 if (!cacheHash || cacheIterator->value) -
trunk/Source/WebCore/dom/StyledElement.h
r132141 r133286 52 52 virtual CSSStyleDeclaration* style() OVERRIDE; 53 53 54 const StylePropertySet* attributeStyle();54 const StylePropertySet* presentationAttributeStyle(); 55 55 56 56 virtual void collectStyleForAttribute(const Attribute&, StylePropertySet*) { } … … 79 79 80 80 void makePresentationAttributeCacheKey(PresentationAttributeCacheKey&) const; 81 void updateAttributeStyle();81 void rebuildPresentationAttributeStyle(); 82 82 }; 83 83 84 84 inline void StyledElement::invalidateStyleAttribute() 85 85 { 86 clearIsStyleAttributeValid(); 86 ASSERT(attributeData()); 87 attributeData()->setStyleAttributeIsDirty(true); 87 88 } 88 89 89 inline const StylePropertySet* StyledElement:: attributeStyle()90 inline const StylePropertySet* StyledElement::presentationAttributeStyle() 90 91 { 91 if (attributeStyleDirty()) 92 updateAttributeStyle(); 93 return attributeData() ? attributeData()->attributeStyle() : 0; 92 if (!attributeData()) 93 return 0; 94 if (attributeData()->presentationAttributeStyleIsDirty()) 95 rebuildPresentationAttributeStyle(); 96 return attributeData()->presentationAttributeStyle(); 94 97 } 95 98 -
trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp
r130612 r133286 1185 1185 return 0; 1186 1186 1187 const StylePropertySet* attributeStyle = static_cast<StyledElement*>(element)->attributeStyle();1188 if (! attributeStyle)1187 const StylePropertySet* presentationAttributeStyle = static_cast<StyledElement*>(element)->presentationAttributeStyle(); 1188 if (!presentationAttributeStyle) 1189 1189 return 0; 1190 1190 1191 RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), const_cast<StylePropertySet*>( attributeStyle)->ensureCSSStyleDeclaration(), 0);1191 RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), const_cast<StylePropertySet*>(presentationAttributeStyle)->ensureCSSStyleDeclaration(), 0); 1192 1192 return inspectorStyle->buildObjectForStyle(); 1193 1193 }
Note: See TracChangeset
for help on using the changeset viewer.