Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (137260 => 137261)
--- trunk/Source/_javascript_Core/ChangeLog 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-12-11 08:32:58 UTC (rev 137261)
@@ -1,3 +1,14 @@
+2012-12-10 Yury Semikhatsky <[email protected]>
+
+ Memory instrumentation: make sure each edge is reported only once
+ https://bugs.webkit.org/show_bug.cgi?id=104630
+
+ Reviewed by Pavel Feldman.
+
+ Changed exported symbols for MemoryInstrumentation.
+
+ * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.def:
+
2012-12-10 Filip Pizlo <[email protected]>
Don't OSR exit just because a string is a rope
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (137260 => 137261)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-12-11 08:32:58 UTC (rev 137261)
@@ -12,7 +12,7 @@
??0DropAllLocks@JSLock@JSC@@QAE@PAVJSGlobalData@2@@Z
??0DynamicGlobalObjectScope@JSC@@QAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@@Z
??0ErrorHandlingMode@Interpreter@JSC@@QAE@PAVExecState@2@@Z
- ??0InstrumentedPointerBase@MemoryInstrumentation@WTF@@QAE@PAVMemoryObjectInfo@2@@Z
+ ??0InstrumentedPointerBase@MemoryInstrumentation@WTF@@QAE@PAVMemoryObjectInfo@2@PBX@Z
??0InternalFunction@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@@Z
??0JSGlobalObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@PBUGlobalObjectMethodTable@1@@Z
??0JSLockHolder@JSC@@QAE@AAVJSGlobalData@1@@Z
Modified: trunk/Source/WTF/ChangeLog (137260 => 137261)
--- trunk/Source/WTF/ChangeLog 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Source/WTF/ChangeLog 2012-12-11 08:32:58 UTC (rev 137261)
@@ -1,3 +1,39 @@
+2012-12-10 Yury Semikhatsky <[email protected]>
+
+ Memory instrumentation: make sure each edge is reported only once
+ https://bugs.webkit.org/show_bug.cgi?id=104630
+
+ Reviewed by Pavel Feldman.
+
+ Make sure that outgoing edges are reported only once if we come to the same
+ object twice: first by an address of a base class and then by a real address
+ of the object.
+
+ * wtf/MemoryInstrumentation.cpp:
+ (WTF::MemoryInstrumentation::MemoryInstrumentation):
+ (WTF::MemoryInstrumentation::reportLinkToBuffer):
+ (WTF::MemoryInstrumentation::InstrumentedPointerBase::InstrumentedPointerBase):
+ (WTF::MemoryInstrumentation::InstrumentedPointerBase::process):
+ (WTF::MemoryClassInfo::init):
+ (WTF::MemoryClassInfo::addRawBuffer):
+ (WTF::MemoryClassInfo::addPrivateBuffer):
+ * wtf/MemoryInstrumentation.h:
+ (InstrumentedPointerBase):
+ (MemoryInstrumentation):
+ (InstrumentedPointer):
+ (WTF::MemoryClassInfo::MemoryClassInfo):
+ (WTF::MemoryClassInfo::addMember):
+ (MemoryClassInfo):
+ (WTF::::InstrumentedPointer):
+ (WTF::::callReportMemoryUsage):
+ * wtf/MemoryObjectInfo.h:
+ (WTF::MemoryObjectInfo::MemoryObjectInfo):
+ (WTF::MemoryObjectInfo::firstVisit):
+ (WTF::MemoryObjectInfo::className):
+ (WTF::MemoryObjectInfo::name):
+ (WTF::MemoryObjectInfo::setAlreadyVisited):
+ (MemoryObjectInfo):
+
2012-12-10 Benjamin Poulain <[email protected]>
Add convenience methods to use ListHashSet for a LRU cache
Modified: trunk/Source/WTF/wtf/MemoryInstrumentation.cpp (137260 => 137261)
--- trunk/Source/WTF/wtf/MemoryInstrumentation.cpp 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Source/WTF/wtf/MemoryInstrumentation.cpp 2012-12-11 08:32:58 UTC (rev 137261)
@@ -42,7 +42,7 @@
MemoryInstrumentation::MemoryInstrumentation(MemoryInstrumentationClient* client)
: m_client(client)
- , m_rootObjectInfo(adoptPtr(new MemoryObjectInfo(this, 0)))
+ , m_rootObjectInfo(adoptPtr(new MemoryObjectInfo(this, 0, 0)))
{
}
@@ -67,14 +67,15 @@
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 memoryObjectInfo(this, ownerObjectType, 0);
memoryObjectInfo.reportObjectInfo(buffer, ownerObjectType, size);
memoryObjectInfo.setName(nodeName);
m_client->reportLeaf(owner, memoryObjectInfo, edgeName);
}
-MemoryInstrumentation::InstrumentedPointerBase::InstrumentedPointerBase(MemoryObjectInfo* memoryObjectInfo)
- : m_ownerObjectType(memoryObjectInfo->objectType())
+MemoryInstrumentation::InstrumentedPointerBase::InstrumentedPointerBase(MemoryObjectInfo* memoryObjectInfo, const void* pointer)
+ : m_pointer(pointer)
+ , m_ownerObjectType(memoryObjectInfo->objectType())
{
#if DEBUG_POINTER_INSTRUMENTATION
m_callStackSize = s_maxCallStackSize;
@@ -84,19 +85,19 @@
void MemoryInstrumentation::InstrumentedPointerBase::process(MemoryInstrumentation* memoryInstrumentation)
{
- MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType);
- const void* originalPointer = callReportMemoryUsage(&memoryObjectInfo);
+ MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType, m_pointer);
+ callReportMemoryUsage(&memoryObjectInfo);
- const void* pointer = memoryObjectInfo.reportedPointer();
- ASSERT(pointer);
- if (pointer != originalPointer) {
- memoryInstrumentation->m_client->reportBaseAddress(originalPointer, pointer);
- if (memoryInstrumentation->visited(pointer))
+ const void* realAddress = memoryObjectInfo.reportedPointer();
+ ASSERT(realAddress);
+ if (realAddress != m_pointer) {
+ memoryInstrumentation->m_client->reportBaseAddress(m_pointer, realAddress);
+ if (!memoryObjectInfo.firstVisit())
return;
}
- memoryInstrumentation->countObjectSize(pointer, memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
+ memoryInstrumentation->countObjectSize(realAddress, memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
memoryInstrumentation->m_client->reportNode(memoryObjectInfo);
- if (!memoryInstrumentation->checkCountedObject(pointer)) {
+ if (!memoryInstrumentation->checkCountedObject(realAddress)) {
#if DEBUG_POINTER_INSTRUMENTATION
fputs("Unknown object counted:\n", stderr);
WTFPrintBacktrace(m_callStack, m_callStackSize);
@@ -104,22 +105,26 @@
}
}
-void MemoryClassInfo::init(const void* pointer, MemoryObjectType objectType, size_t actualSize)
+void MemoryClassInfo::init(const void* objectAddress, MemoryObjectType objectType, size_t actualSize)
{
- m_memoryObjectInfo->reportObjectInfo(pointer, objectType, actualSize);
+ m_memoryObjectInfo->reportObjectInfo(objectAddress, objectType, actualSize);
m_memoryInstrumentation = m_memoryObjectInfo->memoryInstrumentation();
m_objectType = m_memoryObjectInfo->objectType();
+ m_skipMembers = !m_memoryObjectInfo->firstVisit();
}
void MemoryClassInfo::addRawBuffer(const void* buffer, size_t size, const char* nodeName, const char* edgeName)
{
- m_memoryInstrumentation->addRawBuffer(m_memoryObjectInfo->reportedPointer(), buffer, m_objectType, size, nodeName, edgeName);
+ if (!m_skipMembers)
+ m_memoryInstrumentation->addRawBuffer(m_memoryObjectInfo->reportedPointer(), buffer, m_objectType, size, nodeName, edgeName);
}
void MemoryClassInfo::addPrivateBuffer(size_t size, MemoryObjectType ownerObjectType, const char* nodeName, const char* edgeName)
{
if (!size)
return;
+ if (m_skipMembers)
+ return;
if (!ownerObjectType)
ownerObjectType = m_objectType;
m_memoryInstrumentation->countObjectSize(0, ownerObjectType, size);
Modified: trunk/Source/WTF/wtf/MemoryInstrumentation.h (137260 => 137261)
--- trunk/Source/WTF/wtf/MemoryInstrumentation.h 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Source/WTF/wtf/MemoryInstrumentation.h 2012-12-11 08:32:58 UTC (rev 137261)
@@ -79,12 +79,13 @@
protected:
class InstrumentedPointerBase {
public:
- WTF_EXPORT_PRIVATE explicit InstrumentedPointerBase(MemoryObjectInfo*);
+ WTF_EXPORT_PRIVATE InstrumentedPointerBase(MemoryObjectInfo*, const void* pointer);
virtual ~InstrumentedPointerBase() { }
WTF_EXPORT_PRIVATE void process(MemoryInstrumentation*);
protected:
- virtual const void* callReportMemoryUsage(MemoryObjectInfo*) = 0;
+ virtual void callReportMemoryUsage(MemoryObjectInfo*) = 0;
+ const void* m_pointer;
private:
const MemoryObjectType m_ownerObjectType;
@@ -107,6 +108,7 @@
WTF_EXPORT_PRIVATE static MemoryObjectType getObjectType(MemoryObjectInfo*);
+ friend class MemoryObjectInfo;
friend class MemoryClassInfo;
template<typename T> friend void reportMemoryUsage(const T*, MemoryObjectInfo*);
@@ -136,10 +138,7 @@
InstrumentedPointer(const T* pointer, MemoryObjectInfo* ownerObjectInfo);
protected:
- virtual const void* callReportMemoryUsage(MemoryObjectInfo*) OVERRIDE;
-
- private:
- const T* m_pointer;
+ virtual void callReportMemoryUsage(MemoryObjectInfo*) OVERRIDE;
};
template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName) { OwningTraits<T>::addObject(this, t, ownerObjectInfo, edgeName); }
@@ -183,13 +182,15 @@
: m_memoryObjectInfo(memoryObjectInfo)
, m_memoryInstrumentation(0)
, m_objectType(0)
+ , m_skipMembers(false)
{
init(pointer, objectType, actualSize);
}
template<typename M> void addMember(const M& member, const char* edgeName = 0)
{
- m_memoryInstrumentation->addObject(member, m_memoryObjectInfo, edgeName);
+ if (!m_skipMembers)
+ m_memoryInstrumentation->addObject(member, m_memoryObjectInfo, edgeName);
}
WTF_EXPORT_PRIVATE void addRawBuffer(const void* 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);
@@ -202,6 +203,7 @@
MemoryObjectInfo* m_memoryObjectInfo;
MemoryInstrumentation* m_memoryInstrumentation;
MemoryObjectType m_objectType;
+ bool m_skipMembers;
};
template<typename T>
@@ -241,16 +243,14 @@
template<typename T>
MemoryInstrumentation::InstrumentedPointer<T>::InstrumentedPointer(const T* pointer, MemoryObjectInfo* ownerObjectInfo)
- : InstrumentedPointerBase(ownerObjectInfo)
- , m_pointer(pointer)
+ : InstrumentedPointerBase(ownerObjectInfo, pointer)
{
}
template<typename T>
-const void* MemoryInstrumentation::InstrumentedPointer<T>::callReportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
+void MemoryInstrumentation::InstrumentedPointer<T>::callReportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
{
- reportMemoryUsage(m_pointer, memoryObjectInfo);
- return m_pointer;
+ reportMemoryUsage(static_cast<const T*>(m_pointer), memoryObjectInfo);
}
// Link time guard for classes with external memory instrumentation.
Modified: trunk/Source/WTF/wtf/MemoryObjectInfo.h (137260 => 137261)
--- trunk/Source/WTF/wtf/MemoryObjectInfo.h 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Source/WTF/wtf/MemoryObjectInfo.h 2012-12-11 08:32:58 UTC (rev 137261)
@@ -31,6 +31,7 @@
#ifndef MemoryObjectInfo_h
#define MemoryObjectInfo_h
+#include <wtf/MemoryInstrumentation.h>
#include <wtf/text/WTFString.h>
namespace WTF {
@@ -42,11 +43,12 @@
class MemoryObjectInfo {
public:
- MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation, MemoryObjectType ownerObjectType)
+ MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation, MemoryObjectType ownerObjectType, const void* pointer)
: m_memoryInstrumentation(memoryInstrumentation)
, m_objectType(ownerObjectType)
, m_objectSize(0)
- , m_pointer(0)
+ , m_pointer(pointer)
+ , m_firstVisit(true)
{ }
typedef MemoryClassInfo ClassInfo;
@@ -54,9 +56,12 @@
MemoryObjectType objectType() const { return m_objectType; }
size_t objectSize() const { return m_objectSize; }
const void* reportedPointer() const { return m_pointer; }
+ bool firstVisit() const { return m_firstVisit; }
void setClassName(const String& className) { m_className = className; }
+ const String& className() const { return m_className; }
void setName(const String& name) { m_name = name; }
+ const String& name() const { return m_name; }
MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; }
@@ -67,6 +72,8 @@
void reportObjectInfo(const void* pointer, MemoryObjectType objectType, size_t objectSize)
{
if (!m_objectSize) {
+ if (m_pointer != pointer && m_pointer && m_memoryInstrumentation->visited(pointer))
+ m_firstVisit = false;
m_pointer = pointer;
m_objectSize = objectSize;
if (objectType)
@@ -78,6 +85,7 @@
MemoryObjectType m_objectType;
size_t m_objectSize;
const void* m_pointer;
+ bool m_firstVisit;
String m_className;
String m_name;
};
Modified: trunk/Tools/ChangeLog (137260 => 137261)
--- trunk/Tools/ChangeLog 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Tools/ChangeLog 2012-12-11 08:32:58 UTC (rev 137261)
@@ -1,3 +1,16 @@
+2012-12-10 Yury Semikhatsky <[email protected]>
+
+ Memory instrumentation: make sure each edge is reported only once
+ https://bugs.webkit.org/show_bug.cgi?id=104630
+
+ Reviewed by Pavel Feldman.
+
+ Test that outgoing edges are reported only once if we come to the same
+ object twice: first by an address of a base class and then by a real address
+ of the object.
+
+ * TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp:
+
2012-12-10 Dana Jansens <[email protected]>
[chromium] Remove WebCompositorOutputSurface implementations from DRT
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp (137260 => 137261)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp 2012-12-11 08:05:47 UTC (rev 137260)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp 2012-12-11 08:32:58 UTC (rev 137261)
@@ -167,13 +167,21 @@
class Instrumented {
public:
Instrumented() : m_notInstrumented(new NotInstrumented) { }
- virtual ~Instrumented() { delete m_notInstrumented; }
+ virtual ~Instrumented() { disposeOwnedObject(); }
virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, TestType);
- info.addMember(m_notInstrumented);
+ memoryObjectInfo->setClassName("Instrumented");
+ info.addMember(m_notInstrumented, "m_notInstrumented");
}
+
+ void disposeOwnedObject()
+ {
+ delete m_notInstrumented;
+ m_notInstrumented = 0;
+ }
+
NotInstrumented* m_notInstrumented;
};
@@ -799,6 +807,7 @@
virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ Instrumented::reportMemoryUsage(memoryObjectInfo);
}
};
@@ -814,8 +823,8 @@
helper.addRootObject(descendantPointerOwner);
helper.addRootObject(ancestorPointerOwner);
- EXPECT_EQ(sizeof(ClassWithTwoAncestors), helper.reportedSizeForAllTypes());
- EXPECT_EQ(2u, helper.visitedObjects());
+ EXPECT_EQ(sizeof(ClassWithTwoAncestors) + sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(3u, helper.visitedObjects());
}
class CheckCountedObjectsClient : public MemoryInstrumentationTestClient {
@@ -837,6 +846,7 @@
TEST(MemoryInstrumentationTest, checkCountedObjectWithMultipleAncestors)
{
OwnPtr<ClassWithTwoAncestors> instance = adoptPtr(new ClassWithTwoAncestors());
+ instance->disposeOwnedObject();
ClassWithTwoAncestors* descendantPointer = instance.get();
InstrumentedOwner<ClassWithTwoAncestors*> descendantPointerOwner(descendantPointer);
Instrumented* ancestorPointer = descendantPointer;
@@ -850,5 +860,49 @@
EXPECT_TRUE(client.expectedPointerFound());
}
+class TwoPointersToSameInsrumented {
+public:
+ TwoPointersToSameInsrumented()
+ : m_ownPtr(adoptPtr(new ClassWithTwoAncestors()))
+ , m_baseClassPtr(m_ownPtr.get())
+ {
+ EXPECT_NE(static_cast<void*>(m_ownPtr.get()), static_cast<void*>(m_baseClassPtr));
+ }
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_ownPtr);
+ info.addMember(m_baseClassPtr);
+ }
+
+private:
+ OwnPtr<ClassWithTwoAncestors> m_ownPtr;
+ Instrumented* m_baseClassPtr;
+};
+
+class CountLinksFromInstrumentedObject : public MemoryInstrumentationTestClient {
+public:
+ CountLinksFromInstrumentedObject() : m_linkCount(0) { }
+ virtual void reportEdge(const void* source, const void* destination, const char* name) OVERRIDE
+ {
+ if (name && !strcmp("m_notInstrumented", name))
+ m_linkCount++;
+ }
+ int linkCount() const { return m_linkCount; }
+
+private:
+ int m_linkCount;
+};
+
+
+TEST(MemoryInstrumentationTest, doNotReportEdgeTwice)
+{
+ OwnPtr<TwoPointersToSameInsrumented> instance = adoptPtr(new TwoPointersToSameInsrumented());
+
+ CountLinksFromInstrumentedObject client;
+ InstrumentationTestImpl instrumentation(&client);
+ instrumentation.addRootObject(instance);
+ EXPECT_EQ(1, client.linkCount());
+}
} // namespace