Diff
Modified: trunk/Source/WebCore/ChangeLog (102568 => 102569)
--- trunk/Source/WebCore/ChangeLog 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/ChangeLog 2011-12-12 13:09:50 UTC (rev 102569)
@@ -1,3 +1,34 @@
+2011-12-09 Yury Semikhatsky <[email protected]>
+
+ Web Inspector: provide per Document Node count statistics
+ https://bugs.webkit.org/show_bug.cgi?id=74100
+
+ Memory agent now returns counters for nodes with given names. For each
+ object group root user will see total number of its descendtants and per
+ tag name counts.
+
+ This patch also moves generic CounterVisitor code out of V8 bindings. It
+ may well be used with both JS engines.
+
+ Reviewed by Pavel Feldman.
+
+ * GNUmakefile.list.am:
+ * Target.pri:
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/ScriptProfiler.h:
+ (WebCore::ScriptProfiler::visitJSDOMWrappers):
+ * bindings/v8/ScriptProfiler.cpp:
+ (WebCore::ScriptProfiler::visitJSDOMWrappers):
+ * bindings/v8/ScriptProfiler.h:
+ * inspector/DOMWrapperVisitor.h: Added.
+ (WebCore::DOMWrapperVisitor::~DOMWrapperVisitor):
+ * inspector/Inspector.json:
+ * inspector/InspectorMemoryAgent.cpp:
+ (WebCore::InspectorMemoryAgent::getDOMNodeCount):
+ * inspector/InspectorMemoryAgent.h:
+
2011-12-12 Noel Gordon <[email protected]>
WebPImageDecoder: Increase image/webp decoding performance 10-20%
Modified: trunk/Source/WebCore/GNUmakefile.list.am (102568 => 102569)
--- trunk/Source/WebCore/GNUmakefile.list.am 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2011-12-12 13:09:50 UTC (rev 102569)
@@ -2027,6 +2027,7 @@
Source/WebCore/inspector/ContentSearchUtils.h \
Source/WebCore/inspector/DOMNodeHighlighter.cpp \
Source/WebCore/inspector/DOMNodeHighlighter.h \
+ Source/WebCore/inspector/DOMWrapperVisitor.h \
Source/WebCore/inspector/IdentifiersFactory.cpp \
Source/WebCore/inspector/IdentifiersFactory.h \
Source/WebCore/inspector/InjectedScript.cpp \
Modified: trunk/Source/WebCore/Target.pri (102568 => 102569)
--- trunk/Source/WebCore/Target.pri 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/Target.pri 2011-12-12 13:09:50 UTC (rev 102569)
@@ -1894,6 +1894,7 @@
inspector/ConsoleMessage.h \
inspector/ContentSearchUtils.h \
inspector/DOMNodeHighlighter.h \
+ inspector/DOMWrapperVisitor.h \
inspector/IdentifiersFactory.h \
inspector/InjectedScript.h \
inspector/InjectedScriptHost.h \
Modified: trunk/Source/WebCore/WebCore.gypi (102568 => 102569)
--- trunk/Source/WebCore/WebCore.gypi 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/WebCore.gypi 2011-12-12 13:09:50 UTC (rev 102569)
@@ -2724,6 +2724,7 @@
'inspector/ContentSearchUtils.h',
'inspector/DOMNodeHighlighter.cpp',
'inspector/DOMNodeHighlighter.h',
+ 'inspector/DOMWrapperVisitor.h',
'inspector/IdentifiersFactory.cpp',
'inspector/IdentifiersFactory.h',
'inspector/InjectedScript.cpp',
Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (102568 => 102569)
--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2011-12-12 13:09:50 UTC (rev 102569)
@@ -68458,6 +68458,10 @@
>
</File>
<File
+ RelativePath="..\inspector\DOMWrapperVisitor.h"
+ >
+ </File>
+ <File
RelativePath="..\inspector\IdentifiersFactory.cpp"
>
</File>
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (102568 => 102569)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2011-12-12 13:09:50 UTC (rev 102569)
@@ -6027,6 +6027,7 @@
F34742E81343635000531BC2 /* WorkerScriptDebugServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F34742E61343635000531BC2 /* WorkerScriptDebugServer.cpp */; };
F34742E91343635000531BC2 /* WorkerScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = F34742E71343635000531BC2 /* WorkerScriptDebugServer.h */; };
F350B73513F1377D00880C43 /* InstrumentingAgents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F350B73413F1377D00880C43 /* InstrumentingAgents.cpp */; };
+ F35AE5AC14925F5B004D5776 /* DOMWrapperVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = F35AE5AB14925F5B004D5776 /* DOMWrapperVisitor.h */; };
F3644AFF1119805900E0D537 /* InjectedScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3644AFD1119805900E0D537 /* InjectedScript.cpp */; };
F3644B001119805900E0D537 /* InjectedScript.h in Headers */ = {isa = PBXBuildFile; fileRef = F3644AFE1119805900E0D537 /* InjectedScript.h */; };
F36E07A41358A8BE00AACBC9 /* WorkerInspectorController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F36E07A21358A8BE00AACBC9 /* WorkerInspectorController.cpp */; };
@@ -13411,6 +13412,7 @@
F34742E61343635000531BC2 /* WorkerScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerScriptDebugServer.cpp; sourceTree = "<group>"; };
F34742E71343635000531BC2 /* WorkerScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerScriptDebugServer.h; sourceTree = "<group>"; };
F350B73413F1377D00880C43 /* InstrumentingAgents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InstrumentingAgents.cpp; sourceTree = "<group>"; };
+ F35AE5AB14925F5B004D5776 /* DOMWrapperVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMWrapperVisitor.h; sourceTree = "<group>"; };
F3644AFD1119805900E0D537 /* InjectedScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedScript.cpp; sourceTree = "<group>"; };
F3644AFE1119805900E0D537 /* InjectedScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedScript.h; sourceTree = "<group>"; };
F36E07A21358A8BE00AACBC9 /* WorkerInspectorController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerInspectorController.cpp; sourceTree = "<group>"; };
@@ -14530,6 +14532,7 @@
59102FBA14327D3B003C9D04 /* ContentSearchUtils.h */,
4F1442261339FD6200E0D6F8 /* DOMNodeHighlighter.cpp */,
4F1442271339FD6200E0D6F8 /* DOMNodeHighlighter.h */,
+ F35AE5AB14925F5B004D5776 /* DOMWrapperVisitor.h */,
5913A23F13D49EBA00F5B05C /* IdentifiersFactory.cpp */,
5913A24013D49EBA00F5B05C /* IdentifiersFactory.h */,
F3644AFD1119805900E0D537 /* InjectedScript.cpp */,
@@ -24805,6 +24808,7 @@
265541391489811C000DFC5D /* KeyEventCodesIOS.h in Headers */,
8A195932147EA16E00D1EA61 /* DOMWebKitNamedFlow.h in Headers */,
8A195934147EA16E00D1EA61 /* DOMWebKitNamedFlowInternal.h in Headers */,
+ F35AE5AC14925F5B004D5776 /* DOMWrapperVisitor.h in Headers */,
26C17A3E1491D2D400D12BA2 /* FileSystemIOS.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
Modified: trunk/Source/WebCore/bindings/js/ScriptProfiler.h (102568 => 102569)
--- trunk/Source/WebCore/bindings/js/ScriptProfiler.h 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/bindings/js/ScriptProfiler.h 2011-12-12 13:09:50 UTC (rev 102569)
@@ -37,8 +37,8 @@
namespace WebCore {
+class DOMWrapperVisitor;
class InjectedScriptManager;
-class Page;
class ScriptProfiler {
WTF_MAKE_NONCOPYABLE(ScriptProfiler);
@@ -61,7 +61,7 @@
static bool isSampling() { return false; }
static bool hasHeapProfiler() { return false; }
// FIXME: Implement this counter for JSC. See bug 73936 for more details.
- static PassRefPtr<InspectorArray> domNodeCount(Page*) { return 0; };
+ static void visitJSDOMWrappers(DOMWrapperVisitor*) { }
};
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp (102568 => 102569)
--- trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp 2011-12-12 13:09:50 UTC (rev 102569)
@@ -31,14 +31,13 @@
#include "config.h"
#include "ScriptProfiler.h"
-#include "DOMNodeHighlighter.h"
+#include "DOMWrapperVisitor.h"
#include "InjectedScript.h"
#include "InspectorValues.h"
#include "RetainedDOMInfo.h"
#include "V8Binding.h"
#include "V8DOMMap.h"
#include "V8Node.h"
-#include <wtf/text/StringBuilder.h>
#include <v8-profiler.h>
@@ -148,83 +147,20 @@
#endif // ENABLE(INSPECTOR)
}
-namespace {
+void ScriptProfiler::visitJSDOMWrappers(DOMWrapperVisitor* visitor)
+{
+ class VisitorAdapter : public DOMWrapperMap<Node>::Visitor {
+ public:
+ VisitorAdapter(DOMWrapperVisitor* visitor) : m_visitor(visitor) { }
-class CounterVisitor : public DOMWrapperMap<Node>::Visitor {
-public:
- CounterVisitor(Page* page, InspectorArray* counters) : m_page(page), m_counters(counters) { }
-
- void visitDOMWrapper(DOMDataStore* store, Node* node, v8::Persistent<v8::Object> wrapper)
- {
- if (node->document()->frame() && m_page != node->document()->frame()->page())
- return;
-
- Node* rootNode = node;
- while (rootNode->parentNode())
- rootNode = rootNode->parentNode();
-
- if (m_roots.contains(rootNode))
- return;
- m_roots.add(rootNode);
-
- unsigned count = 0;
- Node* currentNode = rootNode;
- while ((currentNode = currentNode->traverseNextNode(rootNode)))
- ++count;
-
- RefPtr<InspectorObject> entry = InspectorObject::create();
- entry->setNumber("size", count);
-
- entry->setString("title", rootNode->nodeType() == Node::ELEMENT_NODE ? elementTitle(static_cast<Element*>(rootNode)) : rootNode->nodeName());
- if (rootNode->nodeType() == Node::DOCUMENT_NODE)
- entry->setString("documentURI", static_cast<Document*>(rootNode)->documentURI());
- m_counters->pushObject(entry);
- }
-
-private:
- String elementTitle(Element* element)
- {
- StringBuilder result;
- bool isXHTML = element->document()->isXHTMLDocument();
- result.append(isXHTML ? element->nodeName() : element->nodeName().lower());
-
- const AtomicString& idValue = element->getIdAttribute();
- String idString;
- if (!idValue.isNull() && !idValue.isEmpty()) {
- result.append("#");
- result.append(idValue);
+ virtual void visitDOMWrapper(DOMDataStore*, Node* node, v8::Persistent<v8::Object>)
+ {
+ m_visitor->visitNode(node);
}
-
- HashSet<AtomicString> usedClassNames;
- if (element->hasClass() && element->isStyledElement()) {
- const SpaceSplitString& classNamesString = static_cast<StyledElement*>(element)->classNames();
- size_t classNameCount = classNamesString.size();
- for (size_t i = 0; i < classNameCount; ++i) {
- const AtomicString& className = classNamesString[i];
- if (usedClassNames.contains(className))
- continue;
- usedClassNames.add(className);
- result.append(".");
- result.append(className);
- }
- }
- return result.toString();
- }
-
- HashSet<Node*> m_roots;
- Page* m_page;
- InspectorArray* m_counters;
-};
-
-} // namespace
-
-PassRefPtr<InspectorArray> ScriptProfiler::domNodeCount(Page* page)
-{
- RefPtr<InspectorArray> result = InspectorArray::create();
- CounterVisitor counterVisitor(page, result.get());
- visitDOMNodes(&counterVisitor);
- return result;
+ private:
+ DOMWrapperVisitor* m_visitor;
+ } adapter(visitor);
+ visitDOMNodes(&adapter);
}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/v8/ScriptProfiler.h (102568 => 102569)
--- trunk/Source/WebCore/bindings/v8/ScriptProfiler.h 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/bindings/v8/ScriptProfiler.h 2011-12-12 13:09:50 UTC (rev 102569)
@@ -41,8 +41,8 @@
namespace WebCore {
+class DOMWrapperVisitor;
class InjectedScriptManager;
-class Page;
class ScriptProfiler {
WTF_MAKE_NONCOPYABLE(ScriptProfiler);
@@ -65,7 +65,7 @@
static bool isSampling() { return true; }
static bool hasHeapProfiler() { return true; }
static void initialize();
- static PassRefPtr<InspectorArray> domNodeCount(Page*);
+ static void visitJSDOMWrappers(DOMWrapperVisitor*);
};
} // namespace WebCore
Added: trunk/Source/WebCore/inspector/DOMWrapperVisitor.h (0 => 102569)
--- trunk/Source/WebCore/inspector/DOMWrapperVisitor.h (rev 0)
+++ trunk/Source/WebCore/inspector/DOMWrapperVisitor.h 2011-12-12 13:09:50 UTC (rev 102569)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMWrapperVisitor_h
+#define DOMWrapperVisitor_h
+
+namespace WebCore {
+
+class Node;
+
+class DOMWrapperVisitor {
+public:
+ virtual void visitNode(Node*) = 0;
+protected:
+ virtual ~DOMWrapperVisitor() { }
+};
+
+} // namespace WebCore
+
+#endif // DOMWrapperVisitor_h
Property changes on: trunk/Source/WebCore/inspector/DOMWrapperVisitor.h
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/inspector/Inspector.json (102568 => 102569)
--- trunk/Source/WebCore/inspector/Inspector.json 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/inspector/Inspector.json 2011-12-12 13:09:50 UTC (rev 102569)
@@ -50,11 +50,22 @@
"hidden": true,
"types": [
{
+ "id": "NodeCount",
+ "type": "object",
+ "properties": [
+ { "name": "nodeName", "type": "string" },
+ { "name": "count", "type": "integer" }
+ ],
+ "description": "Number of nodes with given name."
+ },
+ {
"id": "DOMGroup",
"type": "object",
"properties": [
{ "name": "size", "type": "integer" },
- { "name": "title", "type": "string" }
+ { "name": "title", "type": "string" },
+ { "name": "documentURI", "type": "string", "optional": true },
+ { "name": "nodeCount", "type": "array", "items": { "$ref": "NodeCount" }}
]
}
],
Modified: trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp (102568 => 102569)
--- trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp 2011-12-12 13:09:50 UTC (rev 102569)
@@ -1,55 +1,165 @@
/*
-* Copyright (C) 2011 Google Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following disclaimer
-* in the documentation and/or other materials provided with the
-* distribution.
-* * Neither the name of Google Inc. nor the names of its
-* contributors may be used to endorse or promote products derived from
-* this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
#include "config.h"
#include "InspectorMemoryAgent.h"
#if ENABLE(INSPECTOR)
+#include "DOMWrapperVisitor.h"
+#include "Document.h"
+#include "Frame.h"
#include "InspectorState.h"
#include "InspectorValues.h"
#include "InstrumentingAgents.h"
#include "Node.h"
#include "Page.h"
#include "ScriptProfiler.h"
+#include "StyledElement.h"
#include <wtf/HashSet.h>
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
+namespace {
+
+class CounterVisitor : public DOMWrapperVisitor {
+public:
+ CounterVisitor(Page* page) : m_page(page), m_counters(InspectorArray::create()) { }
+
+ InspectorArray* counters() { return m_counters.get(); }
+
+ virtual void visitNode(Node* node)
+ {
+ if (node->document()->frame() && m_page != node->document()->frame()->page())
+ return;
+
+ Node* rootNode = node;
+ while (rootNode->parentNode())
+ rootNode = rootNode->parentNode();
+
+ if (m_roots.contains(rootNode))
+ return;
+ m_roots.add(rootNode);
+
+ RefPtr<InspectorObject> entry = InspectorObject::create();
+ entry->setString("title", rootNode->nodeType() == Node::ELEMENT_NODE ? elementTitle(static_cast<Element*>(rootNode)) : rootNode->nodeName());
+ if (rootNode->nodeType() == Node::DOCUMENT_NODE)
+ entry->setString("documentURI", static_cast<Document*>(rootNode)->documentURI());
+ collectTreeStatistics(rootNode, entry.get());
+ m_counters->pushObject(entry);
+ }
+
+private:
+ static void collectTreeStatistics(Node* rootNode, InspectorObject* result)
+ {
+ unsigned count = 0;
+ HashMap<String, int> nameToCount;
+ Node* currentNode = rootNode;
+ while ((currentNode = currentNode->traverseNextNode(rootNode))) {
+ ++count;
+ String name = nodeName(currentNode);
+ int currentCount = nameToCount.get(name);
+ nameToCount.set(name, currentCount + 1);
+ }
+
+ RefPtr<InspectorArray> childrenStats = InspectorArray::create();
+ for (HashMap<String, int>::iterator it = nameToCount.begin(); it != nameToCount.end(); ++it) {
+ RefPtr<InspectorObject> nodeCount = InspectorObject::create();
+ nodeCount->setString("nodeName", it->first);
+ nodeCount->setNumber("count", it->second);
+ childrenStats->pushObject(nodeCount);
+ }
+
+ result->setNumber("size", count);
+ result->setArray("nodeCount", childrenStats);
+ }
+
+ static String nodeName(Node* node)
+ {
+ if (node->document()->isXHTMLDocument())
+ return node->nodeName();
+ return node->nodeName().lower();
+ }
+
+ String elementTitle(Element* element)
+ {
+ StringBuilder result;
+ result.append(nodeName(element));
+
+ const AtomicString& idValue = element->getIdAttribute();
+ String idString;
+ if (!idValue.isNull() && !idValue.isEmpty()) {
+ result.append("#");
+ result.append(idValue);
+ }
+
+ HashSet<AtomicString> usedClassNames;
+ if (element->hasClass() && element->isStyledElement()) {
+ const SpaceSplitString& classNamesString = static_cast<StyledElement*>(element)->classNames();
+ size_t classNameCount = classNamesString.size();
+ for (size_t i = 0; i < classNameCount; ++i) {
+ const AtomicString& className = classNamesString[i];
+ if (usedClassNames.contains(className))
+ continue;
+ usedClassNames.add(className);
+ result.append(".");
+ result.append(className);
+ }
+ }
+ return result.toString();
+ }
+
+ HashSet<Node*> m_roots;
+ Page* m_page;
+ RefPtr<InspectorArray> m_counters;
+};
+
+} // namespace
+
InspectorMemoryAgent::~InspectorMemoryAgent()
{
}
void InspectorMemoryAgent::getDOMNodeCount(ErrorString*, RefPtr<InspectorArray>* result)
{
- *result = ScriptProfiler::domNodeCount(m_page);
+ CounterVisitor counterVisitor(m_page);
+ ScriptProfiler::visitJSDOMWrappers(&counterVisitor);
+
+ // Make sure all documents reachable from the main frame are accounted.
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (Document* doc = frame->document())
+ counterVisitor.visitNode(doc);
+ }
+
+ *result = counterVisitor.counters();
}
InspectorMemoryAgent::InspectorMemoryAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state, Page* page, InspectorDOMAgent* domAgent)
Modified: trunk/Source/WebCore/inspector/InspectorMemoryAgent.h (102568 => 102569)
--- trunk/Source/WebCore/inspector/InspectorMemoryAgent.h 2011-12-12 13:08:57 UTC (rev 102568)
+++ trunk/Source/WebCore/inspector/InspectorMemoryAgent.h 2011-12-12 13:09:50 UTC (rev 102569)
@@ -1,32 +1,32 @@
/*
-* Copyright (C) 2011 Google Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following disclaimer
-* in the documentation and/or other materials provided with the
-* distribution.
-* * Neither the name of Google Inc. nor the names of its
-* contributors may be used to endorse or promote products derived from
-* this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef InspectorMemoryAgent_h
#define InspectorMemoryAgent_h