Changeset 103236 in webkit


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

Web Inspector: Implement CSS selector profiler backend
https://bugs.webkit.org/show_bug.cgi?id=74603

Reviewed by Pavel Feldman.

No new tests, as the changed code does not result in visible effects yet.

  • inspector/Inspector.json:
  • inspector/InspectorCSSAgent.cpp:

(WebCore::RuleMatchingStats::RuleMatchingStats):
(WebCore::SelectorProfile::SelectorProfile):
(WebCore::SelectorProfile::~SelectorProfile):
(WebCore::SelectorProfile::totalMatchingTimeMs):
(WebCore::SelectorProfile::startSelector):
(WebCore::SelectorProfile::commitSelector):
(WebCore::SelectorProfile::commitSelectorTime):
(WebCore::SelectorProfile::toInspectorObject):
(WebCore::InspectorCSSAgent::clearFrontend):
(WebCore::InspectorCSSAgent::restore):
(WebCore::InspectorCSSAgent::startSelectorProfiler):
(WebCore::InspectorCSSAgent::stopSelectorProfiler):
(WebCore::InspectorCSSAgent::willMatchRule):
(WebCore::InspectorCSSAgent::didMatchRule):
(WebCore::InspectorCSSAgent::willProcessRule):
(WebCore::InspectorCSSAgent::didProcessRule):

  • inspector/InspectorCSSAgent.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r103235 r103236  
     12011-12-19  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Web Inspector: Implement CSS selector profiler backend
     4        https://bugs.webkit.org/show_bug.cgi?id=74603
     5
     6        Reviewed by Pavel Feldman.
     7
     8        No new tests, as the changed code does not result in visible effects yet.
     9
     10        * inspector/Inspector.json:
     11        * inspector/InspectorCSSAgent.cpp:
     12        (WebCore::RuleMatchingStats::RuleMatchingStats):
     13        (WebCore::SelectorProfile::SelectorProfile):
     14        (WebCore::SelectorProfile::~SelectorProfile):
     15        (WebCore::SelectorProfile::totalMatchingTimeMs):
     16        (WebCore::SelectorProfile::startSelector):
     17        (WebCore::SelectorProfile::commitSelector):
     18        (WebCore::SelectorProfile::commitSelectorTime):
     19        (WebCore::SelectorProfile::toInspectorObject):
     20        (WebCore::InspectorCSSAgent::clearFrontend):
     21        (WebCore::InspectorCSSAgent::restore):
     22        (WebCore::InspectorCSSAgent::startSelectorProfiler):
     23        (WebCore::InspectorCSSAgent::stopSelectorProfiler):
     24        (WebCore::InspectorCSSAgent::willMatchRule):
     25        (WebCore::InspectorCSSAgent::didMatchRule):
     26        (WebCore::InspectorCSSAgent::willProcessRule):
     27        (WebCore::InspectorCSSAgent::didProcessRule):
     28        * inspector/InspectorCSSAgent.h:
     29
    1302011-12-19  Alexander Pavlov  <apavlov@chromium.org>
    231
  • trunk/Source/WebCore/inspector/Inspector.json

    r103174 r103236  
    16141614                ],
    16151615                "description": "CSS media query descriptor."
     1616            },
     1617            {
     1618                "id": "SelectorProfileEntry",
     1619                "type": "object",
     1620                "properties": [
     1621                    { "name": "selector", "type": "string", "description": "CSS selector." },
     1622                    { "name": "time", "type": "number", "description": "Total time this selector handling contributed to the browser running time during profiling (in milliseconds.)" },
     1623                    { "name": "hitCount", "type": "integer", "description": "Number of times this selector was considered a candidate for matching against DOM elements." },
     1624                    { "name": "matchCount", "type": "integer", "description": "Number of times this selector actually matched a DOM element." }
     1625                ],
     1626                "description": "CSS selector profile entry."
     1627            },
     1628            {
     1629                "id": "SelectorProfile",
     1630                "type": "object",
     1631                "properties": [
     1632                    { "name": "totalTime", "type": "number", "description": "Total processing time for all selectors in the profile (in milliseconds.)" },
     1633                    { "name": "data", "type": "array", "items": { "$ref": "SelectorProfileEntry" }, "description": "CSS selector profile entries." }
     1634                ]
    16161635            }
    16171636        ],
     
    17501769                ],
    17511770                "description": "Returns all supported CSS property names."
     1771            },
     1772            {
     1773                "name": "startSelectorProfiler"
     1774            },
     1775            {
     1776                "name": "stopSelectorProfiler",
     1777                "returns": [
     1778                    { "name": "profile", "$ref": "SelectorProfile" }
     1779                ]
    17521780            }
    17531781        ],
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp

    r102903 r103236  
    4848#include "StyleSheetList.h"
    4949
     50#include <wtf/CurrentTime.h>
    5051#include <wtf/HashSet.h>
    5152#include <wtf/Vector.h>
     
    132133namespace CSSAgentState {
    133134static const char cssAgentEnabled[] = "cssAgentEnabled";
     135static const char isSelectorProfiling[] = "isSelectorProfiling";
    134136}
    135137
     
    143145    PseudoVisited = 1 << 3
    144146};
     147
     148struct RuleMatchingStats {
     149    RuleMatchingStats()
     150        : totalTime(0.0), hits(0), matches(0)
     151    {
     152    }
     153    RuleMatchingStats(double totalTime, unsigned hits, unsigned matches)
     154        : totalTime(totalTime), hits(hits), matches(matches)
     155    {
     156    }
     157    double totalTime;
     158    unsigned hits;
     159    unsigned matches;
     160};
     161
     162class SelectorProfile {
     163public:
     164    // FIXME: handle different rules with the same selector differently?
     165    SelectorProfile()
     166        : m_totalMatchingTimeMs(0.0)
     167    {
     168    }
     169    virtual ~SelectorProfile()
     170    {
     171    }
     172
     173    double totalMatchingTimeMs() const { return m_totalMatchingTimeMs; }
     174
     175    void startSelector(const String&);
     176    void commitSelector(bool);
     177    void commitSelectorTime();
     178    PassRefPtr<InspectorObject> toInspectorObject() const;
     179
     180private:
     181    typedef HashMap<String, RuleMatchingStats> RuleMatchingStatsMap;
     182    struct RuleMatchData {
     183        String selector;
     184        double startTime;
     185    };
     186
     187    double m_totalMatchingTimeMs;
     188    RuleMatchingStatsMap m_ruleMatchingStats;
     189    RuleMatchData m_currentMatchData;
     190};
     191
    145192
    146193static unsigned computePseudoClassMask(InspectorArray* pseudoClassArray)
     
    173220}
    174221
     222inline void SelectorProfile::startSelector(const String& selectorText)
     223{
     224    m_currentMatchData.selector = selectorText;
     225    m_currentMatchData.startTime = WTF::currentTimeMS();
     226}
     227
     228inline void SelectorProfile::commitSelector(bool matched)
     229{
     230    double matchTimeMs = WTF::currentTimeMS() - m_currentMatchData.startTime;
     231    m_totalMatchingTimeMs += matchTimeMs;
     232    pair<RuleMatchingStatsMap::iterator, bool> result = m_ruleMatchingStats.add(m_currentMatchData.selector, RuleMatchingStats(matchTimeMs, 1, matched ? 1 : 0));
     233    if (!result.second) {
     234        result.first->second.totalTime += matchTimeMs;
     235        result.first->second.hits += 1;
     236        if (matched)
     237            result.first->second.matches += 1;
     238    }
     239}
     240
     241inline void SelectorProfile::commitSelectorTime()
     242{
     243    double processingTimeMs = WTF::currentTimeMS() - m_currentMatchData.startTime;
     244    m_totalMatchingTimeMs += processingTimeMs;
     245    RuleMatchingStatsMap::iterator it = m_ruleMatchingStats.find(m_currentMatchData.selector);
     246    if (it == m_ruleMatchingStats.end())
     247        return;
     248
     249    it->second.totalTime += WTF::currentTimeMS() - m_currentMatchData.startTime;
     250}
     251
     252PassRefPtr<InspectorObject> SelectorProfile::toInspectorObject() const
     253{
     254    RefPtr<InspectorArray> data = InspectorArray::create();
     255    for (RuleMatchingStatsMap::const_iterator it = m_ruleMatchingStats.begin(); it != m_ruleMatchingStats.end(); ++it) {
     256        RefPtr<TypeBuilder::CSS::SelectorProfileEntry> stat = TypeBuilder::CSS::SelectorProfileEntry::create()
     257            .setSelector(it->first)
     258            .setTime(it->second.totalTime)
     259            .setHitCount(it->second.hits)
     260            .setMatchCount(it->second.matches);
     261        data->pushObject(stat.release());
     262    }
     263
     264    RefPtr<TypeBuilder::CSS::SelectorProfile> result = TypeBuilder::CSS::SelectorProfile::create()
     265        .setTotalTime(totalMatchingTimeMs())
     266        .setData(data);
     267    return result.release();
     268}
     269
    175270// static
    176271CSSStyleSheet* InspectorCSSAgent::parentStyleSheet(CSSRule* rule)
     
    220315    m_frontend = 0;
    221316    clearPseudoState(true);
    222     m_instrumentingAgents->setInspectorCSSAgent(0);
     317    String errorString;
     318    stopSelectorProfiler(&errorString);
    223319}
    224320
     
    234330        ErrorString error;
    235331        enable(&error);
     332    }
     333    if (m_state->getBoolean(CSSAgentState::isSelectorProfiling)) {
     334        String errorString;
     335        startSelectorProfiler(&errorString);
    236336    }
    237337}
     
    290390        element->ownerDocument()->styleSelectorChanged(RecalcStyleImmediately);
    291391}
    292 
    293392
    294393void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>* forcedPseudoClasses, bool* needPseudo, bool* needInherited, RefPtr<InspectorArray>* matchedCSSRules, RefPtr<InspectorArray>* pseudoIdRules, RefPtr<InspectorArray>* inheritedEntries)
     
    481580
    482581    *cssProperties = properties.release();
     582}
     583
     584void InspectorCSSAgent::startSelectorProfiler(ErrorString*)
     585{
     586    m_currentSelectorProfile = adoptPtr(new SelectorProfile());
     587    m_instrumentingAgents->setInspectorCSSAgent(this);
     588    m_state->setBoolean(CSSAgentState::isSelectorProfiling, true);
     589}
     590
     591void InspectorCSSAgent::stopSelectorProfiler(ErrorString*, RefPtr<InspectorObject>* result)
     592{
     593    if (!m_state->getBoolean(CSSAgentState::isSelectorProfiling))
     594        return;
     595    m_state->setBoolean(CSSAgentState::isSelectorProfiling, false);
     596    m_instrumentingAgents->setInspectorCSSAgent(0);
     597    if (m_frontend && result)
     598        *result = m_currentSelectorProfile->toInspectorObject();
     599    m_currentSelectorProfile.clear();
     600}
     601
     602void InspectorCSSAgent::willMatchRule(const CSSStyleRule* rule)
     603{
     604    m_currentSelectorProfile->startSelector(rule->selectorText());
     605}
     606
     607void InspectorCSSAgent::didMatchRule(bool matched)
     608{
     609    m_currentSelectorProfile->commitSelector(matched);
     610}
     611
     612void InspectorCSSAgent::willProcessRule(const CSSStyleRule* rule)
     613{
     614    m_currentSelectorProfile->startSelector(rule->selectorText());
     615}
     616
     617void InspectorCSSAgent::didProcessRule()
     618{
     619    m_currentSelectorProfile->commitSelectorTime();
    483620}
    484621
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.h

    r102903 r103236  
    5151class NameNodeMap;
    5252class Node;
     53class SelectorProfile;
    5354
    5455#if ENABLE(INSPECTOR)
     
    8990    void getSupportedCSSProperties(ErrorString*, RefPtr<InspectorArray>* result);
    9091
     92    void startSelectorProfiler(ErrorString*);
     93    void stopSelectorProfiler(ErrorString*, RefPtr<InspectorObject>* = 0);
     94    void willMatchRule(const CSSStyleRule*);
     95    void didMatchRule(bool);
     96    void willProcessRule(const CSSStyleRule*);
     97    void didProcessRule();
     98
    9199private:
    92100    InspectorCSSAgent(InstrumentingAgents*, InspectorState*, InspectorDOMAgent*);
     
    119127    InspectorFrontend::CSS* m_frontend;
    120128    InspectorDOMAgent* m_domAgent;
    121     RefPtr<Element> m_lastElementWithPseudoState;
    122     unsigned m_lastPseudoState;
    123129
    124130    IdToInspectorStyleSheet m_idToInspectorStyleSheet;
     
    127133    DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet;
    128134
     135    RefPtr<Element> m_lastElementWithPseudoState;
     136    unsigned m_lastPseudoState;
     137
    129138    int m_lastStyleSheetId;
    130139    int m_lastRuleId;
    131140    int m_lastStyleId;
     141
     142    OwnPtr<SelectorProfile> m_currentSelectorProfile;
    132143};
    133144
Note: See TracChangeset for help on using the changeset viewer.