Web Inspector: provide memory instrumentation for HashMap
authoryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Oct 2012 14:46:25 +0000 (14:46 +0000)
committeryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Oct 2012 14:46:25 +0000 (14:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=98005

Reviewed by Pavel Feldman.

Source/WebCore:

Updated all call sites of MemoryInstrumentation::addHashMap to use generic
method of reporting memory footprint instead.

* bindings/v8/ScopedDOMDataStore.cpp:
* bindings/v8/V8Binding.cpp:
(WebCore::StringCache::reportMemoryUsage):
* bindings/v8/V8DOMMap.h:
* bindings/v8/V8PerIsolateData.cpp:
(WebCore::V8PerIsolateData::reportMemoryUsage):
* css/CSSImageGeneratorValue.cpp:
(WebCore::CSSImageGeneratorValue::reportBaseClassMemoryUsage):
* css/PropertySetCSSStyleDeclaration.cpp:
(WebCore::PropertySetCSSStyleDeclaration::reportMemoryUsage):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::collectMatchingRulesForList):
* css/StyleSheetContents.cpp:
(WebCore::StyleSheetContents::reportMemoryUsage):
* dom/Document.cpp:
(WebCore::Document::reportMemoryUsage):
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::reportMemoryUsage):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::reportMemoryUsage):
* loader/cache/MemoryCache.cpp:
(WebCore::MemoryCache::reportMemoryUsage):
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::reportMemoryUsage):
* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::reportMemoryUsage):
* rendering/style/StyleRareNonInheritedData.cpp:

Source/WebKit/chromium:

Added unit tests for HashMap memory instrumentation.

* tests/MemoryInstrumentationTest.cpp:
(WTF):

Source/WTF:

Extracted HashMap memory instrumentation into its own file. The map's content
elements will be automatically traversed if their types are supported
by the memory instrumentation. No need to call special method for hash map
fields any more.

* GNUmakefile.list.am:
* WTF.gypi:
* WTF.pro:
* WTF.vcproj/WTF.vcproj:
* wtf/MemoryInstrumentation.h:
(MemoryInstrumentation):
(WTF):
* wtf/MemoryInstrumentationHashMap.h: Added.
(WTF):
(WTF::SequenceMemoryInstrumentationTraits::reportMemoryUsage):
(WTF::reportMemoryUsage):

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

26 files changed:
Source/WTF/ChangeLog
Source/WTF/GNUmakefile.list.am
Source/WTF/WTF.gypi
Source/WTF/WTF.pro
Source/WTF/WTF.vcproj/WTF.vcproj
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/MemoryInstrumentation.h
Source/WTF/wtf/MemoryInstrumentationHashMap.h [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/v8/ScopedDOMDataStore.cpp
Source/WebCore/bindings/v8/V8Binding.cpp
Source/WebCore/bindings/v8/V8DOMMap.h
Source/WebCore/bindings/v8/V8PerIsolateData.cpp
Source/WebCore/css/CSSImageGeneratorValue.cpp
Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleSheetContents.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/cache/CachedResourceLoader.cpp
Source/WebCore/loader/cache/MemoryCache.cpp
Source/WebCore/platform/network/ResourceRequestBase.cpp
Source/WebCore/platform/network/ResourceResponseBase.cpp
Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp

index 6fb5803..ce47ee6 100644 (file)
@@ -1,3 +1,27 @@
+2012-10-01  Yury Semikhatsky  <yurys@chromium.org>
+
+        Web Inspector: provide memory instrumentation for HashMap
+        https://bugs.webkit.org/show_bug.cgi?id=98005
+
+        Reviewed by Pavel Feldman.
+
+        Extracted HashMap memory instrumentation into its own file. The map's content
+        elements will be automatically traversed if their types are supported
+        by the memory instrumentation. No need to call special method for hash map
+        fields any more.
+
+        * GNUmakefile.list.am:
+        * WTF.gypi:
+        * WTF.pro:
+        * WTF.vcproj/WTF.vcproj:
+        * wtf/MemoryInstrumentation.h:
+        (MemoryInstrumentation):
+        (WTF):
+        * wtf/MemoryInstrumentationHashMap.h: Added.
+        (WTF):
+        (WTF::SequenceMemoryInstrumentationTraits::reportMemoryUsage):
+        (WTF::reportMemoryUsage):
+
 2012-10-01  Alberto Garcia  <agarcia@igalia.com>
 
         Check that __cplusplus is defined before comparing its value
index cf7606b..bd6e01f 100644 (file)
@@ -81,6 +81,7 @@ wtf_sources += \
     Source/WTF/wtf/MediaTime.cpp \
     Source/WTF/wtf/MemoryInstrumentation.h \
     Source/WTF/wtf/MemoryInstrumentationArrayBufferView.h \
+    Source/WTF/wtf/MemoryInstrumentationHashMap.h \
     Source/WTF/wtf/MemoryInstrumentationHashSet.h \
     Source/WTF/wtf/MemoryInstrumentationVector.h \
     Source/WTF/wtf/MessageQueue.h \
index deac571..1f97fe0 100644 (file)
@@ -51,6 +51,7 @@
             'wtf/MathExtras.h',
             'wtf/MemoryInstrumentation.h',
             'wtf/MemoryInstrumentationArrayBufferView.h',
+            'wtf/MemoryInstrumentationHashMap.h',
             'wtf/MemoryInstrumentationHashSet.h',
             'wtf/MemoryInstrumentationVector.h',
             'wtf/MessageQueue.h',
index 7a10bef..7f2cc60 100644 (file)
@@ -88,6 +88,7 @@ HEADERS += \
     MediaTime.h \
     MemoryInstrumentation.h \
     MemoryInstrumentationArrayBufferView.h \
+    MemoryInstrumentationHashMap.h \
     MemoryInstrumentationHashSet.h \
     MemoryInstrumentationVector.h \
     MessageQueue.h \
index b92e778..2bda687 100644 (file)
                        >
                </File>
                <File
+                       RelativePath="..\wtf\MemoryInstrumentationHashMap.h"
+                       >
+               </File>
+               <File
                        RelativePath="..\wtf\MemoryInstrumentationHashSet.h"
                        >
                </File>
index 973b1c8..e7e4903 100644 (file)
                A8A4748C151A8264004123FF /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4748B151A8264004123FF /* config.h */; };
                CD5497AC15857D0300B5BC30 /* MediaTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5497AA15857D0300B5BC30 /* MediaTime.cpp */; };
                CD5497AD15857D0300B5BC30 /* MediaTime.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5497AB15857D0300B5BC30 /* MediaTime.h */; };
+               F3525E461619A4EE00278BC1 /* MemoryInstrumentationHashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = F3525E451619A4EE00278BC1 /* MemoryInstrumentationHashMap.h */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
                A8A4748B151A8264004123FF /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
                CD5497AA15857D0300B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = "<group>"; };
                CD5497AB15857D0300B5BC30 /* MediaTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaTime.h; sourceTree = "<group>"; };
+               F3525E451619A4EE00278BC1 /* MemoryInstrumentationHashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryInstrumentationHashMap.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                CD5497AB15857D0300B5BC30 /* MediaTime.h */,
                                4F1D115315FF11BE0026E908 /* MemoryInstrumentation.h */,
                                4FD8554616133E0E00C5B704 /* MemoryInstrumentationArrayBufferView.h */,
+                               F3525E451619A4EE00278BC1 /* MemoryInstrumentationHashMap.h */,
                                4F1B2DB5160B44AA00586559 /* MemoryInstrumentationHashSet.h */,
                                4FCB7109160A1A07008425EC /* MemoryInstrumentationVector.h */,
                                A8A472CC151A825B004123FF /* MessageQueue.h */,
                                4FCB710A160A1A07008425EC /* MemoryInstrumentationVector.h in Headers */,
                                4F1B2DB6160B44AA00586559 /* MemoryInstrumentationHashSet.h in Headers */,
                                4FD8554716133E0E00C5B704 /* MemoryInstrumentationArrayBufferView.h in Headers */,
+                               F3525E461619A4EE00278BC1 /* MemoryInstrumentationHashMap.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 69b0225..b1496c8 100644 (file)
@@ -156,10 +156,8 @@ private:
     };
 
     template<typename T> void addObject(const T& t, MemoryObjectType ownerObjectType) { OwningTraits<T>::addObject(this, t, ownerObjectType); }
-    template<typename HashMapType> void addHashMap(const HashMapType&, MemoryObjectType, bool contentOnly = false);
+    template<typename HashCountedSetType> void addHashCountedSet(const HashCountedSetType&, MemoryObjectType, bool contentOnly = false);
     template<typename CollectionType> void addInstrumentedCollection(const CollectionType&, MemoryObjectType, bool contentOnly = false);
-    template<typename MapType> void addInstrumentedMapEntries(const MapType&, MemoryObjectType);
-    template<typename MapType> void addInstrumentedMapValues(const MapType&, MemoryObjectType);
     template<typename ListHashSetType> void addListHashSet(const ListHashSetType&, MemoryObjectType, bool contentOnly = false);
     void addRawBuffer(const void* const& buffer, MemoryObjectType ownerObjectType, size_t size)
     {
@@ -214,10 +212,7 @@ public:
     void addCollectionElements(const char*, const char*) { }
     void addCollectionElements(const int*, const int*) { }
 
-    template<typename HashMapType> void addHashMap(const HashMapType& map) { m_memoryInstrumentation->addHashMap(map, m_objectType, true); }
-    template<typename HashSetType> void addHashCountedSet(const HashSetType& set) { m_memoryInstrumentation->addHashMap(set, m_objectType, true); }
-    template<typename MapType> void addInstrumentedMapEntries(const MapType& map) { m_memoryInstrumentation->addInstrumentedMapEntries(map, m_objectType); }
-    template<typename MapType> void addInstrumentedMapValues(const MapType& map) { m_memoryInstrumentation->addInstrumentedMapValues(map, m_objectType); }
+    template<typename HashSetType> void addHashCountedSet(const HashSetType& set) { m_memoryInstrumentation->addHashCountedSet(set, m_objectType, true); }
     template<typename ListHashSetType> void addListHashSet(const ListHashSetType& set) { m_memoryInstrumentation->addListHashSet(set, m_objectType, true); }
     void addRawBuffer(const void* const& buffer, size_t size) { m_memoryInstrumentation->addRawBuffer(buffer, m_objectType, size); }
     void addPrivateBuffer(size_t size) { m_memoryInstrumentation->countObjectSize(m_objectType, size); }
@@ -270,12 +265,12 @@ void MemoryInstrumentation::addObjectImpl(const RefPtr<T>* const& object, Memory
     addObjectImpl(object->get(), ownerObjectType, byPointer);
 }
 
-template<typename HashMapType>
-void MemoryInstrumentation::addHashMap(const HashMapType& hashMap, MemoryObjectType ownerObjectType, bool contentOnly)
+template<typename HashCountedSetType>
+void MemoryInstrumentation::addHashCountedSet(const HashCountedSetType& hashCountedSet, MemoryObjectType ownerObjectType, bool contentOnly)
 {
-    if (visited(&hashMap))
+    if (visited(&hashCountedSet))
         return;
-    countObjectSize(ownerObjectType, calculateContainerSize(hashMap, contentOnly));
+    countObjectSize(ownerObjectType, calculateContainerSize(hashCountedSet, contentOnly));
 }
 
 template<typename CollectionType>
@@ -289,24 +284,6 @@ void MemoryInstrumentation::addInstrumentedCollection(const CollectionType& coll
         addObject(*i, ownerObjectType);
 }
 
-template<typename MapType>
-void MemoryInstrumentation::addInstrumentedMapEntries(const MapType& map, MemoryObjectType ownerObjectType)
-{
-    typename MapType::const_iterator end = map.end();
-    for (typename MapType::const_iterator i = map.begin(); i != end; ++i) {
-        addObject(i->first, ownerObjectType);
-        addObject(i->second, ownerObjectType);
-    }
-}
-
-template<typename MapType>
-void MemoryInstrumentation::addInstrumentedMapValues(const MapType& map, MemoryObjectType ownerObjectType)
-{
-    typename MapType::const_iterator end = map.end();
-    for (typename MapType::const_iterator i = map.begin(); i != end; ++i)
-        addObject(i->second, ownerObjectType);
-}
-
 template<typename ListHashSetType>
 void MemoryInstrumentation::addListHashSet(const ListHashSetType& hashSet, MemoryObjectType ownerObjectType, bool contentOnly)
 {
@@ -334,6 +311,9 @@ void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentatio
 template<typename T, size_t inlineCapacity> class Vector;
 template<typename T, size_t inlineCapacity> void reportMemoryUsage(const Vector<T, inlineCapacity>* const&, MemoryObjectInfo*);
 
+template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> class HashMap;
+template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> void reportMemoryUsage(const HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>* const&, MemoryObjectInfo*);
+
 } // namespace WTF
 
 #endif // !defined(MemoryInstrumentation_h)
diff --git a/Source/WTF/wtf/MemoryInstrumentationHashMap.h b/Source/WTF/wtf/MemoryInstrumentationHashMap.h
new file mode 100644 (file)
index 0000000..5e401ee
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 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 MemoryInstrumentationHashMap_h
+#define MemoryInstrumentationHashMap_h
+
+#include <wtf/HashMap.h>
+#include <wtf/TypeTraits.h>
+
+namespace WTF {
+
+template<typename KeyType>
+struct SequenceMemoryInstrumentationTraits {
+    template <typename I> static void reportMemoryUsage(I iterator, I end, MemoryClassInfo& info)
+    {
+        info.addCollectionElements(iterator, end);
+    }
+};
+
+template<> struct SequenceMemoryInstrumentationTraits<int> {
+    template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
+};
+
+template<> struct SequenceMemoryInstrumentationTraits<void*> {
+    template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
+};
+
+template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
+void reportMemoryUsage(const HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>* const& hashMap, MemoryObjectInfo* memoryObjectInfo)
+{
+    MemoryClassInfo info(memoryObjectInfo, hashMap);
+    typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
+
+    typedef HashMapValueTraits<KeyArg, MappedArg> ValueTraits;
+    typedef HashTable<typename HashMapType::KeyType, typename HashMapType::ValueType, KeyValuePairKeyExtractor<typename HashMapType::ValueType>, HashArg, ValueTraits, KeyTraitsArg> HashTableType;
+
+    info.addPrivateBuffer(sizeof(typename HashTableType::ValueType) * hashMap->capacity());
+
+    // Check if type is convertible to integer to handle enum keys and values.
+    SequenceMemoryInstrumentationTraits<typename Conditional<IsConvertibleToInteger<KeyArg>::value, int, KeyArg>::Type>::reportMemoryUsage(hashMap->begin().keys(), hashMap->end().keys(), info);
+    SequenceMemoryInstrumentationTraits<typename Conditional<IsConvertibleToInteger<MappedArg>::value, int, MappedArg>::Type>::reportMemoryUsage(hashMap->begin().values(), hashMap->end().values(), info);
+}
+
+}
+
+#endif // !defined(MemoryInstrumentationHashMap_h)
index 4f9bc84..e155163 100644 (file)
@@ -1,5 +1,43 @@
 2012-10-01  Yury Semikhatsky  <yurys@chromium.org>
 
+        Web Inspector: provide memory instrumentation for HashMap
+        https://bugs.webkit.org/show_bug.cgi?id=98005
+
+        Reviewed by Pavel Feldman.
+
+        Updated all call sites of MemoryInstrumentation::addHashMap to use generic
+        method of reporting memory footprint instead. 
+
+        * bindings/v8/ScopedDOMDataStore.cpp:
+        * bindings/v8/V8Binding.cpp:
+        (WebCore::StringCache::reportMemoryUsage):
+        * bindings/v8/V8DOMMap.h:
+        * bindings/v8/V8PerIsolateData.cpp:
+        (WebCore::V8PerIsolateData::reportMemoryUsage):
+        * css/CSSImageGeneratorValue.cpp:
+        (WebCore::CSSImageGeneratorValue::reportBaseClassMemoryUsage):
+        * css/PropertySetCSSStyleDeclaration.cpp:
+        (WebCore::PropertySetCSSStyleDeclaration::reportMemoryUsage):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::collectMatchingRulesForList):
+        * css/StyleSheetContents.cpp:
+        (WebCore::StyleSheetContents::reportMemoryUsage):
+        * dom/Document.cpp:
+        (WebCore::Document::reportMemoryUsage):
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::reportMemoryUsage):
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::reportMemoryUsage):
+        * loader/cache/MemoryCache.cpp:
+        (WebCore::MemoryCache::reportMemoryUsage):
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::reportMemoryUsage):
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::reportMemoryUsage):
+        * rendering/style/StyleRareNonInheritedData.cpp:
+
+2012-10-01  Yury Semikhatsky  <yurys@chromium.org>
+
         Put implementation details of StyleBuilder.cpp into anonymous namespace
         https://bugs.webkit.org/show_bug.cgi?id=98028
 
index f951366..bbddc5c 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "ScopedDOMDataStore.h"
 
+#include "Node.h"
 #include "WebCoreMemoryInstrumentation.h"
 
 namespace WebCore {
index d22e775..a2d5df4 100644 (file)
@@ -52,6 +52,7 @@
 #include "XPathNSResolver.h"
 #include <wtf/MathExtras.h>
 #include <wtf/MainThread.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/Threading.h>
 #include <wtf/text/AtomicString.h>
@@ -221,7 +222,7 @@ v8::Persistent<v8::FunctionTemplate> createRawTemplate()
 void StringCache::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding);
-    info.addHashMap(m_stringCache);
+    info.addMember(m_stringCache);
 }
     
 PassRefPtr<DOMStringList> toDOMStringList(v8::Handle<v8::Value> value)
index a7598c6..b6ce39d 100644 (file)
@@ -34,6 +34,7 @@
 #include "WebCoreMemoryInstrumentation.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/OwnPtr.h>
 #include <v8.h>
 
@@ -137,7 +138,7 @@ namespace WebCore {
         virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const OVERRIDE
         {
             MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding);
-            info.addHashMap(m_map);
+            info.addMember(m_map);
         }
 
     protected:
index 4e1e0a1..f5cd38a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "ScriptGCEvent.h"
 #include "V8Binding.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationVector.h>
 
 namespace WebCore {
@@ -85,8 +86,8 @@ v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate()
 void V8PerIsolateData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding);
-    info.addHashMap(m_rawTemplates);
-    info.addHashMap(m_templates);
+    info.addMember(m_rawTemplates);
+    info.addMember(m_templates);
     info.addMember(m_stringCache);
     info.addMember(m_domDataList);
 
index 63cb422..90e1271 100644 (file)
@@ -32,6 +32,7 @@
 #include "Image.h"
 #include "RenderObject.h"
 #include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -113,8 +114,8 @@ void CSSImageGeneratorValue::reportBaseClassMemoryUsage(MemoryObjectInfo* memory
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
     info.addHashCountedSet(m_sizes);
-    info.addHashMap(m_clients);
-    info.addHashMap(m_images); // FIXME: instrument Image
+    info.addMember(m_clients);
+    info.addMember(m_images); // FIXME: instrument Image
 }
 
 PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size)
index f6e3db3..5fadf16 100644 (file)
@@ -32,6 +32,7 @@
 #include "StyledElement.h"
 #include "UndoManager.h"
 #include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 
 using namespace std;
 
@@ -173,8 +174,7 @@ void PropertySetCSSStyleDeclaration::reportMemoryUsage(MemoryObjectInfo* memoryO
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
     info.addMember(m_propertySet);
-    if (m_cssomCSSValueClones)
-        info.addInstrumentedMapEntries(*m_cssomCSSValueClones);
+    info.addMember(m_cssomCSSValueClones);
 }
 
 unsigned PropertySetCSSStyleDeclaration::length() const
index 0d5219b..54a53bd 100644 (file)
 #include "WebKitCSSTransformValue.h"
 #include "WebKitFontFamilyNames.h"
 #include "XMLNames.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationHashSet.h>
 #include <wtf/MemoryInstrumentationVector.h>
 #include <wtf/StdLibExtras.h>
@@ -2569,7 +2570,7 @@ RuleSet::RuleSet()
 
 static void reportAtomRuleMap(MemoryClassInfo* info, const RuleSet::AtomRuleMap& atomicRuleMap)
 {
-    info->addHashMap(atomicRuleMap);
+    info->addMember(atomicRuleMap);
     for (RuleSet::AtomRuleMap::const_iterator it = atomicRuleMap.begin(); it != atomicRuleMap.end(); ++it)
         info->addMember(*it->second);
 }
@@ -5781,25 +5782,21 @@ void StyleResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     info.addMember(m_userStyle);
     info.addMember(m_siblingRuleSet);
     info.addMember(m_uncommonAttributeRuleSet);
-    info.addHashMap(m_keyframesRuleMap);
-    info.addHashMap(m_matchedPropertiesCache);
-    info.addInstrumentedMapValues(m_matchedPropertiesCache);
+    info.addMember(m_keyframesRuleMap);
+    info.addMember(m_matchedPropertiesCache);
     info.addMember(m_matchedRules);
 
     info.addMember(m_ruleList);
-    info.addHashMap(m_pendingImageProperties);
-    info.addInstrumentedMapValues(m_pendingImageProperties);
+    info.addMember(m_pendingImageProperties);
     info.addMember(m_lineHeightValue);
     info.addMember(m_viewportDependentMediaQueryResults);
-    info.addHashMap(m_styleRuleToCSSOMWrapperMap);
-    info.addInstrumentedMapEntries(m_styleRuleToCSSOMWrapperMap);
+    info.addMember(m_styleRuleToCSSOMWrapperMap);
     info.addMember(m_styleSheetCSSOMWrapperSet);
 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
-    info.addHashMap(m_pendingSVGDocuments);
+    info.addMember(m_pendingSVGDocuments);
 #endif
 #if ENABLE(STYLE_SCOPED)
-    info.addHashMap(m_scopedAuthorStyles);
-    info.addInstrumentedMapEntries(m_scopedAuthorStyles);
+    info.addMember(m_scopedAuthorStyles);
     info.addMember(m_scopeStack);
 #endif
 
index 8c39fac..9b1f514 100644 (file)
@@ -33,6 +33,7 @@
 #include "StyleRuleImport.h"
 #include "WebCoreMemoryInstrumentation.h"
 #include <wtf/Deque.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationVector.h>
 
 namespace WebCore {
@@ -498,7 +499,7 @@ void StyleSheetContents::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) c
     info.addMember(m_encodingFromCharsetRule);
     info.addMember(m_importRules);
     info.addMember(m_childRules);
-    info.addHashMap(m_namespaces);
+    info.addMember(m_namespaces);
     info.addMember(m_clients);
 }
 
index c509465..d3bbd53 100644 (file)
 #include <wtf/CurrentTime.h>
 #include <wtf/HashFunctions.h>
 #include <wtf/MainThread.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationHashSet.h>
 #include <wtf/MemoryInstrumentationVector.h>
 #include <wtf/PassRefPtr.h>
@@ -5887,17 +5888,17 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     info.addMember(m_xmlEncoding);
     info.addMember(m_xmlVersion);
     info.addMember(m_contentLanguage);
-    info.addHashMap(m_documentNamedItemCollections);
-    info.addHashMap(m_windowNamedItemCollections);
+    info.addMember(m_documentNamedItemCollections);
+    info.addMember(m_windowNamedItemCollections);
 #if ENABLE(DASHBOARD_SUPPORT)
     info.addMember(m_dashboardRegions);
 #endif
-    info.addHashMap(m_cssCanvasElements);
+    info.addMember(m_cssCanvasElements);
     info.addMember(m_iconURLs);
     info.addMember(m_documentSuspensionCallbackElements);
     info.addMember(m_mediaVolumeCallbackElements);
     info.addMember(m_privateBrowsingStateChangedElements);
-    info.addHashMap(m_elementsByAccessKey);
+    info.addMember(m_elementsByAccessKey);
     info.addMember(m_eventQueue);
     info.addMember(m_mediaCanStartListeners);
     info.addMember(m_pendingTasks);
index 4cc8361..b5acf2b 100644 (file)
@@ -53,6 +53,7 @@
 #include "TextResourceDecoder.h"
 #include "WebCoreMemoryInstrumentation.h"
 #include <wtf/Assertions.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationHashSet.h>
 #include <wtf/MemoryInstrumentationVector.h>
 #include <wtf/text/CString.h>
@@ -377,7 +378,7 @@ void DocumentLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     info.addMember(m_response);
     info.addMember(m_lastCheckedRequest);
     info.addMember(m_responses);
-    info.addHashMap(m_pendingSubstituteResources);
+    info.addMember(m_pendingSubstituteResources);
     info.addMember(m_resourcesClientKnowsAbout);
     info.addMember(m_resourcesLoadedFromMemoryCacheForClientNotification);
     info.addMember(m_clientRedirectSourceForHistory);
index bb68740..be0d9d7 100644 (file)
@@ -48,6 +48,7 @@
 #include "ResourceLoadScheduler.h"
 #include "SecurityOrigin.h"
 #include "Settings.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationHashSet.h>
 #include <wtf/UnusedParam.h>
 #include <wtf/text/CString.h>
@@ -896,11 +897,7 @@ void CachedResourceLoader::printPreloadStats()
 void CachedResourceLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Loader);
-    info.addHashMap(m_documentResources);
-    for (DocumentResourceMap::const_iterator i = m_documentResources.begin(); i != m_documentResources.end(); ++i) {
-        info.addMember(i->first);
-        info.addMember(i->second);
-    }
+    info.addMember(m_documentResources);
     info.addMember(m_validatedURLs);
     if (m_preloads)
         info.addListHashSet(*m_preloads);
index c1af09d..10c9e6b 100644 (file)
@@ -45,6 +45,7 @@
 #include "WorkerThread.h"
 #include <stdio.h>
 #include <wtf/CurrentTime.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationVector.h>
 #include <wtf/TemporaryChange.h>
 #include <wtf/text/CString.h>
@@ -719,12 +720,7 @@ MemoryCache::Statistics MemoryCache::getStatistics()
 void MemoryCache::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::MemoryCacheStructures);
-    info.addHashMap(m_resources);
-    CachedResourceMap::const_iterator e = m_resources.end();
-    for (CachedResourceMap::const_iterator i = m_resources.begin(); i != e; ++i) {
-        info.addMember(i->first);
-        info.addMember(i->second);
-    }
+    info.addMember(m_resources);
     info.addMember(m_allResources);
     info.addMember(m_liveDecodedResources);
 }
index 303deaa..543647b 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "PlatformMemoryInstrumentation.h"
 #include "ResourceRequest.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationVector.h>
 
 using namespace std;
@@ -451,8 +452,7 @@ void ResourceRequestBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
     info.addMember(m_url);
     info.addMember(m_firstPartyForCookies);
     info.addMember(m_httpMethod);
-    info.addHashMap(m_httpHeaderFields);
-    info.addInstrumentedMapEntries(m_httpHeaderFields);
+    info.addMember(m_httpHeaderFields);
     info.addMember(m_responseContentDispositionEncodingFallbackArray);
     info.addMember(m_httpBody);
 }
index 2521fb1..48568ef 100644 (file)
@@ -32,6 +32,7 @@
 #include "ResourceResponse.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/MathExtras.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/StdLibExtras.h>
 
 using namespace std;
@@ -576,8 +577,7 @@ void ResourceResponseBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
     info.addMember(m_textEncodingName);
     info.addMember(m_suggestedFilename);
     info.addMember(m_httpStatusText);
-    info.addHashMap(m_httpHeaderFields);
-    info.addInstrumentedMapEntries(m_httpHeaderFields);
+    info.addMember(m_httpHeaderFields);
     info.addMember(m_resourceLoadTiming);
     info.addMember(m_resourceLoadInfo);
 }
index 22425f0..398ed0f 100644 (file)
@@ -31,6 +31,7 @@
 #include "StyleImage.h"
 #include "StyleResolver.h"
 #include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationVector.h>
 
 namespace WebCore {
index 654a1ea..df7a375 100644 (file)
@@ -1,3 +1,15 @@
+2012-10-01  Yury Semikhatsky  <yurys@chromium.org>
+
+        Web Inspector: provide memory instrumentation for HashMap
+        https://bugs.webkit.org/show_bug.cgi?id=98005
+
+        Reviewed by Pavel Feldman.
+
+        Added unit tests for HashMap memory instrumentation.
+
+        * tests/MemoryInstrumentationTest.cpp:
+        (WTF):
+
 2012-10-01  Alexander Pavlov  <apavlov@chromium.org>
 
         Web Inspector: [Device Metrics] Remove the gutter overlay moving its functionality into the InspectorOverlay
index bec1c00..d4b25a7 100644 (file)
 #include <gtest/gtest.h>
 
 #include <wtf/ArrayBuffer.h>
+#include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/MemoryInstrumentationArrayBufferView.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
 #include <wtf/MemoryInstrumentationHashSet.h>
 #include <wtf/MemoryInstrumentationVector.h>
 #include <wtf/RefCounted.h>
 using namespace WebCore;
 
 namespace {
+enum TestEnum { ONE = 1, TWO, THREE, MY_ENUM_MAX };
+}
+
+namespace WTF {
+
+template<> struct DefaultHash<TestEnum> {
+    typedef IntHash<unsigned> Hash;
+};
+
+template<> struct HashTraits<TestEnum> : GenericHashTraits<TestEnum> {
+    static const bool emptyValueIsZero = true;
+    static const bool needsDestruction = false;
+    static void constructDeletedValue(TestEnum& slot) { slot = static_cast<TestEnum>(MY_ENUM_MAX + 1); }
+    static bool isDeletedValue(TestEnum value) { return value == (MY_ENUM_MAX + 1); }
+};
+
+}
+
+namespace {
 
 class InstrumentationTestHelper {
 public:
@@ -450,6 +471,141 @@ TEST(MemoryInstrumentationTest, hashSetWithInstrumentedType)
     EXPECT_EQ(count + 1, (size_t)helper.visitedObjects());
 }
 
+TEST(MemoryInstrumentationTest, hashMapWithNotInstrumentedKeysAndValues)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<int, int> IntToIntMap;
+    OwnPtr<IntToIntMap> value = adoptPtr(new IntToIntMap());
+    size_t count = 10;
+    for (size_t i = 1; i <= count; ++i)
+        value->set(i, i);
+    InstrumentedOwner<IntToIntMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(IntToIntMap) + sizeof(IntToIntMap::ValueType) * value->capacity(), helper.reportedSizeForAllTypes());
+    EXPECT_EQ(1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedKeys)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<String, int> StringToIntMap;
+    OwnPtr<StringToIntMap> value = adoptPtr(new StringToIntMap());
+    int count = 10;
+    for (int i = 1; i <= count; ++i)
+        value->set(String::number(i), i);
+    InstrumentedOwner<StringToIntMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(StringToIntMap) + sizeof(StringToIntMap::ValueType) * value->capacity() + sizeof(StringImpl) * value->size(), helper.reportedSizeForAllTypes());
+    EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedValues)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<int, String> IntToStringMap;
+    OwnPtr<IntToStringMap> value = adoptPtr(new IntToStringMap());
+    int count = 10;
+    for (int i = 1; i <= count; ++i)
+        value->set(i, String::number(i));
+    InstrumentedOwner<IntToStringMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(IntToStringMap) + sizeof(IntToStringMap::ValueType) * value->capacity() + sizeof(StringImpl) * value->size(), helper.reportedSizeForAllTypes());
+    EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedKeysAndValues)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<String, String> StringToStringMap;
+    OwnPtr<StringToStringMap> value = adoptPtr(new StringToStringMap());
+    int count = 10;
+    for (int i = 1; i <= count; ++i)
+        value->set(String::number(count + i), String::number(i));
+    InstrumentedOwner<StringToStringMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(StringToStringMap) + sizeof(StringToStringMap::ValueType) * value->capacity() + 2 * sizeof(StringImpl) * value->size(), helper.reportedSizeForAllTypes());
+    EXPECT_EQ(2 * count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedPointerKeysAndPointerValues)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<Instrumented*, Instrumented*> InstrumentedToInstrumentedMap;
+    OwnPtr<InstrumentedToInstrumentedMap> value = adoptPtr(new InstrumentedToInstrumentedMap());
+    Vector<OwnPtr<Instrumented> > valuesVector;
+    int count = 10;
+    for (int i = 0; i < count; ++i) {
+        valuesVector.append(adoptPtr(new Instrumented()));
+        valuesVector.append(adoptPtr(new Instrumented()));
+        value->set(valuesVector[2 * i].get(), valuesVector[2 * i + 1].get());
+    }
+    InstrumentedOwner<InstrumentedToInstrumentedMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(InstrumentedToInstrumentedMap) + sizeof(InstrumentedToInstrumentedMap::ValueType) * value->capacity() + 2 * (sizeof(Instrumented) + sizeof(NotInstrumented)) * value->size(), helper.reportedSizeForAllTypes());
+    EXPECT_EQ(2 * 2 * count + 1, helper.visitedObjects());
+}
+
+class InstrumentedConvertibleToInt {
+public:
+    InstrumentedConvertibleToInt() : m_notInstrumented(0) { }
+    ~InstrumentedConvertibleToInt() { }
+
+    virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+    {
+        MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
+        info.addMember(m_notInstrumented);
+    }
+
+    operator int() const { return 2012; }
+
+    NotInstrumented* m_notInstrumented;
+};
+
+// This test checks if reportMemoryUsage method will be called on a class
+// that can be implicitly cast to int. Currently objects of such classes are
+// treated as integers when they are stored in a HashMap by value and
+// reportMemoryUsage will not be called on them. We may fix that later.
+TEST(MemoryInstrumentationTest, hashMapWithValuesConvertibleToInt)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<InstrumentedConvertibleToInt*, InstrumentedConvertibleToInt> TestMap;
+    OwnPtr<TestMap> value = adoptPtr(new TestMap());
+    Vector<OwnPtr<InstrumentedConvertibleToInt> > keysVector;
+    Vector<OwnPtr<NotInstrumented> > valuesVector;
+    int count = 10;
+    for (int i = 0; i < count; ++i) {
+        keysVector.append(adoptPtr(new InstrumentedConvertibleToInt()));
+        valuesVector.append(adoptPtr(new NotInstrumented()));
+        value->set(keysVector[i].get(), InstrumentedConvertibleToInt()).iterator->second.m_notInstrumented = valuesVector[i].get();
+    }
+    InstrumentedOwner<TestMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(TestMap) + sizeof(TestMap::ValueType) * value->capacity() +
+        sizeof(InstrumentedConvertibleToInt) * count /* + sizeof(NotInstrumented) * count */, helper.reportedSizeForAllTypes());
+    EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithEnumKeysAndInstrumentedValues)
+{
+    InstrumentationTestHelper helper;
+
+    typedef HashMap<TestEnum, String> EnumToStringMap;
+    OwnPtr<EnumToStringMap> value = adoptPtr(new EnumToStringMap());
+    int count = MY_ENUM_MAX;
+    for (int i = ONE; i <= count; ++i)
+        value->set(static_cast<TestEnum>(i), String::number(i));
+    InstrumentedOwner<EnumToStringMap* > root(value.get());
+    helper.addRootObject(root);
+    EXPECT_EQ(sizeof(EnumToStringMap) + sizeof(EnumToStringMap::ValueType) * value->capacity() + sizeof(StringImpl) * value->size(), helper.reportedSizeForAllTypes());
+    EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
 TEST(MemoryInstrumentationTest, arrayBuffer)
 {
     InstrumentationTestHelper helper;