Log Message
Web Inspector: NMI introduce heap graph recording API https://bugs.webkit.org/show_bug.cgi?id=103232
Reviewed by Vsevolod Vlasov. MemoryInstrumentationClient is extended with several methods for reporting heap graph vertices and edges. Edge source is always idenfied by heap object address. Target node might be either a destination object address(either real or adjusted if the edge was retrieved from a pointer to a base class) or a MemoryObjectInfo in case of internal buffers. * wtf/MemoryInstrumentation.cpp: (WTF::MemoryInstrumentation::reportEdge): (WTF): (WTF::MemoryInstrumentation::reportLinkToBuffer): report edge between the object and a buffer which it owns. (WTF::MemoryInstrumentation::InstrumentedPointerBase::process): (WTF::MemoryClassInfo::addRawBuffer): (WTF::MemoryClassInfo::addPrivateBuffer): * wtf/MemoryInstrumentation.h: (MemoryInstrumentationClient): (WTF::MemoryInstrumentationClient::reportNode): (WTF::MemoryInstrumentationClient::reportEdge): (WTF::MemoryInstrumentationClient::reportLeaf): (WTF::MemoryInstrumentationClient::reportBaseAddress): if we found an object by a pointer to base class it may have different value than real object address. Report both real and adjusted addresses so that they both can be used for identifying corresponding heap graph node. (WTF::MemoryInstrumentation::addRootObject): (MemoryInstrumentation): (WTF::MemoryInstrumentation::addObject): (WTF::MemoryInstrumentation::addRawBuffer): (WTF::MemoryInstrumentation::OwningTraits::addObject): (WTF::MemoryClassInfo::addMember): (MemoryClassInfo): (WTF::MemoryInstrumentation::addObjectImpl): * wtf/MemoryObjectInfo.h: added methods for repoting class name and some name string. (WTF::MemoryObjectInfo::setClassName): (WTF::MemoryObjectInfo::setName): (MemoryObjectInfo):
Modified Paths
- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def
- trunk/Source/WTF/ChangeLog
- trunk/Source/WTF/wtf/MemoryInstrumentation.cpp
- trunk/Source/WTF/wtf/MemoryInstrumentation.h
- trunk/Source/WTF/wtf/MemoryObjectInfo.h
- trunk/Source/WebCore/inspector/MemoryInstrumentationImpl.h
- trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp
Diff
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (136562 => 136563)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-12-04 22:02:12 UTC (rev 136563)
@@ -70,8 +70,8 @@
?addPropertyTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VPropertyName@2@IPAVJSCell@2@AAH@Z
?addPropertyTransitionToExistingStructure@Structure@JSC@@SAPAV12@PAV12@VPropertyName@2@IPAVJSCell@2@AAH@Z
?addPropertyWithoutTransition@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@IPAVJSCell@2@@Z
- ?addPrivateBuffer@MemoryClassInfo@WTF@@QAEXIPBD@Z
- ?addRawBuffer@MemoryClassInfo@WTF@@QAEXABQBXI@Z
+ ?addPrivateBuffer@MemoryClassInfo@WTF@@QAEXIPBD00@Z
+ ?addRawBuffer@MemoryClassInfo@WTF@@QAEXABQBXIPBD1@Z
?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
@@ -327,6 +327,7 @@
?removeBlock@MarkedAllocator@JSC@@QAEXPAVMarkedBlock@2@@Z
?removeDirect@JSObject@JSC@@QAE_NAAVJSGlobalData@2@VPropertyName@2@@Z
?reportAbandonedObjectGraph@Heap@JSC@@QAEXXZ
+ ?reportEdge@MemoryInstrumentation@WTF@@AAEXPAVMemoryObjectInfo@2@PBXPBD@Z
?reportExtraMemoryCostSlowCase@Heap@JSC@@AAEXI@Z
?reportSuccess@HeapStatistics@JSC@@SAXXZ
?reserveAndCommit@OSAllocator@WTF@@SAPAXIW4Usage@12@_N11@Z
Modified: trunk/Source/WTF/ChangeLog (136562 => 136563)
--- trunk/Source/WTF/ChangeLog 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Source/WTF/ChangeLog 2012-12-04 22:02:12 UTC (rev 136563)
@@ -1,3 +1,46 @@
+2012-12-03 Yury Semikhatsky <[email protected]>
+
+ Web Inspector: NMI introduce heap graph recording API
+ https://bugs.webkit.org/show_bug.cgi?id=103232
+
+ Reviewed by Vsevolod Vlasov.
+
+ MemoryInstrumentationClient is extended with several methods for reporting
+ heap graph vertices and edges. Edge source is always idenfied by heap object
+ address. Target node might be either a destination object address(either real
+ or adjusted if the edge was retrieved from a pointer to a base class) or a
+ MemoryObjectInfo in case of internal buffers.
+
+ * wtf/MemoryInstrumentation.cpp:
+ (WTF::MemoryInstrumentation::reportEdge):
+ (WTF):
+ (WTF::MemoryInstrumentation::reportLinkToBuffer): report edge between the object
+ and a buffer which it owns.
+ (WTF::MemoryInstrumentation::InstrumentedPointerBase::process):
+ (WTF::MemoryClassInfo::addRawBuffer):
+ (WTF::MemoryClassInfo::addPrivateBuffer):
+ * wtf/MemoryInstrumentation.h:
+ (MemoryInstrumentationClient):
+ (WTF::MemoryInstrumentationClient::reportNode):
+ (WTF::MemoryInstrumentationClient::reportEdge):
+ (WTF::MemoryInstrumentationClient::reportLeaf):
+ (WTF::MemoryInstrumentationClient::reportBaseAddress): if we found an object by a pointer
+ to base class it may have different value than real object address. Report both real and
+ adjusted addresses so that they both can be used for identifying corresponding heap graph
+ node.
+ (WTF::MemoryInstrumentation::addRootObject):
+ (MemoryInstrumentation):
+ (WTF::MemoryInstrumentation::addObject):
+ (WTF::MemoryInstrumentation::addRawBuffer):
+ (WTF::MemoryInstrumentation::OwningTraits::addObject):
+ (WTF::MemoryClassInfo::addMember):
+ (MemoryClassInfo):
+ (WTF::MemoryInstrumentation::addObjectImpl):
+ * wtf/MemoryObjectInfo.h: added methods for repoting class name and some name string.
+ (WTF::MemoryObjectInfo::setClassName):
+ (WTF::MemoryObjectInfo::setName):
+ (MemoryObjectInfo):
+
2012-12-03 Filip Pizlo <[email protected]>
Replace JSValue::description() with JSValue::dump(PrintStream&)
Modified: trunk/Source/WTF/wtf/MemoryInstrumentation.cpp (136562 => 136563)
--- trunk/Source/WTF/wtf/MemoryInstrumentation.cpp 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Source/WTF/wtf/MemoryInstrumentation.cpp 2012-12-04 22:02:12 UTC (rev 136563)
@@ -50,6 +50,11 @@
{
}
+void MemoryInstrumentation::reportEdge(MemoryObjectInfo* ownerObjectInfo, const void* target, const char* name)
+{
+ m_client->reportEdge(ownerObjectInfo->reportedPointer(), target, name);
+}
+
MemoryObjectType MemoryInstrumentation::getObjectType(MemoryObjectInfo* objectInfo)
{
return objectInfo->objectType();
@@ -60,6 +65,14 @@
memoryObjectInfo->reportObjectInfo(pointer, objectType, objectSize);
}
+void MemoryInstrumentation::reportLinkToBuffer(const void* owner, const void* buffer, MemoryObjectType ownerObjectType, size_t size, const char* nodeName, const char* edgeName)
+{
+ MemoryObjectInfo memoryObjectInfo(this, ownerObjectType);
+ memoryObjectInfo.reportObjectInfo(buffer, ownerObjectType, size);
+ memoryObjectInfo.setName(nodeName);
+ m_client->reportLeaf(owner, memoryObjectInfo, edgeName);
+}
+
MemoryInstrumentation::InstrumentedPointerBase::InstrumentedPointerBase(MemoryObjectInfo* memoryObjectInfo)
: m_ownerObjectType(memoryObjectInfo->objectType())
{
@@ -76,9 +89,13 @@
const void* pointer = memoryObjectInfo.reportedPointer();
ASSERT(pointer);
- if (pointer != originalPointer && memoryInstrumentation->visited(pointer))
- return;
+ if (pointer != originalPointer) {
+ memoryInstrumentation->m_client->reportBaseAddress(originalPointer, pointer);
+ if (memoryInstrumentation->visited(pointer))
+ return;
+ }
memoryInstrumentation->countObjectSize(pointer, memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
+ memoryInstrumentation->m_client->reportNode(memoryObjectInfo);
if (!memoryInstrumentation->checkCountedObject(pointer)) {
#if DEBUG_POINTER_INSTRUMENTATION
fputs("Unknown object counted:\n", stderr);
@@ -94,18 +111,19 @@
m_objectType = m_memoryObjectInfo->objectType();
}
-void MemoryClassInfo::addRawBuffer(const void* const& buffer, size_t size)
+void MemoryClassInfo::addRawBuffer(const void* const& buffer, size_t size, const char* nodeName, const char* edgeName)
{
- m_memoryInstrumentation->addRawBuffer(buffer, m_objectType, size);
+ m_memoryInstrumentation->addRawBuffer(m_memoryObjectInfo->reportedPointer(), buffer, m_objectType, size, nodeName, edgeName);
}
-void MemoryClassInfo::addPrivateBuffer(size_t size, MemoryObjectType ownerObjectType)
+void MemoryClassInfo::addPrivateBuffer(size_t size, MemoryObjectType ownerObjectType, const char* nodeName, const char* edgeName)
{
if (!size)
return;
if (!ownerObjectType)
ownerObjectType = m_objectType;
m_memoryInstrumentation->countObjectSize(0, ownerObjectType, size);
+ m_memoryInstrumentation->reportLinkToBuffer(m_memoryObjectInfo->reportedPointer(), 0, ownerObjectType, size, nodeName, edgeName);
}
} // namespace WTF
Modified: trunk/Source/WTF/wtf/MemoryInstrumentation.h (136562 => 136563)
--- trunk/Source/WTF/wtf/MemoryInstrumentation.h 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Source/WTF/wtf/MemoryInstrumentation.h 2012-12-04 22:02:12 UTC (rev 136563)
@@ -58,6 +58,11 @@
virtual void countObjectSize(const void*, MemoryObjectType, size_t) = 0;
virtual bool visited(const void*) = 0;
virtual bool checkCountedObject(const void*) = 0;
+
+ virtual void reportNode(const MemoryObjectInfo&) = 0;
+ virtual void reportEdge(const void* source, const void* target, const char* edgeName) = 0;
+ virtual void reportLeaf(const void* source, const MemoryObjectInfo&, const char* edgeName) = 0;
+ virtual void reportBaseAddress(const void* base, const void* real) = 0;
};
class MemoryInstrumentation {
@@ -67,7 +72,7 @@
template <typename T> void addRootObject(const T& t)
{
- addObject(t, m_rootObjectInfo.get());
+ addObject(t, m_rootObjectInfo.get(), 0);
processDeferredInstrumentedPointers();
}
@@ -95,6 +100,8 @@
bool visited(const void* pointer) { return m_client->visited(pointer); }
bool checkCountedObject(const void* pointer) { return m_client->checkCountedObject(pointer); }
+ WTF_EXPORT_PRIVATE void reportEdge(MemoryObjectInfo* ownerObjectInfo, const void* target, const char* edgeName);
+
virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>) = 0;
virtual void processDeferredInstrumentedPointers() = 0;
@@ -135,33 +142,35 @@
const T* m_pointer;
};
- template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjectInfo) { OwningTraits<T>::addObject(this, t, ownerObjectInfo); }
- void addRawBuffer(const void* const& buffer, MemoryObjectType ownerObjectType, size_t size)
+ template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName) { OwningTraits<T>::addObject(this, t, ownerObjectInfo, edgeName); }
+ void addRawBuffer(const void* owner, const void* buffer, MemoryObjectType ownerObjectType, size_t size, const char* nodeName = 0, const char* edgeName = 0)
{
if (!buffer || visited(buffer))
return;
countObjectSize(buffer, ownerObjectType, size);
+ reportLinkToBuffer(owner, buffer, ownerObjectType, size, nodeName, edgeName);
}
+ WTF_EXPORT_PRIVATE void reportLinkToBuffer(const void* owner, const void* buffer, MemoryObjectType ownerObjectType, size_t, const char* nodeName, const char* edgeName);
template<typename T>
struct OwningTraits { // Default byReference implementation.
- static void addObject(MemoryInstrumentation* instrumentation, const T& t, MemoryObjectInfo* ownerObjectInfo)
+ static void addObject(MemoryInstrumentation* instrumentation, const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName)
{
- instrumentation->addObjectImpl(&t, ownerObjectInfo, byReference);
+ instrumentation->addObjectImpl(&t, ownerObjectInfo, byReference, edgeName);
}
};
template<typename T>
struct OwningTraits<T*> { // Custom byPointer implementation.
- static void addObject(MemoryInstrumentation* instrumentation, const T* const& t, MemoryObjectInfo* ownerObjectInfo)
+ static void addObject(MemoryInstrumentation* instrumentation, const T* const& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName)
{
- instrumentation->addObjectImpl(t, ownerObjectInfo, byPointer);
+ instrumentation->addObjectImpl(t, ownerObjectInfo, byPointer, edgeName);
}
};
- template<typename T> void addObjectImpl(const T* const&, MemoryObjectInfo*, MemoryOwningType);
- template<typename T> void addObjectImpl(const OwnPtr<T>* const&, MemoryObjectInfo*, MemoryOwningType);
- template<typename T> void addObjectImpl(const RefPtr<T>* const&, MemoryObjectInfo*, MemoryOwningType);
+ template<typename T> void addObjectImpl(const T* const&, MemoryObjectInfo*, MemoryOwningType, const char* edgeName);
+ template<typename T> void addObjectImpl(const OwnPtr<T>* const&, MemoryObjectInfo*, MemoryOwningType, const char* edgeName);
+ template<typename T> void addObjectImpl(const RefPtr<T>* const&, MemoryObjectInfo*, MemoryOwningType, const char* edgeName);
MemoryInstrumentationClient* m_client;
OwnPtr<MemoryObjectInfo> m_rootObjectInfo;
@@ -178,9 +187,12 @@
init(pointer, objectType, actualSize);
}
- template<typename M> void addMember(const M& member) { m_memoryInstrumentation->addObject(member, m_memoryObjectInfo); }
- WTF_EXPORT_PRIVATE void addRawBuffer(const void* const& buffer, size_t);
- WTF_EXPORT_PRIVATE void addPrivateBuffer(size_t, MemoryObjectType ownerObjectType = 0);
+ template<typename M> void addMember(const M& member, const char* edgeName = 0)
+ {
+ m_memoryInstrumentation->addObject(member, m_memoryObjectInfo, edgeName);
+ }
+ WTF_EXPORT_PRIVATE void addRawBuffer(const void* const& buffer, size_t, const char* nodeName = 0, const char* edgeName = 0);
+ WTF_EXPORT_PRIVATE void addPrivateBuffer(size_t, MemoryObjectType ownerObjectType = 0, const char* nodeName = 0, const char* edgeName = 0);
void addWeakPointer(void*) { }
@@ -199,11 +211,12 @@
}
template<typename T>
-void MemoryInstrumentation::addObjectImpl(const T* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType)
+void MemoryInstrumentation::addObjectImpl(const T* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType, const char* edgeName)
{
if (owningType == byReference)
reportMemoryUsage(object, ownerObjectInfo);
else {
+ reportEdge(ownerObjectInfo, object, edgeName);
if (!object || visited(object))
return;
deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object, ownerObjectInfo)));
@@ -211,19 +224,19 @@
}
template<typename T>
-void MemoryInstrumentation::addObjectImpl(const OwnPtr<T>* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType)
+void MemoryInstrumentation::addObjectImpl(const OwnPtr<T>* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType, const char* edgeName)
{
if (owningType == byPointer && !visited(object))
countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object));
- addObjectImpl(object->get(), ownerObjectInfo, byPointer);
+ addObjectImpl(object->get(), ownerObjectInfo, byPointer, edgeName);
}
template<typename T>
-void MemoryInstrumentation::addObjectImpl(const RefPtr<T>* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType)
+void MemoryInstrumentation::addObjectImpl(const RefPtr<T>* const& object, MemoryObjectInfo* ownerObjectInfo, MemoryOwningType owningType, const char* edgeName)
{
if (owningType == byPointer && !visited(object))
countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object));
- addObjectImpl(object->get(), ownerObjectInfo, byPointer);
+ addObjectImpl(object->get(), ownerObjectInfo, byPointer, edgeName);
}
template<typename T>
Modified: trunk/Source/WTF/wtf/MemoryObjectInfo.h (136562 => 136563)
--- trunk/Source/WTF/wtf/MemoryObjectInfo.h 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Source/WTF/wtf/MemoryObjectInfo.h 2012-12-04 22:02:12 UTC (rev 136563)
@@ -31,6 +31,8 @@
#ifndef MemoryObjectInfo_h
#define MemoryObjectInfo_h
+#include <wtf/text/WTFString.h>
+
namespace WTF {
class MemoryClassInfo;
@@ -53,6 +55,9 @@
size_t objectSize() const { return m_objectSize; }
const void* reportedPointer() const { return m_pointer; }
+ void setClassName(const String& className) { m_className = className; }
+ void setName(const String& name) { m_name = name; }
+
MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; }
private:
@@ -73,6 +78,8 @@
MemoryObjectType m_objectType;
size_t m_objectSize;
const void* m_pointer;
+ String m_className;
+ String m_name;
};
} // namespace WTF
Modified: trunk/Source/WebCore/inspector/MemoryInstrumentationImpl.h (136562 => 136563)
--- trunk/Source/WebCore/inspector/MemoryInstrumentationImpl.h 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Source/WebCore/inspector/MemoryInstrumentationImpl.h 2012-12-04 22:02:12 UTC (rev 136563)
@@ -81,6 +81,10 @@
virtual void countObjectSize(const void*, MemoryObjectType, size_t) OVERRIDE;
virtual bool visited(const void*) OVERRIDE;
virtual bool checkCountedObject(const void*) OVERRIDE;
+ virtual void reportNode(const MemoryObjectInfo&) OVERRIDE { }
+ virtual void reportEdge(const void*, const void*, const char*) OVERRIDE { }
+ virtual void reportLeaf(const void*, const MemoryObjectInfo&, const char*) OVERRIDE { }
+ virtual void reportBaseAddress(const void*, const void*) OVERRIDE { }
void reportMemoryUsage(MemoryObjectInfo*) const;
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp (136562 => 136563)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp 2012-12-04 22:01:11 UTC (rev 136562)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp 2012-12-04 22:02:12 UTC (rev 136563)
@@ -92,6 +92,10 @@
}
virtual bool visited(const void* object) { return !m_visitedObjects.add(object).isNewEntry; }
virtual bool checkCountedObject(const void*) { return true; }
+ virtual void reportNode(const MemoryObjectInfo&) OVERRIDE { }
+ virtual void reportEdge(const void*, const void*, const char*) OVERRIDE { }
+ virtual void reportLeaf(const void*, const MemoryObjectInfo&, const char*) OVERRIDE { }
+ virtual void reportBaseAddress(const void*, const void*) OVERRIDE { }
size_t visitedObjects() const { return m_visitedObjects.size(); }
size_t totalSize(const MemoryObjectType objectType) const
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo/webkit-changes
