Web Inspector: add v8 bindings memory info to the native memory graph
authoryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Jul 2012 07:04:41 +0000 (07:04 +0000)
committeryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Jul 2012 07:04:41 +0000 (07:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=90149

Reviewed by Pavel Feldman.

Size of V8 binding maps is now reported on the memory chart.

* bindings/js/ScriptProfiler.h:
(WebCore::ScriptProfiler::collectBindingMemoryInfo):
* bindings/v8/DOMDataStore.cpp:
(WebCore::DOMDataStore::reportMemoryUsage):
(WebCore):
* bindings/v8/DOMDataStore.h:
(WebCore):
(DOMDataStore):
* bindings/v8/IntrusiveDOMWrapperMap.h:
(WebCore::ChunkedTable::reportMemoryUsage):
(ChunkedTable):
* bindings/v8/ScriptProfiler.cpp:
(WebCore::ScriptProfiler::collectBindingMemoryInfo):
(WebCore):
* bindings/v8/ScriptProfiler.h:
(WebCore):
(ScriptProfiler):
* bindings/v8/V8Binding.cpp:
(WebCore::V8BindingPerIsolateData::reportMemoryUsage):
(WebCore):
(WebCore::StringCache::reportMemoryUsage):
* bindings/v8/V8Binding.h:
(WebCore):
(StringCache):
(V8BindingPerIsolateData):
* bindings/v8/V8DOMMap.h:
(WebCore):
(AbstractWeakReferenceMap):
* dom/MemoryInstrumentation.h:
(MemoryInstrumentation):
(WebCore):
(WebCore::MemoryInstrumentation::reportHashMap): added a method for reporting
size of a HashMap.
* inspector/InspectorMemoryAgent.cpp:
(MemoryBlockName):
(WebCore):
(WebCore::domTreeInfo):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121658 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/ScriptProfiler.h
Source/WebCore/bindings/v8/DOMDataStore.cpp
Source/WebCore/bindings/v8/DOMDataStore.h
Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h
Source/WebCore/bindings/v8/ScriptProfiler.cpp
Source/WebCore/bindings/v8/ScriptProfiler.h
Source/WebCore/bindings/v8/V8Binding.cpp
Source/WebCore/bindings/v8/V8Binding.h
Source/WebCore/bindings/v8/V8DOMMap.h
Source/WebCore/dom/MemoryInstrumentation.h
Source/WebCore/inspector/InspectorMemoryAgent.cpp

index bb250c8..67835c6 100644 (file)
@@ -1,3 +1,50 @@
+2012-06-28  Yury Semikhatsky  <yurys@chromium.org>
+
+        Web Inspector: add v8 bindings memory info to the native memory graph
+        https://bugs.webkit.org/show_bug.cgi?id=90149
+
+        Reviewed by Pavel Feldman.
+
+        Size of V8 binding maps is now reported on the memory chart.
+
+        * bindings/js/ScriptProfiler.h:
+        (WebCore::ScriptProfiler::collectBindingMemoryInfo):
+        * bindings/v8/DOMDataStore.cpp:
+        (WebCore::DOMDataStore::reportMemoryUsage):
+        (WebCore):
+        * bindings/v8/DOMDataStore.h:
+        (WebCore):
+        (DOMDataStore):
+        * bindings/v8/IntrusiveDOMWrapperMap.h:
+        (WebCore::ChunkedTable::reportMemoryUsage):
+        (ChunkedTable):
+        * bindings/v8/ScriptProfiler.cpp:
+        (WebCore::ScriptProfiler::collectBindingMemoryInfo):
+        (WebCore):
+        * bindings/v8/ScriptProfiler.h:
+        (WebCore):
+        (ScriptProfiler):
+        * bindings/v8/V8Binding.cpp:
+        (WebCore::V8BindingPerIsolateData::reportMemoryUsage):
+        (WebCore):
+        (WebCore::StringCache::reportMemoryUsage):
+        * bindings/v8/V8Binding.h:
+        (WebCore):
+        (StringCache):
+        (V8BindingPerIsolateData):
+        * bindings/v8/V8DOMMap.h:
+        (WebCore):
+        (AbstractWeakReferenceMap):
+        * dom/MemoryInstrumentation.h:
+        (MemoryInstrumentation):
+        (WebCore):
+        (WebCore::MemoryInstrumentation::reportHashMap): added a method for reporting
+        size of a HashMap.
+        * inspector/InspectorMemoryAgent.cpp:
+        (MemoryBlockName):
+        (WebCore):
+        (WebCore::domTreeInfo):
+
 2012-07-01  Christophe Dumez  <christophe.dumez@intel.com>
 
         [EFL] Add Gamepad support
index 5768535..782eac8 100644 (file)
@@ -38,6 +38,7 @@ namespace WebCore {
 
 class ExternalArrayVisitor;
 class ExternalStringVisitor;
+class MemoryInstrumentation;
 class NodeWrapperVisitor;
 class Page;
 class ScriptObject;
@@ -75,8 +76,10 @@ public:
     static bool hasHeapProfiler() { return false; }
     // FIXME: Implement this counter for JSC. See bug 73936 for more details.
     static void visitNodeWrappers(NodeWrapperVisitor*) { }
+    // FIXME: Support these methods for JSC. See bug 90358.
     static void visitExternalStrings(ExternalStringVisitor*) { }
     static void visitExternalArrays(ExternalArrayVisitor*) { }
+    static void collectBindingMemoryInfo(MemoryInstrumentation*) { }
     static size_t profilerSnapshotsSize() { return 0; }
 };
 
index 2d5b5e6..dbca395 100644 (file)
@@ -32,6 +32,7 @@
 #include "DOMDataStore.h"
 
 #include "DOMData.h"
+#include "MemoryInstrumentation.h"
 #include "V8Binding.h"
 #include <wtf/MainThread.h>
 
@@ -118,6 +119,15 @@ void* DOMDataStore::getDOMWrapperMap(DOMWrapperMapType type)
     return 0;
 }
 
+void DOMDataStore::reportMemoryUsage(MemoryInstrumentation* instrumentation)
+{
+    instrumentation->reportPointer(this, MemoryInstrumentation::Binding);
+    domNodeMap().reportMemoryUsage(instrumentation);
+    activeDomNodeMap().reportMemoryUsage(instrumentation);
+    domObjectMap().reportMemoryUsage(instrumentation);
+    activeDomObjectMap().reportMemoryUsage(instrumentation);
+}
+
 // Called when the object is near death (not reachable from JS roots).
 // It is time to remove the entry from the table and dispose the handle.
 void DOMDataStore::weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
index 089d86d..b5bdfc3 100644 (file)
@@ -47,6 +47,7 @@ namespace WebCore {
 
     class DOMData;
     class DOMDataStore;
+    class MemoryInstrumentation;
 
     typedef WTF::Vector<DOMDataStore*> DOMDataList;
 
@@ -86,6 +87,8 @@ namespace WebCore {
         static void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
         static void weakNodeCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
 
+        void reportMemoryUsage(MemoryInstrumentation*);
+
     protected:
         static void weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
 
index 5c066f0..5d61668 100644 (file)
@@ -32,6 +32,7 @@
 #define IntrusiveDOMWrapperMap_h
 
 #include "DOMDataStore.h"
+#include "MemoryInstrumentation.h"
 #include "V8Node.h"
 
 namespace WebCore {
@@ -101,6 +102,12 @@ class ChunkedTable {
             visitEntries(store, chunk->m_entries, chunk->m_entries + CHUNK_SIZE, visitor);
     }
 
+    void reportMemoryUsage(MemoryInstrumentation* instrumentation)
+    {
+        for (Chunk* chunk = m_chunks; chunk; chunk = chunk->m_previous)
+            instrumentation->reportPointer(chunk, MemoryInstrumentation::Binding);
+    }
+
   private:
     struct Chunk {
         explicit Chunk(Chunk* previous) : m_previous(previous) { }
@@ -176,6 +183,12 @@ public:
         m_table.clear();
     }
 
+    virtual void reportMemoryUsage(MemoryInstrumentation* instrumentation) OVERRIDE
+    {
+        instrumentation->reportPointer(this, MemoryInstrumentation::Binding);
+        m_table.reportMemoryUsage(instrumentation);
+    }
+
 private:
     static int const numberOfEntries = (1 << 10) - 1;
 
index 57bb808..8d6c502 100644 (file)
@@ -33,6 +33,7 @@
 #include "ScriptProfiler.h"
 
 #include "BindingVisitors.h"
+#include "MemoryInstrumentation.h"
 #include "RetainedDOMInfo.h"
 #include "ScriptObject.h"
 #include "V8ArrayBufferView.h"
@@ -219,6 +220,14 @@ void ScriptProfiler::visitExternalArrays(ExternalArrayVisitor* visitor)
 
 }
 
+void ScriptProfiler::collectBindingMemoryInfo(MemoryInstrumentation* instrumentation)
+{
+    V8BindingPerIsolateData* data = V8BindingPerIsolateData::current();
+    if (!data)
+        return;
+    data->reportMemoryUsage(instrumentation);
+}
+
 size_t ScriptProfiler::profilerSnapshotsSize()
 {
     return v8::HeapProfiler::GetMemorySizeUsedByProfiler();
index 25f6e12..7ffa50d 100644 (file)
@@ -42,6 +42,7 @@ namespace WebCore {
 
 class ExternalArrayVisitor;
 class ExternalStringVisitor;
+class MemoryInstrumentation;
 class NodeWrapperVisitor;
 class Page;
 class ScriptObject;
@@ -81,6 +82,7 @@ public:
     static void visitNodeWrappers(NodeWrapperVisitor*);
     static void visitExternalStrings(ExternalStringVisitor*);
     static void visitExternalArrays(ExternalArrayVisitor*);
+    static void collectBindingMemoryInfo(MemoryInstrumentation*);
     static size_t profilerSnapshotsSize();
 };
 
index aca0bb3..c29bcf8 100644 (file)
@@ -34,6 +34,7 @@
 #include "BindingVisitors.h"
 #include "DOMStringList.h"
 #include "Element.h"
+#include "MemoryInstrumentation.h"
 #include "PlatformString.h"
 #include "QualifiedName.h"
 #include "V8DOMStringList.h"
@@ -89,7 +90,16 @@ void V8BindingPerIsolateData::dispose(v8::Isolate* isolate)
     isolate->SetData(0);
 }
 
+void V8BindingPerIsolateData::reportMemoryUsage(MemoryInstrumentation* instrumentation)
+{
+    instrumentation->reportPointer(this, MemoryInstrumentation::Binding);
+    instrumentation->reportHashMap(m_rawTemplates, MemoryInstrumentation::Binding);
+    instrumentation->reportHashMap(m_templates, MemoryInstrumentation::Binding);
+    m_stringCache.reportMemoryUsage(instrumentation);
 
+    for (size_t i = 0; i < m_domDataList.size(); i++)
+        m_domDataList[i]->reportMemoryUsage(instrumentation);
+}
 
 // WebCoreStringResource is a helper class for v8ExternalString. It is used
 // to manage the life-cycle of the underlying buffer of the external string.
@@ -576,6 +586,11 @@ v8::Persistent<v8::FunctionTemplate> getToStringTemplate()
         toStringTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(constructorToString));
     return toStringTemplate;
 }
+
+void StringCache::reportMemoryUsage(MemoryInstrumentation* instrumentation)
+{
+    instrumentation->reportHashMap(m_stringCache, MemoryInstrumentation::Binding);
+}
     
 PassRefPtr<DOMStringList> v8ValueToWebCoreDOMStringList(v8::Handle<v8::Value> value)
 {
index 07c6615..4e45f7b 100644 (file)
@@ -49,6 +49,7 @@ namespace WebCore {
     class EventListener;
     class EventTarget;
     class ExternalStringVisitor;
+    class MemoryInstrumentation;
 
     // FIXME: Remove V8Binding.
     class V8Binding {
@@ -78,6 +79,8 @@ namespace WebCore {
 
         void remove(StringImpl*);
 
+        void reportMemoryUsage(MemoryInstrumentation*);
+
     private:
         v8::Local<v8::String> v8ExternalStringSlow(StringImpl*, v8::Isolate*);
 
@@ -214,6 +217,8 @@ namespace WebCore {
 
         GCEventData& gcEventData() { return m_gcEventData; }
 
+        void reportMemoryUsage(MemoryInstrumentation*);
+
     private:
         explicit V8BindingPerIsolateData(v8::Isolate*);
         ~V8BindingPerIsolateData();
index bc51540..531d07d 100644 (file)
@@ -31,6 +31,7 @@
 #ifndef V8DOMMap_h
 #define V8DOMMap_h
 
+#include "MemoryInstrumentation.h"
 #include <wtf/HashMap.h>
 #include <wtf/OwnPtr.h>
 #include <v8.h>
@@ -38,6 +39,7 @@
 namespace WebCore {
     class DOMDataStore;
     class Node;
+    class MemoryInstrumentation;
 
     template <class KeyType, class ValueType> class AbstractWeakReferenceMap {
     public:
@@ -61,6 +63,9 @@ namespace WebCore {
         virtual void clear() = 0;
 
         v8::WeakReferenceCallback weakReferenceCallback() { return m_weakReferenceCallback; }
+
+        virtual void reportMemoryUsage(MemoryInstrumentation*) = 0;
+
     private:
         v8::WeakReferenceCallback m_weakReferenceCallback;
     };
@@ -129,6 +134,11 @@ namespace WebCore {
             visitor->endMap();
         }
 
+        virtual void reportMemoryUsage(MemoryInstrumentation* instrumentation) OVERRIDE
+        {
+            instrumentation->reportHashMap(m_map, MemoryInstrumentation::Binding);
+        }
+
     protected:
         HashMap<KeyType*, ValueType*> m_map;
     };
index 99fe46a..b81f5be 100644 (file)
@@ -47,6 +47,7 @@ public:
         Other,
         DOM,
         CSS,
+        Binding,
         LastTypeEntry
     };
 
@@ -59,6 +60,7 @@ public:
             return;
         countObjectSize(objectType, sizeof(T));
     }
+    template <typename HashMapType> void reportHashMap(const HashMapType&, ObjectType);
 
 private:
     friend class MemoryObjectInfo;
@@ -139,6 +141,14 @@ void MemoryInstrumentation::reportInstrumentedObject(const T& object)
     object.reportMemoryUsage(&memoryObjectInfo);
 }
 
+
+template<typename HashMapType>
+void MemoryInstrumentation::reportHashMap(const HashMapType& hashMap, ObjectType objectType)
+{
+    size_t size = sizeof(HashMapType) + hashMap.capacity() * sizeof(typename HashMapType::ValueType);
+    countObjectSize(objectType, size);
+}
+
 } // namespace WebCore
 
 #endif // !defined(MemoryInstrumentation_h)
index 0e25d70..b5fd836 100644 (file)
@@ -90,6 +90,7 @@ static const char dom[] = "DOM";
 static const char domTreeOther[] = "DOMTreeOther";
 static const char domTreeDOM[] = "DOMTreeDOM";
 static const char domTreeCSS[] = "DOMTreeCSS";
+static const char domTreeBinding[] = "DOMTreeBinding";
 }
 
 namespace {
@@ -447,6 +448,7 @@ public:
         addMemoryBlockFor(domChildren.get(), m_totalSizes[Other], MemoryBlockName::domTreeOther);
         addMemoryBlockFor(domChildren.get(), m_totalSizes[DOM], MemoryBlockName::domTreeDOM);
         addMemoryBlockFor(domChildren.get(), m_totalSizes[CSS], MemoryBlockName::domTreeCSS);
+        addMemoryBlockFor(domChildren.get(), m_totalSizes[Binding], MemoryBlockName::domTreeBinding);
 
         RefPtr<InspectorMemoryBlock> dom = InspectorMemoryBlock::create().setName(MemoryBlockName::dom);
         dom->setSize(totalSize);
@@ -492,6 +494,11 @@ public:
         m_domMemoryUsage.reportInstrumentedPointer(node);
     }
 
+    void visitBindings()
+    {
+        ScriptProfiler::collectBindingMemoryInfo(&m_domMemoryUsage);
+    }
+
     PassRefPtr<InspectorMemoryBlock> dumpStatistics() { return m_domMemoryUsage.dumpStatistics(); }
 
 private:
@@ -512,6 +519,8 @@ static PassRefPtr<InspectorMemoryBlock> domTreeInfo(Page* page, VisitedObjects&
             domTreesIterator.visitNode(doc);
     }
 
+    domTreesIterator.visitBindings();
+
     return domTreesIterator.dumpStatistics();
 }