Changeset 142281 in webkit


Ignore:
Timestamp:
Feb 8, 2013 8:04:28 AM (11 years ago)
Author:
yurys@chromium.org
Message:

Web Inspector: simplify Memory.getDOMNodeCount implementation
https://bugs.webkit.org/show_bug.cgi?id=108821

Reviewed by Alexander Pavlov.

Removed Memory.getDOMNodeCount command from the protocol. Memory.getDOMCounters
should be used instead.

  • inspector/Inspector.json:
  • inspector/InspectorMemoryAgent.cpp:
  • inspector/InspectorMemoryAgent.h:

(InspectorMemoryAgent):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r142278 r142281  
     12013-02-04  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Web Inspector: simplify Memory.getDOMNodeCount implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=108821
     5
     6        Reviewed by Alexander Pavlov.
     7
     8        Removed Memory.getDOMNodeCount command from the protocol. Memory.getDOMCounters
     9        should be used instead.
     10
     11        * inspector/Inspector.json:
     12        * inspector/InspectorMemoryAgent.cpp:
     13        * inspector/InspectorMemoryAgent.h:
     14        (InspectorMemoryAgent):
     15
    1162013-02-08  Yury Semikhatsky  <yurys@chromium.org>
    217
  • trunk/Source/WebCore/inspector/Inspector.json

    r142161 r142281  
    4444        "types": [
    4545            {
    46                 "id": "NodeCount",
    47                 "type": "object",
    48                 "properties": [
    49                     { "name": "nodeName", "type": "string" },
    50                     { "name": "count", "type": "integer" }
    51                 ],
    52                 "description": "Number of nodes with given name."
    53             },
    54             {
    55                 "id": "ListenerCount",
    56                 "type": "object",
    57                 "properties": [
    58                     { "name": "type", "type": "string" },
    59                     { "name": "count", "type": "integer" }
    60                 ],
    61                 "description": "Number of JS event listeners by event type."
    62             },
    63             {
    64                 "id": "StringStatistics",
    65                 "type": "object",
    66                 "properties": [
    67                     { "name": "dom", "type": "integer" },
    68                     { "name": "js", "type": "integer" },
    69                     { "name": "shared", "type": "integer" }
    70                 ],
    71                 "description": "Character data statistics for the page."
    72             },
    73             {
    74                 "id": "DOMGroup",
    75                 "type": "object",
    76                 "properties": [
    77                     { "name": "size", "type": "integer" },
    78                     { "name": "title", "type": "string" },
    79                     { "name": "documentURI", "type": "string", "optional": true },
    80                     { "name": "nodeCount", "type": "array", "items": { "$ref": "NodeCount" }},
    81                     { "name": "listenerCount", "type": "array", "items": { "$ref": "ListenerCount" }}
    82                 ]
    83             },
    84             {
    8546                "id": "MemoryBlock",
    8647                "type": "object",
     
    10364        ],
    10465        "commands": [
    105             {
    106                 "name": "getDOMNodeCount",
    107                 "returns": [
    108                     { "name": "domGroups", "type": "array", "items": { "$ref": "DOMGroup" }},
    109                     { "name": "strings", "$ref": "StringStatistics" }
    110                 ]
    111             },
    11266            {
    11367                "name": "getDOMCounters",
  • trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp

    r142086 r142281  
    6767#include <wtf/text/WTFString.h>
    6868
    69 using WebCore::TypeBuilder::Memory::DOMGroup;
    70 using WebCore::TypeBuilder::Memory::ListenerCount;
    71 using WebCore::TypeBuilder::Memory::NodeCount;
    72 using WebCore::TypeBuilder::Memory::StringStatistics;
    73 
    7469// Use a type alias instead of 'using' here which would cause a conflict on Mac.
    7570typedef WebCore::TypeBuilder::Memory::MemoryBlock InspectorMemoryBlock;
     
    150145};
    151146
    152 String nodeName(Node* node)
    153 {
    154     if (node->document()->isXHTMLDocument())
    155          return node->nodeName();
    156     return node->nodeName().lower();
    157 }
    158 
    159 typedef HashSet<StringImpl*, PtrHash<StringImpl*> > StringImplIdentitySet;
    160 
    161 class CharacterDataStatistics {
    162     WTF_MAKE_NONCOPYABLE(CharacterDataStatistics);
    163 public:
    164     CharacterDataStatistics() : m_characterDataSize(0) { }
    165 
    166     void collectCharacterData(Node* node)
    167     {
    168         if (!node->isCharacterDataNode())
    169             return;
    170 
    171         CharacterData* characterData = static_cast<CharacterData*>(node);
    172         StringImpl* dataImpl = characterData->dataImpl();
    173         if (m_domStringImplSet.contains(dataImpl))
    174             return;
    175         m_domStringImplSet.add(dataImpl);
    176 
    177         m_characterDataSize += dataImpl->sizeInBytes();
    178     }
    179 
    180     bool contains(StringImpl* s) { return m_domStringImplSet.contains(s); }
    181 
    182     int characterDataSize() { return m_characterDataSize; }
    183 
    184 private:
    185     StringImplIdentitySet m_domStringImplSet;
    186     int m_characterDataSize;
    187 };
    188 
    189 class DOMTreeStatistics {
    190     WTF_MAKE_NONCOPYABLE(DOMTreeStatistics);
    191 public:
    192     DOMTreeStatistics(Node* rootNode, CharacterDataStatistics& characterDataStatistics)
    193         : m_totalNodeCount(0)
    194         , m_characterDataStatistics(characterDataStatistics)
    195     {
    196         collectTreeStatistics(rootNode);
    197     }
    198 
    199     int totalNodeCount() { return m_totalNodeCount; }
    200 
    201     PassRefPtr<TypeBuilder::Array<TypeBuilder::Memory::NodeCount> > nodeCount()
    202     {
    203         RefPtr<TypeBuilder::Array<TypeBuilder::Memory::NodeCount> > childrenStats = TypeBuilder::Array<TypeBuilder::Memory::NodeCount>::create();
    204         for (HashMap<String, int>::iterator it = m_nodeNameToCount.begin(); it != m_nodeNameToCount.end(); ++it) {
    205             RefPtr<NodeCount> nodeCount = NodeCount::create().setNodeName(it->key)
    206                                                              .setCount(it->value);
    207             childrenStats->addItem(nodeCount);
    208         }
    209         return childrenStats.release();
    210     }
    211 
    212     PassRefPtr<TypeBuilder::Array<TypeBuilder::Memory::ListenerCount> > listenerCount()
    213     {
    214         RefPtr<TypeBuilder::Array<TypeBuilder::Memory::ListenerCount> > listenerStats = TypeBuilder::Array<TypeBuilder::Memory::ListenerCount>::create();
    215         for (HashMap<AtomicString, int>::iterator it = m_eventTypeToCount.begin(); it != m_eventTypeToCount.end(); ++it) {
    216             RefPtr<ListenerCount> listenerCount = ListenerCount::create().setType(it->key)
    217                                                                          .setCount(it->value);
    218             listenerStats->addItem(listenerCount);
    219         }
    220         return listenerStats.release();
    221     }
    222 
    223 private:
    224     void collectTreeStatistics(Node* rootNode)
    225     {
    226         Node* currentNode = rootNode;
    227         collectListenersInfo(rootNode);
    228         while ((currentNode = NodeTraversal::next(currentNode, rootNode))) {
    229             ++m_totalNodeCount;
    230             collectNodeStatistics(currentNode);
    231         }
    232     }
    233     void collectNodeStatistics(Node* node)
    234     {
    235         m_characterDataStatistics.collectCharacterData(node);
    236         collectNodeNameInfo(node);
    237         collectListenersInfo(node);
    238     }
    239 
    240     void collectNodeNameInfo(Node* node)
    241     {
    242         String name = nodeName(node);
    243         int currentCount = m_nodeNameToCount.get(name);
    244         m_nodeNameToCount.set(name, currentCount + 1);
    245     }
    246 
    247     void collectListenersInfo(Node* node)
    248     {
    249         EventTargetData* d = node->eventTargetData();
    250         if (!d)
    251             return;
    252         EventListenerMap& eventListenerMap = d->eventListenerMap;
    253         if (eventListenerMap.isEmpty())
    254             return;
    255         Vector<AtomicString> eventNames = eventListenerMap.eventTypes();
    256         for (Vector<AtomicString>::iterator it = eventNames.begin(); it != eventNames.end(); ++it) {
    257             AtomicString name = *it;
    258             EventListenerVector* listeners = eventListenerMap.find(name);
    259             int count = 0;
    260             for (EventListenerVector::iterator j = listeners->begin(); j != listeners->end(); ++j) {
    261                 if (j->listener->type() == EventListener::JSEventListenerType)
    262                     ++count;
    263             }
    264             if (count)
    265                 m_eventTypeToCount.set(name, m_eventTypeToCount.get(name) + count);
    266         }
    267     }
    268 
    269     int m_totalNodeCount;
    270     HashMap<AtomicString, int> m_eventTypeToCount;
    271     HashMap<String, int> m_nodeNameToCount;
    272     CharacterDataStatistics& m_characterDataStatistics;
    273 };
    274 
    275 class CounterVisitor : public WrappedNodeVisitor, public ExternalStringVisitor {
    276 public:
    277     CounterVisitor(Page* page)
    278         : m_page(page)
    279         , m_domGroups(TypeBuilder::Array<TypeBuilder::Memory::DOMGroup>::create())
    280         , m_jsExternalStringSize(0)
    281         , m_sharedStringSize(0) { }
    282 
    283     TypeBuilder::Array<TypeBuilder::Memory::DOMGroup>* domGroups() { return m_domGroups.get(); }
    284 
    285     PassRefPtr<StringStatistics> strings()
    286     {
    287         RefPtr<StringStatistics> stringStatistics = StringStatistics::create()
    288             .setDom(m_characterDataStatistics.characterDataSize())
    289             .setJs(m_jsExternalStringSize)
    290             .setShared(m_sharedStringSize);
    291         return stringStatistics.release();
    292     }
    293 
    294     virtual void visitNode(Node* node)
    295     {
    296         if (node->document()->frame() && m_page != node->document()->frame()->page())
    297             return;
    298 
    299         Node* rootNode = node;
    300         while (rootNode->parentNode())
    301             rootNode = rootNode->parentNode();
    302 
    303         if (m_roots.contains(rootNode))
    304             return;
    305         m_roots.add(rootNode);
    306 
    307         DOMTreeStatistics domTreeStats(rootNode, m_characterDataStatistics);
    308 
    309         RefPtr<DOMGroup> domGroup = DOMGroup::create()
    310             .setSize(domTreeStats.totalNodeCount())
    311             .setTitle(rootNode->nodeType() == Node::ELEMENT_NODE ? elementTitle(static_cast<Element*>(rootNode)) : rootNode->nodeName())
    312             .setNodeCount(domTreeStats.nodeCount())
    313             .setListenerCount(domTreeStats.listenerCount());
    314         if (rootNode->nodeType() == Node::DOCUMENT_NODE)
    315             domGroup->setDocumentURI(static_cast<Document*>(rootNode)->documentURI());
    316 
    317         m_domGroups->addItem(domGroup);
    318     }
    319 
    320     virtual void visitJSExternalString(StringImpl* string)
    321     {
    322         int size = string->sizeInBytes();
    323         m_jsExternalStringSize += size;
    324         if (m_characterDataStatistics.contains(string))
    325             m_sharedStringSize += size;
    326     }
    327 
    328 private:
    329     String elementTitle(Element* element)
    330     {
    331         StringBuilder result;
    332         result.append(nodeName(element));
    333 
    334         const AtomicString& idValue = element->getIdAttribute();
    335         String idString;
    336         if (!idValue.isNull() && !idValue.isEmpty()) {
    337             result.append("#");
    338             result.append(idValue);
    339         }
    340 
    341         HashSet<AtomicString> usedClassNames;
    342         if (element->hasClass() && element->isStyledElement()) {
    343             const SpaceSplitString& classNamesString = static_cast<StyledElement*>(element)->classNames();
    344             size_t classNameCount = classNamesString.size();
    345             for (size_t i = 0; i < classNameCount; ++i) {
    346                 const AtomicString& className = classNamesString[i];
    347                 if (usedClassNames.contains(className))
    348                     continue;
    349                 usedClassNames.add(className);
    350                 result.append(".");
    351                 result.append(className);
    352             }
    353         }
    354         return result.toString();
    355     }
    356 
    357     HashSet<Node*> m_roots;
    358     Page* m_page;
    359     RefPtr<TypeBuilder::Array<TypeBuilder::Memory::DOMGroup> > m_domGroups;
    360     CharacterDataStatistics m_characterDataStatistics;
    361     int m_jsExternalStringSize;
    362     int m_sharedStringSize;
    363 };
    364 
    365147class ExternalStringsRoot : public ExternalStringVisitor {
    366148public:
     
    411193InspectorMemoryAgent::~InspectorMemoryAgent()
    412194{
    413 }
    414 
    415 void InspectorMemoryAgent::getDOMNodeCount(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Memory::DOMGroup> >& domGroups, RefPtr<TypeBuilder::Memory::StringStatistics>& strings)
    416 {
    417     CounterVisitor counterVisitor(m_page);
    418     ScriptProfiler::visitNodeWrappers(&counterVisitor);
    419 
    420     // Make sure all documents reachable from the main frame are accounted.
    421     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    422         if (Document* doc = frame->document())
    423             counterVisitor.visitNode(doc);
    424     }
    425 
    426     ScriptProfiler::visitExternalStrings(&counterVisitor);
    427 
    428     domGroups = counterVisitor.domGroups();
    429     strings = counterVisitor.strings();
    430195}
    431196
  • trunk/Source/WebCore/inspector/InspectorMemoryAgent.h

    r142074 r142281  
    6060    virtual ~InspectorMemoryAgent();
    6161
    62     virtual void getDOMNodeCount(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Memory::DOMGroup> >& domGroups, RefPtr<TypeBuilder::Memory::StringStatistics>& strings);
    6362    virtual void getDOMCounters(ErrorString*, int* documents, int* nodes, int* jsEventListeners);
    6463    virtual void getProcessMemoryDistribution(ErrorString*, const bool* reportGraph, RefPtr<TypeBuilder::Memory::MemoryBlock>& processMemory);
Note: See TracChangeset for help on using the changeset viewer.