Changeset 102584 in webkit


Ignore:
Timestamp:
Dec 12, 2011 7:47:43 AM (12 years ago)
Author:
apavlov@chromium.org
Message:

Implement a cache for CSSStyleRule::selectorText()
https://bugs.webkit.org/show_bug.cgi?id=74269

This change is geared towards speeding up the CSS selector profiler,
its implementation tracked at https://bugs.webkit.org/show_bug.cgi?id=74004.
Using a proof-of-concept implementation of the profiler, this change reduces
the profiler temporal overhead on PerformanceTests/Parser/html5-full-render.html
roughly by 86% (from ~72 seconds down to ~10 seconds). This change also does not
considerably increase average memory usage, as reading selectorText is a relatively
rare case during normal web browsing.

Reviewed by Andreas Kling.

No new tests, as this functionality is covered by existing tests.

  • css/CSSRule.h:
  • css/CSSStyleRule.cpp:

(WebCore::CSSStyleRule::~CSSStyleRule):
(WebCore::selectorTextCache):
(WebCore::CSSStyleRule::cleanup):
(WebCore::CSSStyleRule::generateSelectorText):
(WebCore::CSSStyleRule::selectorText):
(WebCore::CSSStyleRule::setSelectorText):

  • css/CSSStyleRule.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r102581 r102584  
     12011-12-12  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Implement a cache for CSSStyleRule::selectorText()
     4        https://bugs.webkit.org/show_bug.cgi?id=74269
     5
     6        This change is geared towards speeding up the CSS selector profiler,
     7        its implementation tracked at https://bugs.webkit.org/show_bug.cgi?id=74004.
     8        Using a proof-of-concept implementation of the profiler, this change reduces
     9        the profiler temporal overhead on PerformanceTests/Parser/html5-full-render.html
     10        roughly by 86% (from ~72 seconds down to ~10 seconds). This change also does not
     11        considerably increase average memory usage, as reading selectorText is a relatively
     12        rare case during normal web browsing.
     13
     14        Reviewed by Andreas Kling.
     15
     16        No new tests, as this functionality is covered by existing tests.
     17
     18        * css/CSSRule.h:
     19        * css/CSSStyleRule.cpp:
     20        (WebCore::CSSStyleRule::~CSSStyleRule):
     21        (WebCore::selectorTextCache):
     22        (WebCore::CSSStyleRule::cleanup):
     23        (WebCore::CSSStyleRule::generateSelectorText):
     24        (WebCore::CSSStyleRule::selectorText):
     25        (WebCore::CSSStyleRule::setSelectorText):
     26        * css/CSSStyleRule.h:
     27
    1282011-12-12  Alexander Pavlov  <apavlov@chromium.org>
    229
  • trunk/Source/WebCore/css/CSSRule.h

    r101899 r102584  
    111111    CSSRule(CSSStyleSheet* parent, Type type)
    112112        : m_sourceLine(0)
     113        , m_hasCachedSelectorText(false)
    113114        , m_parentIsRule(false)
    114115        , m_type(type)
     
    123124
    124125    // Only used by CSSStyleRule but kept here to maximize struct packing.
    125     signed m_sourceLine : 27;
     126    signed m_sourceLine : 26;
     127    mutable bool m_hasCachedSelectorText : 1;
    126128
    127129private:
  • trunk/Source/WebCore/css/CSSStyleRule.cpp

    r101218 r102584  
    3232#include "StyleSheet.h"
    3333
     34#include <wtf/text/StringBuilder.h>
     35
    3436namespace WebCore {
    3537
     
    4749    if (m_style)
    4850        m_style->setParentRule(0);
     51    cleanup();
     52}
     53
     54typedef HashMap<const CSSStyleRule*, String> SelectorTextCache;
     55static SelectorTextCache& selectorTextCache()
     56{
     57    DEFINE_STATIC_LOCAL(SelectorTextCache, cache, ());
     58    return cache;
     59}
     60
     61inline void CSSStyleRule::cleanup()
     62{
     63    if (m_hasCachedSelectorText) {
     64        selectorTextCache().remove(this);
     65        m_hasCachedSelectorText = false;
     66    }
     67}
     68
     69String CSSStyleRule::generateSelectorText() const
     70{
     71    if (isPageRule())
     72        return static_cast<const CSSPageRule*>(this)->pageSelectorText();
     73    else {
     74        StringBuilder builder;
     75        for (CSSSelector* s = selectorList().first(); s; s = CSSSelectorList::next(s)) {
     76            if (s != selectorList().first())
     77                builder.append(", ");
     78            builder.append(s->selectorText());
     79        }
     80        return builder.toString();
     81    }
    4982}
    5083
    5184String CSSStyleRule::selectorText() const
    5285{
    53     if (isPageRule())
    54         return static_cast<const CSSPageRule*>(this)->pageSelectorText();
     86    if (m_hasCachedSelectorText) {
     87        ASSERT(selectorTextCache().contains(this));
     88        return selectorTextCache().get(this);
     89    }
    5590
    56     String str;
    57     for (CSSSelector* s = selectorList().first(); s; s = CSSSelectorList::next(s)) {
    58         if (s != selectorList().first())
    59             str += ", ";
    60         str += s->selectorText();
    61     }
    62     return str;
     91    ASSERT(!selectorTextCache().contains(this));
     92    String text = generateSelectorText();
     93    selectorTextCache().set(this, text);
     94    m_hasCachedSelectorText = true;
     95    return text;
    6396}
    6497
     
    86119    String oldSelectorText = this->selectorText();
    87120    m_selectorList.adopt(selectorList);
     121
     122    if (m_hasCachedSelectorText) {
     123        ASSERT(selectorTextCache().contains(this));
     124        selectorTextCache().set(this, generateSelectorText());
     125    }
     126
    88127    if (this->selectorText() == oldSelectorText)
    89128        return;
  • trunk/Source/WebCore/css/CSSStyleRule.h

    r101218 r102584  
    6262
    6363private:
     64    void cleanup();
     65    String generateSelectorText() const;
     66
    6467    RefPtr<CSSMutableStyleDeclaration> m_style;
    6568    CSSSelectorList m_selectorList;
Note: See TracChangeset for help on using the changeset viewer.