+2012-02-08 Andreas Kling <awesomekling@apple.com>
+
+ Increased style sharing for elements with presentation attributes.
+ <http://webkit.org/b/78199>
+
+ Reviewed by Antti Koivisto.
+
+ When determining whether two elements can share style, we can do a lot better.
+ Instead of comparing the attribute maps for exact equality, do a property-by-property
+ comparison of the attributeStyle() and the additionalAttributeStyle() (if any.)
+
+ This increases our style sharing hit rate and shaves 100ms off of each cycle on
+ Chromium's "Moz" page cycler test on my machine.
+
+ The function that compares attribute styles has O(n^2) runtime in the worst case,
+ where n is the number of properties in the styles. However, given the low number of
+ properties found in attribute styles, this should be fine, and it doesn't seem to
+ heat up in profiles.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::attributeStylesEqual):
+ (WebCore::CSSStyleSelector::canShareStyleWithElement):
+
2012-02-08 Raymond Liu <raymond.liu@intel.com>
Fix the caculation of preDelayFrames in DynamicsCompressorKernel
return true;
}
+// This function makes some assumptions that only make sense for attribute styles (we only compare CSSProperty::id() and CSSProperty::value().)
+static inline bool attributeStylesEqual(StylePropertySet* a, StylePropertySet* b)
+{
+ if (a == b)
+ return true;
+ if (a->propertyCount() != b->propertyCount())
+ return false;
+ unsigned propertyCount = a->propertyCount();
+ for (unsigned i = 0; i < propertyCount; ++i) {
+ const CSSProperty& aProperty = a->propertyAt(i);
+ unsigned j;
+ for (j = 0; j < propertyCount; ++j) {
+ const CSSProperty& bProperty = b->propertyAt(j);
+ if (aProperty.id() != bProperty.id())
+ continue;
+ // We could get a few more hits by comparing cssText() here, but that gets expensive quickly.
+ if (aProperty.value() != bProperty.value())
+ return false;
+ break;
+ }
+ if (j == propertyCount)
+ return false;
+ }
+ return true;
+}
+
bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
{
RenderStyle* style = element->renderStyle();
return false;
if (!!element->attributeStyle() != !!m_styledElement->attributeStyle())
return false;
+ StylePropertySet* additionalAttributeStyleA = element->additionalAttributeStyle().get();
+ StylePropertySet* additionalAttributeStyleB = m_styledElement->additionalAttributeStyle().get();
+ if (!additionalAttributeStyleA != !additionalAttributeStyleB)
+ return false;
if (element->isLink() != m_element->isLink())
return false;
if (style->affectedByUncommonAttributeSelectors())
if (element->hasClass() && m_element->getAttribute(classAttr) != element->getAttribute(classAttr))
return false;
- if (element->attributeStyle() && !element->attributeMap()->mapsEquivalent(m_styledElement->attributeMap()))
+ if (element->attributeStyle() && !attributeStylesEqual(element->attributeStyle(), m_styledElement->attributeStyle()))
+ return false;
+
+ if (additionalAttributeStyleA && !attributeStylesEqual(additionalAttributeStyleA, additionalAttributeStyleB))
return false;
if (element->isLink() && m_elementLinkState != style->insideLink())