Changeset 39088 in webkit


Ignore:
Timestamp:
Dec 7, 2008 5:29:53 PM (15 years ago)
Author:
Antti Koivisto
Message:

2008-12-07 Antti Koivisto <Antti Koivisto>

Reviewed by Darin Adler.

https://bugs.webkit.org/show_bug.cgi?id=22717
Make CSS values use less memory


Share CSSPrimitiveValue objects for commonly used values including

  • idents
  • colors
  • small integers


This reduces the amount CSSPrimitiveValue instances by > 80%.

  • css/CSSPrimitiveValue.cpp: (WebCore::CSSPrimitiveValue::createIdentifier): (WebCore::CSSPrimitiveValue::createColor): (WebCore::CSSPrimitiveValue::create):
  • css/CSSPrimitiveValue.h: (WebCore::CSSPrimitiveValue::create):
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r39086 r39088  
     12008-12-07  Antti Koivisto  <antti@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=22717
     6        Make CSS values use less memory
     7       
     8        Share CSSPrimitiveValue objects for commonly used values including
     9        - idents
     10        - colors
     11        - small integers
     12       
     13        This reduces the amount CSSPrimitiveValue instances by > 80%.
     14
     15        * css/CSSPrimitiveValue.cpp:
     16        (WebCore::CSSPrimitiveValue::createIdentifier):
     17        (WebCore::CSSPrimitiveValue::createColor):
     18        (WebCore::CSSPrimitiveValue::create):
     19        * css/CSSPrimitiveValue.h:
     20        (WebCore::CSSPrimitiveValue::create):
     21
    1222008-12-07  Antti Koivisto  <antti@apple.com>
    223
  • trunk/WebCore/css/CSSPrimitiveValue.cpp

    r38959 r39088  
    4141
    4242namespace WebCore {
     43
     44// A more stylish solution than sharing would be to turn CSSPrimitiveValue (or CSSValues in general) into non-virtual,
     45// non-refcounted simple type with value semantics. In practice these sharing tricks get similar memory benefits
     46// with less need for refactoring.
     47
     48PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createIdentifier(int ident)
     49{
     50    static RefPtr<CSSPrimitiveValue>* identValueCache = new RefPtr<CSSPrimitiveValue>[numCSSValueKeywords];
     51    if (ident >= 0 && ident < numCSSValueKeywords) {
     52        RefPtr<CSSPrimitiveValue> primitiveValue;
     53        if (!(primitiveValue = identValueCache[ident])) {
     54            primitiveValue = adoptRef(new CSSPrimitiveValue(ident));
     55            identValueCache[ident] = primitiveValue;
     56        }
     57        return primitiveValue.release();
     58    }
     59    return adoptRef(new CSSPrimitiveValue(ident));
     60}
     61
     62PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createColor(unsigned rgbValue)
     63{
     64    typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache;
     65    static ColorValueCache* colorValueCache = new ColorValueCache;
     66    // These are the empty and deleted values of the hash table.
     67    if (rgbValue == Color::transparent) {
     68        static CSSPrimitiveValue* colorTransparent = new CSSPrimitiveValue(Color::transparent);
     69        return colorTransparent;
     70    }
     71    if (rgbValue == Color::white) {
     72        static CSSPrimitiveValue* colorWhite = new CSSPrimitiveValue(Color::white);
     73        return colorWhite;
     74    }
     75    RefPtr<CSSPrimitiveValue> primitiveValue = colorValueCache->get(rgbValue);
     76    if (primitiveValue)
     77        return primitiveValue.release();
     78    primitiveValue = adoptRef(new CSSPrimitiveValue(rgbValue));
     79    // Just wipe out the cache and start rebuilding when it gets too big.
     80    const int maxColorCacheSize = 512;
     81    if (colorValueCache->size() >= maxColorCacheSize)
     82        colorValueCache->clear();
     83    colorValueCache->add(rgbValue, primitiveValue);
     84   
     85    return primitiveValue.release();
     86}
     87
     88PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(double value, UnitTypes type)
     89{
     90    // Small integers are very common. Try to share them.
     91    const int cachedIntegerCount = 128;
     92    // Other common primitive types have UnitTypes smaller than this.
     93    const int maxCachedUnitType = CSS_PX;
     94    typedef RefPtr<CSSPrimitiveValue>(* IntegerValueCache)[maxCachedUnitType + 1];
     95    static IntegerValueCache integerValueCache = new RefPtr<CSSPrimitiveValue>[cachedIntegerCount][maxCachedUnitType + 1];
     96    if (type <= CSS_PX && value >= 0 && value < cachedIntegerCount) {
     97        int intValue = static_cast<int>(value);
     98        if (value == intValue) {
     99            RefPtr<CSSPrimitiveValue> primitiveValue;
     100            if (!(primitiveValue = integerValueCache[intValue][type])) {
     101                primitiveValue = adoptRef(new CSSPrimitiveValue(value, type));
     102                integerValueCache[intValue][type] = primitiveValue;
     103            }
     104            return primitiveValue.release();
     105        }
     106    }
     107
     108    return adoptRef(new CSSPrimitiveValue(value, type));
     109}
     110
     111PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(const String& value, UnitTypes type)
     112{
     113    return adoptRef(new CSSPrimitiveValue(value, type));
     114}
    43115
    44116static const char* valueOrPropertyName(int valueOrPropertyID)
  • trunk/WebCore/css/CSSPrimitiveValue.h

    r38959 r39088  
    8383    };
    8484
    85     static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident)
    86     {
    87         return adoptRef(new CSSPrimitiveValue(ident));
    88     }
    89     static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue)
    90     {
    91         return adoptRef(new CSSPrimitiveValue(rgbValue));
    92     }
     85    static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident);
     86    static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue);
     87    static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type);
     88    static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type);
     89   
    9390    template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value)
    9491    {
    9592        return adoptRef(new CSSPrimitiveValue(value));
    96     }
    97     static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type)
    98     {
    99         return adoptRef(new CSSPrimitiveValue(value, type));
    100     }
    101     static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type)
    102     {
    103         return adoptRef(new CSSPrimitiveValue(value, type));
    10493    }
    10594
Note: See TracChangeset for help on using the changeset viewer.