Modified: trunk/Source/WTF/wtf/MemoryInstrumentation.h (128731 => 128732)
--- trunk/Source/WTF/wtf/MemoryInstrumentation.h 2012-09-17 09:37:51 UTC (rev 128731)
+++ trunk/Source/WTF/wtf/MemoryInstrumentation.h 2012-09-17 09:44:22 UTC (rev 128732)
@@ -48,6 +48,39 @@
byReference
};
+class MemoryObjectInfo {
+public:
+ MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation, MemoryObjectType ownerObjectType)
+ : m_memoryInstrumentation(memoryInstrumentation)
+ , m_objectType(ownerObjectType)
+ , m_objectSize(0)
+ { }
+
+ typedef MemoryClassInfo ClassInfo;
+
+ MemoryObjectType objectType() const { return m_objectType; }
+ size_t objectSize() const { return m_objectSize; }
+
+ MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; }
+
+private:
+ friend class MemoryClassInfo;
+ friend class MemoryInstrumentation;
+
+ template<typename T> void reportObjectInfo(MemoryObjectType objectType, size_t actualSize)
+ {
+ if (!m_objectSize) {
+ m_objectSize = actualSize ? actualSize : sizeof(T);
+ if (objectType)
+ m_objectType = objectType;
+ }
+ }
+
+ MemoryInstrumentation* m_memoryInstrumentation;
+ MemoryObjectType m_objectType;
+ size_t m_objectSize;
+};
+
class MemoryInstrumentation {
public:
virtual ~MemoryInstrumentation() { }
@@ -75,6 +108,29 @@
friend class MemoryClassInfo;
+ template<typename T> static void selectInstrumentationMethod(const T* const& object, MemoryObjectInfo* memoryObjectInfo)
+ {
+ // If there is reportMemoryUsage method on the object, call it.
+ // Otherwise count only object's self size.
+ reportObjectMemoryUsage<T, void (T::*)(MemoryObjectInfo*) const>(object, memoryObjectInfo, 0);
+ }
+
+ template<typename Type, Type Ptr> struct MemberHelperStruct;
+ template<typename T, typename Type>
+ static void reportObjectMemoryUsage(const T* const& object, MemoryObjectInfo* memoryObjectInfo, MemberHelperStruct<Type, &T::reportMemoryUsage>*)
+ {
+ object->reportMemoryUsage(memoryObjectInfo);
+ }
+
+ template<typename T, typename Type>
+ static void reportObjectMemoryUsage(const T* const& object, MemoryObjectInfo* memoryObjectInfo, ...)
+ {
+ memoryObjectInfo->reportObjectInfo<T>(0, sizeof(T));
+ }
+
+ template<typename T>
+ static void countNotInstrumentedObject(const T* const&, MemoryObjectInfo*);
+
template<typename T> class InstrumentedPointer : public InstrumentedPointerBase {
public:
explicit InstrumentedPointer(const T* pointer, MemoryObjectType ownerObjectType) : m_pointer(pointer), m_ownerObjectType(ownerObjectType) { }
@@ -138,38 +194,6 @@
template<typename T> void addObjectImpl(const RefPtr<T>* const&, MemoryObjectType, MemoryOwningType);
};
-class MemoryObjectInfo {
-public:
- MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation, MemoryObjectType ownerObjectType)
- : m_memoryInstrumentation(memoryInstrumentation)
- , m_objectType(ownerObjectType)
- , m_objectSize(0)
- { }
-
- typedef MemoryClassInfo ClassInfo;
-
- MemoryObjectType objectType() const { return m_objectType; }
- size_t objectSize() const { return m_objectSize; }
-
- MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; }
-
-private:
- friend class MemoryClassInfo;
-
- template<typename T> void reportObjectInfo(MemoryObjectType objectType, size_t actualSize)
- {
- if (!m_objectSize) {
- m_objectSize = actualSize ? actualSize : sizeof(T);
- if (objectType)
- m_objectType = objectType;
- }
- }
-
- MemoryInstrumentation* m_memoryInstrumentation;
- MemoryObjectType m_objectType;
- size_t m_objectSize;
-};
-
class MemoryClassInfo {
public:
template<typename T>
@@ -211,7 +235,7 @@
{
if (owningType == byReference) {
MemoryObjectInfo memoryObjectInfo(this, ownerObjectType);
- object->reportMemoryUsage(&memoryObjectInfo);
+ selectInstrumentationMethod<T>(object, &memoryObjectInfo);
} else {
if (!object || visited(object))
return;
@@ -254,11 +278,7 @@
template<typename T>
void MemoryInstrumentation::addObjectImpl(const T* const& object, MemoryObjectType ownerObjectType, MemoryOwningType owningType)
{
- if (owningType == byReference)
- return;
- if (!object || visited(object))
- return;
- countObjectSize(ownerObjectType, sizeof(T));
+ addInstrumentedObjectImpl(object, ownerObjectType, owningType);
}
template<typename HashMapType>
@@ -333,7 +353,7 @@
void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentation* memoryInstrumentation)
{
MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType);
- m_pointer->reportMemoryUsage(&memoryObjectInfo);
+ selectInstrumentationMethod<T>(m_pointer, &memoryObjectInfo);
memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
}
Modified: trunk/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp (128731 => 128732)
--- trunk/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp 2012-09-17 09:37:51 UTC (rev 128731)
+++ trunk/Source/WebKit/chromium/tests/MemoryInstrumentationTest.cpp 2012-09-17 09:44:22 UTC (rev 128732)
@@ -50,6 +50,7 @@
class NotInstrumented {
public:
+ NotInstrumented(const char* = 0) { }
char m_data[42];
};
@@ -275,7 +276,6 @@
}
}
-
class TwoPointersToRefPtr {
public:
TwoPointersToRefPtr(const RefPtr<StringImpl>& value) : m_ptr1(&value), m_ptr2(&value) { }
@@ -326,5 +326,45 @@
EXPECT_EQ(1, visitedObjects.size());
}
+template<typename T>
+class InstrumentedTemplate {
+public:
+ template<typename V>
+ InstrumentedTemplate(const V& value) : m_value(value) { }
+
+ template<typename MemoryObjectInfo>
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ typename MemoryObjectInfo::ClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
+ info.addMember(m_value);
+ }
+
+ T m_value;
+};
+
+TEST(MemoryInstrumentationTest, detectReportMemoryUsageMethod)
+{
+ {
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+
+ OwnPtr<InstrumentedTemplate<String> > value = adoptPtr(new InstrumentedTemplate<String>(""));
+ InstrumentedOwner<InstrumentedTemplate<String>* > root(value.get());
+ impl.addRootObject(root);
+ EXPECT_EQ(sizeof(InstrumentedTemplate<String>) + sizeof(StringImpl), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(2, visitedObjects.size());
+ }
+ {
+ VisitedObjects visitedObjects;
+ MemoryInstrumentationImpl impl(visitedObjects);
+
+ OwnPtr<InstrumentedTemplate<NotInstrumented> > value = adoptPtr(new InstrumentedTemplate<NotInstrumented>(""));
+ InstrumentedOwner<InstrumentedTemplate<NotInstrumented>* > root(value.get());
+ impl.addRootObject(root);
+ EXPECT_EQ(sizeof(InstrumentedTemplate<NotInstrumented>), impl.reportedSizeForAllTypes());
+ EXPECT_EQ(1, visitedObjects.size());
+ }
+}
+
} // namespace