<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
+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
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))
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&);
#include "config.h"
#include "CSSValuePool.h"
+
+#include "CSSParser.h"
#include "CSSValueKeywords.h"
+#include "CSSValueList.h"
namespace WebCore {
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;
+}
+
}
#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; }
IntegerValueCache m_percentValueCache;
IntegerValueCache m_numberValueCache;
+ typedef HashMap<AtomicString, RefPtr<CSSValueList> > FontFaceValueCache;
+ FontFaceValueCache m_fontFaceValueCache;
+
typedef HashMap<String, RefPtr<CSSPrimitiveValue> > FontFamilyValueCache;
FontFamilyValueCache m_fontFamilyValueCache;
};
#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>
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);
}