Changeset 142281 in webkit
- Timestamp:
- Feb 8, 2013 8:04:28 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r142278 r142281 1 2013-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 1 16 2013-02-08 Yury Semikhatsky <yurys@chromium.org> 2 17 -
trunk/Source/WebCore/inspector/Inspector.json
r142161 r142281 44 44 "types": [ 45 45 { 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 {85 46 "id": "MemoryBlock", 86 47 "type": "object", … … 103 64 ], 104 65 "commands": [ 105 {106 "name": "getDOMNodeCount",107 "returns": [108 { "name": "domGroups", "type": "array", "items": { "$ref": "DOMGroup" }},109 { "name": "strings", "$ref": "StringStatistics" }110 ]111 },112 66 { 113 67 "name": "getDOMCounters", -
trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp
r142086 r142281 67 67 #include <wtf/text/WTFString.h> 68 68 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 74 69 // Use a type alias instead of 'using' here which would cause a conflict on Mac. 75 70 typedef WebCore::TypeBuilder::Memory::MemoryBlock InspectorMemoryBlock; … … 150 145 }; 151 146 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 365 147 class ExternalStringsRoot : public ExternalStringVisitor { 366 148 public: … … 411 193 InspectorMemoryAgent::~InspectorMemoryAgent() 412 194 { 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();430 195 } 431 196 -
trunk/Source/WebCore/inspector/InspectorMemoryAgent.h
r142074 r142281 60 60 virtual ~InspectorMemoryAgent(); 61 61 62 virtual void getDOMNodeCount(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Memory::DOMGroup> >& domGroups, RefPtr<TypeBuilder::Memory::StringStatistics>& strings);63 62 virtual void getDOMCounters(ErrorString*, int* documents, int* nodes, int* jsEventListeners); 64 63 virtual void getProcessMemoryDistribution(ErrorString*, const bool* reportGraph, RefPtr<TypeBuilder::Memory::MemoryBlock>& processMemory);
Note: See TracChangeset
for help on using the changeset viewer.