Changeset 107919 in webkit


Ignore:
Timestamp:
Feb 16, 2012 3:05:24 AM (12 years ago)
Author:
kling@webkit.org
Message:

Share font-family CSS values through CSSValuePool.
<http://webkit.org/b/78604>

Reviewed by Darin Adler.

Cache and share FontFamilyValue instances in the per-document CSSValuePool.
This reduces memory consumption by 248 kB on the Moz page cycler (64-bit)
and avoids a bunch of extra work.

This is a regression from the recent attribute style refactoring; previously
the mapped attribute declaration table would ensure that multiple 'font'
elements with the same 'face' value would share the same FontFamilyValue.

We're not yet sharing the entire CSSValueList returned by parseFontFamily()
but this is a step on the way there.

  • css/FontFamilyValue.cpp:
  • css/FontFamilyValue.h:

Removed appendSpaceSeparated(), making FontFamilyValue immutable.

  • css/CSSParser.cpp:

(FontFamilyValueBuilder):
(WebCore::FontFamilyValueBuilder::FontFamilyValueBuilder):
(WebCore::FontFamilyValueBuilder::add):
(WebCore::FontFamilyValueBuilder::commit):
(WebCore::CSSParser::parseFontFamily):

Refactor parseFontFamily() to defer creation of FontFamilyValue until
the whole family name is known. Added a little helper class to avoid
code duplication.

  • css/CSSValuePool.h:
  • css/CSSValuePool.cpp:

(WebCore::CSSValuePool::createFontFamilyValue):

Added a FontFamilyValue cache to CSSValuePool. All values are tied to
the lifetime of the pool.

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r107915 r107919  
     12012-02-15  Andreas Kling  <awesomekling@apple.com>
     2
     3        Share font-family CSS values through CSSValuePool.
     4        <http://webkit.org/b/78604>
     5
     6        Reviewed by Darin Adler.
     7
     8        Cache and share FontFamilyValue instances in the per-document CSSValuePool.
     9        This reduces memory consumption by 248 kB on the Moz page cycler (64-bit)
     10        and avoids a bunch of extra work.
     11
     12        This is a regression from the recent attribute style refactoring; previously
     13        the mapped attribute declaration table would ensure that multiple 'font'
     14        elements with the same 'face' value would share the same FontFamilyValue.
     15
     16        We're not yet sharing the entire CSSValueList returned by parseFontFamily()
     17        but this is a step on the way there.
     18
     19        * css/FontFamilyValue.cpp:
     20        * css/FontFamilyValue.h:
     21
     22            Removed appendSpaceSeparated(), making FontFamilyValue immutable.
     23
     24        * css/CSSParser.cpp:
     25        (FontFamilyValueBuilder):
     26        (WebCore::FontFamilyValueBuilder::FontFamilyValueBuilder):
     27        (WebCore::FontFamilyValueBuilder::add):
     28        (WebCore::FontFamilyValueBuilder::commit):
     29        (WebCore::CSSParser::parseFontFamily):
     30
     31            Refactor parseFontFamily() to defer creation of FontFamilyValue until
     32            the whole family name is known. Added a little helper class to avoid
     33            code duplication.
     34
     35        * css/CSSValuePool.h:
     36        * css/CSSValuePool.cpp:
     37        (WebCore::CSSValuePool::createFontFamilyValue):
     38
     39            Added a FontFamilyValue cache to CSSValuePool. All values are tied to
     40            the lifetime of the pool.
     41
    1422012-02-16  Simon Hausmann  <simon.hausmann@nokia.com>
    243
  • trunk/Source/WebCore/css/CSSParser.cpp

    r107899 r107919  
    42964296}
    42974297
     4298class FontFamilyValueBuilder {
     4299public:
     4300    FontFamilyValueBuilder(CSSValueList* list, CSSValuePool* pool)
     4301        : m_list(list)
     4302        , m_cssValuePool(pool)
     4303    {
     4304    }
     4305
     4306    void add(const CSSParserString& string)
     4307    {
     4308        if (!m_builder.isEmpty())
     4309            m_builder.append(' ');
     4310        m_builder.append(string.characters, string.length);
     4311    }
     4312
     4313    void commit()
     4314    {
     4315        if (m_builder.isEmpty())
     4316            return;
     4317        m_list->append(m_cssValuePool->createFontFamilyValue(m_builder.toString()));
     4318        m_builder.clear();
     4319    }
     4320
     4321private:
     4322    StringBuilder m_builder;
     4323    CSSValueList* m_list;
     4324    CSSValuePool* m_cssValuePool;
     4325};
     4326
    42984327PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
    42994328{
     
    43014330    CSSParserValue* value = m_valueList->current();
    43024331
    4303     FontFamilyValue* currFamily = 0;
     4332    FontFamilyValueBuilder familyBuilder(list.get(), cssValuePool());
     4333    bool inFamily = false;
     4334
    43044335    while (value) {
    43054336        if (value->id == CSSValueInitial || value->id == CSSValueInherit)
     
    43134344
    43144345        if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) {
    4315             if (currFamily)
    4316                 currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
     4346            if (inFamily)
     4347                familyBuilder.add(value->string);
    43174348            else if (nextValBreaksFont || !nextValIsFontName)
    43184349                list->append(cssValuePool()->createIdentifierValue(value->id));
    43194350            else {
    4320                 RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string);
    4321                 currFamily = newFamily.get();
    4322                 list->append(newFamily.release());
     4351                familyBuilder.commit();
     4352                familyBuilder.add(value->string);
     4353                inFamily = true;
    43234354            }
    43244355        } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
    43254356            // Strings never share in a family name.
    4326             currFamily = 0;
    4327             list->append(FontFamilyValue::create(value->string));
     4357            inFamily = false;
     4358            familyBuilder.commit();
     4359            list->append(cssValuePool()->createFontFamilyValue(value->string));
    43284360        } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
    4329             if (currFamily)
    4330                 currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
     4361            if (inFamily)
     4362                familyBuilder.add(value->string);
    43314363            else if (nextValBreaksFont || !nextValIsFontName)
    4332                 list->append(FontFamilyValue::create(value->string));
     4364                list->append(cssValuePool()->createFontFamilyValue(value->string));
    43334365            else {
    4334                 RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string);
    4335                 currFamily = newFamily.get();
    4336                 list->append(newFamily.release());
     4366                familyBuilder.commit();
     4367                familyBuilder.add(value->string);
     4368                inFamily = true;
    43374369            }
    43384370        } else {
     
    43454377        if (nextValBreaksFont) {
    43464378            value = m_valueList->next();
    4347             currFamily = 0;
     4379            familyBuilder.commit();
     4380            inFamily = false;
    43484381        }
    43494382        else if (nextValIsFontName)
     
    43524385            break;
    43534386    }
     4387    familyBuilder.commit();
     4388
    43544389    if (!list->length())
    43554390        list = 0;
  • trunk/Source/WebCore/css/CSSValuePool.cpp

    r101959 r107919  
    121121}
    122122
     123PassRefPtr<FontFamilyValue> CSSValuePool::createFontFamilyValue(const String& familyName)
     124{
     125    RefPtr<FontFamilyValue>& value = m_fontFamilyValueCache.add(familyName, 0).first->second;
     126    if (!value)
     127        value = FontFamilyValue::create(familyName);
     128    return value;
    123129}
     130
     131}
  • trunk/Source/WebCore/css/CSSValuePool.h

    r101959 r107919  
    3030#include "CSSInitialValue.h"
    3131#include "CSSPrimitiveValue.h"
     32#include "FontFamilyValue.h"
    3233#include <wtf/HashMap.h>
    3334#include <wtf/RefPtr.h>
     
    4041    ~CSSValuePool();
    4142
     43    PassRefPtr<FontFamilyValue> createFontFamilyValue(const String&);
    4244    PassRefPtr<CSSInheritedValue> createInheritedValue() { return m_inheritedValue; }
    4345    PassRefPtr<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue; }
     
    7274    IntegerValueCache m_percentValueCache;
    7375    IntegerValueCache m_numberValueCache;
     76
     77    typedef HashMap<String, RefPtr<FontFamilyValue> > FontFamilyValueCache;
     78    FontFamilyValueCache m_fontFamilyValueCache;
    7479};
    7580
  • trunk/Source/WebCore/css/FontFamilyValue.cpp

    r99567 r107919  
    5959}
    6060
    61 void FontFamilyValue::appendSpaceSeparated(const UChar* characters, unsigned length)
    62 {
    63     m_familyName.append(' ');
    64     m_familyName.append(characters, length);
    65 }
    66 
    6761String FontFamilyValue::customCssText() const
    6862{
  • trunk/Source/WebCore/css/FontFamilyValue.h

    r99567 r107919  
    3434    }
    3535
    36     void appendSpaceSeparated(const UChar* characters, unsigned length);
    37 
    3836    const String& familyName() const { return m_familyName; }
    3937
Note: See TracChangeset for help on using the changeset viewer.