Cache <font face> family lists in CSSValuePool.
authorkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2012 07:33:56 +0000 (07:33 +0000)
committerkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2012 07:33:56 +0000 (07:33 +0000)
<http://webkit.org/b/79195>

Reviewed by Antti Koivisto.

HTMLFontElements with "face" attributes are very common in legacy web content.
Add a String->CSSValue cache for these in CSSValuePool and use it to avoid
reparsing and recreating duplicate font face values.

This knocks 20ms (~1.5%) worth of samples off of the Moz page cycler on my system.

* css/CSSParser.cpp:
(WebCore::CSSParser::parseFontFaceValue):
* css/CSSParser.h:
* css/CSSValuePool.cpp:
(WebCore::CSSValuePool::createFontFaceValue):
* css/CSSValuePool.h:
* html/HTMLFontElement.cpp:
(WebCore::HTMLFontElement::collectStyleForAttribute):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@108451 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/css/CSSValuePool.cpp
Source/WebCore/css/CSSValuePool.h
Source/WebCore/html/HTMLFontElement.cpp

index d469cc5..d1f8a16 100644 (file)
@@ -1,3 +1,25 @@
+2012-02-21  Andreas Kling  <awesomekling@apple.com>
+
+        Cache <font face> family lists in CSSValuePool.
+        <http://webkit.org/b/79195>
+
+        Reviewed by Antti Koivisto.
+
+        HTMLFontElements with "face" attributes are very common in legacy web content.
+        Add a String->CSSValue cache for these in CSSValuePool and use it to avoid
+        reparsing and recreating duplicate font face values.
+
+        This knocks 20ms (~1.5%) worth of samples off of the Moz page cycler on my system.
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseFontFaceValue):
+        * css/CSSParser.h:
+        * css/CSSValuePool.cpp:
+        (WebCore::CSSValuePool::createFontFaceValue):
+        * css/CSSValuePool.h:
+        * html/HTMLFontElement.cpp:
+        (WebCore::HTMLFontElement::collectStyleForAttribute):
+
 2012-02-21  Adam Barth  <abarth@webkit.org>
 
         Separate the implementation of registerProtocolHandler from Navigator.cpp
index 9f8bc93..03f91b3 100644 (file)
@@ -485,6 +485,14 @@ static bool parseSimpleLengthValue(StylePropertySet* declaration, int propertyId
     return true;
 }
 
+PassRefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string, CSSStyleSheet* contextStyleSheet)
+{
+    RefPtr<StylePropertySet> dummyStyle = StylePropertySet::create();
+    if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, false, contextStyleSheet))
+        return 0;
+    return static_pointer_cast<CSSValueList>(dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily));
+}
+
 bool CSSParser::parseValue(StylePropertySet* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet)
 {
     if (parseSimpleLengthValue(declaration, propertyId, string, important, strict, contextStyleSheet))
index a1350e9..05e6e0e 100644 (file)
@@ -72,6 +72,7 @@ public:
     static bool parseValue(StylePropertySet*, int propId, const String&, bool important, bool strict, CSSStyleSheet* contextStyleSheet);
     static bool parseColor(RGBA32& color, const String&, bool strict = false);
     static bool parseSystemColor(RGBA32& color, const String&, Document*);
+    static PassRefPtr<CSSValueList> parseFontFaceValue(const AtomicString&, CSSStyleSheet* contextStyleSheet);
     PassRefPtr<CSSPrimitiveValue> parseValidPrimitive(int propId, CSSParserValue*);
     bool parseDeclaration(StylePropertySet*, const String&, RefPtr<CSSStyleSourceData>*, CSSStyleSheet* contextStyleSheet);
     bool parseMediaQuery(MediaList*, const String&);
index d48c7e7..c46c704 100644 (file)
 
 #include "config.h"
 #include "CSSValuePool.h"
+
+#include "CSSParser.h"
 #include "CSSValueKeywords.h"
+#include "CSSValueList.h"
 
 namespace WebCore {
 
@@ -128,4 +131,17 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String&
     return value;
 }
 
+PassRefPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& string, CSSStyleSheet* contextStyleSheet)
+{
+    // Just wipe out the cache and start rebuilding if it gets too big.
+    const int maximumFontFaceCacheSize = 128;
+    if (m_fontFaceValueCache.size() > maximumFontFaceCacheSize)
+        m_fontFaceValueCache.clear();
+
+    RefPtr<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).first->second;
+    if (!value)
+        value = CSSParser::parseFontFaceValue(string, contextStyleSheet);
+    return value;
+}
+
 }
index 57c7cc6..ade9fe0 100644 (file)
 #include "CSSInheritedValue.h"
 #include "CSSInitialValue.h"
 #include "CSSPrimitiveValue.h"
+#include <wtf/text/AtomicStringHash.h>
 #include <wtf/HashMap.h>
 #include <wtf/RefPtr.h>
 
 namespace WebCore {
 
+class CSSValueList;
+
 class CSSValuePool : public RefCounted<CSSValuePool> {
 public:
     static PassRefPtr<CSSValuePool> create() { return adoptRef(new CSSValuePool); }
     ~CSSValuePool();
 
+    PassRefPtr<CSSValueList> createFontFaceValue(const AtomicString&, CSSStyleSheet* contextStyleSheet);
     PassRefPtr<CSSPrimitiveValue> createFontFamilyValue(const String&);
     PassRefPtr<CSSInheritedValue> createInheritedValue() { return m_inheritedValue; }
     PassRefPtr<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue; }
@@ -73,6 +77,9 @@ private:
     IntegerValueCache m_percentValueCache;
     IntegerValueCache m_numberValueCache;
 
+    typedef HashMap<AtomicString, RefPtr<CSSValueList> > FontFaceValueCache;
+    FontFaceValueCache m_fontFaceValueCache;
+
     typedef HashMap<String, RefPtr<CSSPrimitiveValue> > FontFamilyValueCache;
     FontFamilyValueCache m_fontFamilyValueCache;
 };
index ea04017..a7c2e95 100644 (file)
@@ -26,6 +26,8 @@
 #include "Attribute.h"
 #include "CSSPropertyNames.h"
 #include "CSSValueKeywords.h"
+#include "CSSValueList.h"
+#include "CSSValuePool.h"
 #include "HTMLNames.h"
 #include "HTMLParserIdioms.h"
 #include <wtf/text/StringBuilder.h>
@@ -173,9 +175,10 @@ void HTMLFontElement::collectStyleForAttribute(Attribute* attr, StylePropertySet
             addPropertyToAttributeStyle(style, CSSPropertyFontSize, size);
     } else if (attr->name() == colorAttr)
         addHTMLColorToStyle(style, CSSPropertyColor, attr->value());
-    else if (attr->name() == faceAttr)
-        addPropertyToAttributeStyle(style, CSSPropertyFontFamily, attr->value());
-    else
+    else if (attr->name() == faceAttr) {
+        if (RefPtr<CSSValueList> fontFaceValue = document()->cssValuePool()->createFontFaceValue(attr->value(), document()->elementSheet()))
+            style->setProperty(CSSProperty(CSSPropertyFontFamily, fontFaceValue.release()));
+    } else
         HTMLElement::collectStyleForAttribute(attr, style);
 }