Changeset 144527 in webkit


Ignore:
Timestamp:
Mar 1, 2013 9:23:18 PM (11 years ago)
Author:
loislo@chromium.org
Message:

Web Inspector: Native Memory Instrumentation: do not visit raw pointers by default.
https://bugs.webkit.org/show_bug.cgi?id=110943

Reviewed by Yury Semikhatsky.

Unfortunately in many cases raw pointer may point to an object that has been deleted.
There is no working solution to solve this problem in general.
It could be solved only on case by case basis.

Source/WebCore:

  • inspector/HeapGraphSerializer.cpp:

(WebCore::HeapGraphSerializer::HeapGraphSerializer):
(WebCore::HeapGraphSerializer::reportLeaf):

  • loader/cache/MemoryCache.cpp:

(WebCore::MemoryCache::reportMemoryUsage):

  • platform/graphics/BitmapImage.cpp:

(WebCore::FrameData::reportMemoryUsage):

  • platform/graphics/skia/MemoryInstrumentationSkia.cpp:

(reportMemoryUsage):

Source/WTF:

  • wtf/MemoryInstrumentation.h:

(WTF::MemoryInstrumentation::addObject):
(WTF::MemoryInstrumentation::MemberTypeTraits::addObject):
(WTF::MemoryClassInfo::addMember):
(WTF::MemoryInstrumentation::addObjectImpl):

  • wtf/MemoryInstrumentationString.h:

(WTF::reportMemoryUsage):

Tools:

  • TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp:
  • TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp:

(TestWebKitAPI::TEST):

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r144498 r144527  
     12013-03-01  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Web Inspector: Native Memory Instrumentation: do not visit raw pointers by default.
     4        https://bugs.webkit.org/show_bug.cgi?id=110943
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        Unfortunately in many cases raw pointer may point to an object that has been deleted.
     9        There is no working solution to solve this problem in general.
     10        It could be solved only on case by case basis.
     11
     12        * wtf/MemoryInstrumentation.h:
     13        (WTF::MemoryInstrumentation::addObject):
     14        (WTF::MemoryInstrumentation::MemberTypeTraits::addObject):
     15        (WTF::MemoryClassInfo::addMember):
     16        (WTF::MemoryInstrumentation::addObjectImpl):
     17        * wtf/MemoryInstrumentationString.h:
     18        (WTF::reportMemoryUsage):
     19
    1202013-03-01  Eric Seidel  <eric@webkit.org>
    221
  • trunk/Source/WTF/wtf/MemoryInstrumentation.h

    r143913 r144527  
    4949    PointerMember,
    5050    ReferenceMember,
    51     OwnPtrMember,
    52     RefPtrMember,
     51    RetainingPointer,
    5352    LastMemberTypeEntry
    5453};
     
    168167    };
    169168
    170     template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName) { MemberTypeTraits<T>::addObject(this, t, ownerObjectInfo, edgeName); }
     169    template<typename T> void addObject(const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName, MemberType memberType)
     170    {
     171        MemberTypeTraits<T>::addObject(this, t, ownerObjectInfo, edgeName, memberType);
     172    }
    171173    void addRawBuffer(const void* buffer, MemoryObjectType ownerObjectType, size_t size, const char* className = 0, const char* edgeName = 0)
    172174    {
     
    180182    template<typename T>
    181183    struct MemberTypeTraits { // Default ReferenceMember implementation.
    182         static void addObject(MemoryInstrumentation* instrumentation, const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName)
     184        static void addObject(MemoryInstrumentation* instrumentation, const T& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName, MemberType)
    183185        {
    184186            instrumentation->addObjectImpl(&t, ownerObjectInfo, ReferenceMember, edgeName);
     
    193195    template<typename T>
    194196    struct MemberTypeTraits<T*> { // Custom PointerMember implementation.
    195         static void addObject(MemoryInstrumentation* instrumentation, const T* const& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName)
     197        static void addObject(MemoryInstrumentation* instrumentation, const T* const& t, MemoryObjectInfo* ownerObjectInfo, const char* edgeName, MemberType memberType)
    196198        {
    197             instrumentation->addObjectImpl(t, ownerObjectInfo, PointerMember, edgeName);
     199            instrumentation->addObjectImpl(t, ownerObjectInfo, memberType != LastMemberTypeEntry ? memberType : PointerMember, edgeName);
    198200        }
    199201
     
    238240    }
    239241
    240     template<typename M> void addMember(const M& member, const char* edgeName = 0)
     242    template<typename M> void addMember(const M& member, const char* edgeName = 0, MemberType memberType = LastMemberTypeEntry)
    241243    {
    242244        if (!m_skipMembers)
    243             m_memoryInstrumentation->addObject(member, m_memoryObjectInfo, edgeName);
     245            m_memoryInstrumentation->addObject(member, m_memoryObjectInfo, edgeName, memberType);
    244246    }
    245247
     
    285287void MemoryInstrumentation::addObjectImpl(const T* object, MemoryObjectInfo* ownerObjectInfo, MemberType memberType, const char* edgeName)
    286288{
     289    if (memberType == PointerMember)
     290        return;
    287291    if (memberType == ReferenceMember)
    288292        reportMemoryUsage(object, ownerObjectInfo);
     
    302306    if (memberType == PointerMember && !visited(object))
    303307        countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object));
    304     addObjectImpl(object->get(), ownerObjectInfo, OwnPtrMember, edgeName);
     308    addObjectImpl(object->get(), ownerObjectInfo, RetainingPointer, edgeName);
    305309}
    306310
     
    310314    if (memberType == PointerMember && !visited(object))
    311315        countObjectSize(object, getObjectType(ownerObjectInfo), sizeof(*object));
    312     addObjectImpl(object->get(), ownerObjectInfo, RefPtrMember, edgeName);
     316    addObjectImpl(object->get(), ownerObjectInfo, RetainingPointer, edgeName);
    313317}
    314318
  • trunk/Source/WTF/wtf/MemoryInstrumentationString.h

    r141591 r144527  
    5555
    5656    if (StringImpl* baseString = stringImpl->baseString())
    57         info.addMember(baseString, "baseString");
     57        info.addMember(baseString, "baseString", RetainingPointer);
    5858    else {
    5959        if (stringImpl->hasOwnedBuffer())
     
    6868{
    6969    MemoryClassInfo info(memoryObjectInfo, string);
    70     info.addMember(string->impl(), "stringImpl");
     70    info.addMember(string->impl(), "stringImpl", RetainingPointer);
    7171}
    7272
     
    8585{
    8686    MemoryClassInfo info(memoryObjectInfo, cString);
    87     info.addMember(cString->buffer(), "buffer");
     87    info.addMember(cString->buffer(), "buffer", RetainingPointer);
    8888}
    8989
  • trunk/Source/WebCore/ChangeLog

    r144526 r144527  
     12013-03-01  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Web Inspector: Native Memory Instrumentation: do not visit raw pointers by default.
     4        https://bugs.webkit.org/show_bug.cgi?id=110943
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        Unfortunately in many cases raw pointer may point to an object that has been deleted.
     9        There is no working solution to solve this problem in general.
     10        It could be solved only on case by case basis.
     11
     12        * inspector/HeapGraphSerializer.cpp:
     13        (WebCore::HeapGraphSerializer::HeapGraphSerializer):
     14        (WebCore::HeapGraphSerializer::reportLeaf):
     15        * loader/cache/MemoryCache.cpp:
     16        (WebCore::MemoryCache::reportMemoryUsage):
     17        * platform/graphics/BitmapImage.cpp:
     18        (WebCore::FrameData::reportMemoryUsage):
     19        * platform/graphics/skia/MemoryInstrumentationSkia.cpp:
     20        (reportMemoryUsage):
     21
    1222013-03-01  Kentaro Hara  <haraken@chromium.org>
    223
  • trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp

    r143913 r144527  
    6060
    6161    m_edgeTypes[WTF::PointerMember] = registerTypeString("weak");
    62     m_edgeTypes[WTF::OwnPtrMember] = m_edgeTypes[WTF::RefPtrMember] = registerTypeString("property");
     62    m_edgeTypes[WTF::RetainingPointer] = registerTypeString("property");
    6363
    6464    // FIXME: It is used as a magic constant for 'object' node type.
     
    149149{
    150150    int nodeId = reportNodeImpl(info, 0);
    151     reportEdgeImpl(nodeId, edgeName, m_edgeTypes[WTF::OwnPtrMember]);
     151    reportEdgeImpl(nodeId, edgeName, m_edgeTypes[WTF::RetainingPointer]);
    152152    pushUpdateIfNeeded();
    153153}
  • trunk/Source/WebCore/loader/cache/MemoryCache.cpp

    r144446 r144527  
    801801    info.addMember(m_allResources, "allResources");
    802802    info.addMember(m_liveDecodedResources, "liveDecodedResources");
     803#if !ENABLE(CACHE_PARTITIONING)
     804    for (CachedResourceMap::const_iterator i = m_resources.begin(); i != m_resources.end(); ++i)
     805        info.addMember(i->value, "cachedResourceItem", WTF::RetainingPointer);
     806#endif
    803807}
    804808
  • trunk/Source/WebCore/platform/graphics/BitmapImage.cpp

    r141637 r144527  
    592592    info.addRawBuffer(m_frame.get(), m_frameBytes, "NativeImage", "frame");
    593593#elif USE(SKIA)
    594     info.addMember(m_frame, "frame");
     594    info.addMember(m_frame, "frame", WTF::RetainingPointer);
    595595#else
    596596    info.addRawBuffer(m_frame, m_frameBytes, "NativeImage", "frame");
  • trunk/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp

    r141570 r144527  
    5252{
    5353    WTF::MemoryClassInfo info(memoryObjectInfo, device);
    54     info.addMember(const_cast<SkDevice*>(device)->accessBitmap(false), "bitmap");
     54    info.addMember(const_cast<SkDevice*>(device)->accessBitmap(false), "bitmap", WTF::RetainingPointer);
    5555}
    5656
     
    5858{
    5959    WTF::MemoryClassInfo info(memoryObjectInfo, canvas);
    60     info.addMember(canvas->getDevice(), "canvas");
     60    info.addMember(canvas->getDevice(), "canvas", WTF::RetainingPointer);
    6161}
  • trunk/Tools/ChangeLog

    r144524 r144527  
     12013-03-01  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Web Inspector: Native Memory Instrumentation: do not visit raw pointers by default.
     4        https://bugs.webkit.org/show_bug.cgi?id=110943
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        Unfortunately in many cases raw pointer may point to an object that has been deleted.
     9        There is no working solution to solve this problem in general.
     10        It could be solved only on case by case basis.
     11
     12        * TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp:
     13        * TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp:
     14        (TestWebKitAPI::TEST):
     15
    1162013-03-01  Jason Anderssen  <janderssen@gmail.com>
    217
  • trunk/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp

    r143913 r144527  
    9090        m_links[WTF::PointerMember] = 0;
    9191        m_links[WTF::ReferenceMember] = 0;
    92         m_links[WTF::RefPtrMember] = 0;
    93         m_links[WTF::OwnPtrMember] = 0;
     92        m_links[WTF::RetainingPointer] = 0;
    9493    }
    9594
     
    109108    virtual void reportLeaf(const MemoryObjectInfo&, const char*) OVERRIDE
    110109    {
    111         ++m_links[WTF::OwnPtrMember];
     110        ++m_links[WTF::RetainingPointer];
    112111    }
    113112    virtual void reportBaseAddress(const void*, const void*) OVERRIDE { }
     
    197196        MemoryClassInfo info(memoryObjectInfo, this, TestType);
    198197        memoryObjectInfo->setClassName("Instrumented");
    199         info.addMember(m_notInstrumented, "m_notInstrumented");
     198        info.addMember(m_notInstrumented, "m_notInstrumented", WTF::RetainingPointer);
    200199    }
    201200
     
    216215    EXPECT_EQ(sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
    217216    EXPECT_EQ(1u, helper.visitedObjects());
    218     EXPECT_EQ(1u, helper.linksCount(WTF::PointerMember));
     217    EXPECT_EQ(1u, helper.linksCount(WTF::RetainingPointer));
    219218}
    220219
     
    226225    EXPECT_EQ(0u, helper.reportedSizeForAllTypes());
    227226    EXPECT_EQ(0u, helper.visitedObjects());
    228     EXPECT_EQ(0u, helper.linksCount(WTF::PointerMember));
     227    EXPECT_EQ(0u, helper.linksCount(WTF::RetainingPointer));
    229228}
    230229
     
    237236        EXPECT_EQ(sizeof(Instrumented) + sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
    238237        EXPECT_EQ(2u, helper.visitedObjects());
    239         EXPECT_EQ(1u, helper.linksCount(WTF::PointerMember));
     238        EXPECT_EQ(1u, helper.linksCount(WTF::RetainingPointer));
    240239    }
    241240    {
     
    245244        EXPECT_EQ(sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
    246245        EXPECT_EQ(1u, helper.visitedObjects());
    247         EXPECT_EQ(1u, helper.linksCount(WTF::PointerMember));
     246        EXPECT_EQ(1u, helper.linksCount(WTF::RetainingPointer));
    248247    }
    249248}
     
    269268    EXPECT_EQ(2u * sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
    270269    EXPECT_EQ(2u, helper.visitedObjects());
    271     EXPECT_EQ(1u, helper.linksCount(WTF::OwnPtrMember));
    272     EXPECT_EQ(1u, helper.linksCount(WTF::PointerMember));
     270    EXPECT_EQ(2u, helper.linksCount(WTF::RetainingPointer));
    273271}
    274272
     
    335333    {
    336334        MemoryClassInfo info(memoryObjectInfo, this, TestType);
    337         info.addMember(m_value);
     335        info.addMember(m_value, "value", WTF::RetainingPointer);
    338336    }
    339337
     
    650648}
    651649
     650class InstrumentedRefCounted : public RefCounted<InstrumentedRefCounted> {
     651public:
     652    InstrumentedRefCounted() : m_notInstrumented(new NotInstrumented) { }
     653    ~InstrumentedRefCounted() { delete m_notInstrumented; }
     654   
     655    void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     656    {
     657        MemoryClassInfo info(memoryObjectInfo, this, TestType);
     658        info.addMember(m_notInstrumented, "m_notInstrumented", WTF::RetainingPointer);
     659    }
     660private:
     661    NotInstrumented* m_notInstrumented;
     662};
     663
    652664TEST(MemoryInstrumentationTest, hashMapWithInstrumentedPointerKeysAndPointerValues)
    653665{
    654666    InstrumentationTestHelper helper;
    655667
    656     typedef HashMap<Instrumented*, Instrumented*> InstrumentedToInstrumentedMap;
     668    typedef HashMap<RefPtr<InstrumentedRefCounted>, RefPtr<InstrumentedRefCounted> > InstrumentedToInstrumentedMap;
    657669    OwnPtr<InstrumentedToInstrumentedMap> value(adoptPtr(new InstrumentedToInstrumentedMap()));
    658     Vector<OwnPtr<Instrumented> > valuesVector;
    659670    size_t count = 10;
    660     for (size_t i = 0; i < count; ++i) {
    661         valuesVector.append(adoptPtr(new Instrumented()));
    662         valuesVector.append(adoptPtr(new Instrumented()));
    663         value->set(valuesVector[2 * i].get(), valuesVector[2 * i + 1].get());
    664     }
     671    for (size_t i = 0; i < count; ++i)
     672        value->set(adoptRef(new InstrumentedRefCounted()), adoptRef(new InstrumentedRefCounted()));
    665673    InstrumentedOwner<InstrumentedToInstrumentedMap* > root(value.get());
    666674    helper.addRootObject(root);
    667     EXPECT_EQ(sizeof(InstrumentedToInstrumentedMap) + sizeof(InstrumentedToInstrumentedMap::ValueType) * value->capacity() + 2 * (sizeof(Instrumented) + sizeof(NotInstrumented)) * value->size(), helper.reportedSizeForAllTypes());
     675    EXPECT_EQ(sizeof(InstrumentedToInstrumentedMap)
     676        + sizeof(InstrumentedToInstrumentedMap::ValueType) * value->capacity()
     677        + 2 * (sizeof(InstrumentedRefCounted) + sizeof(NotInstrumented)) * value->size(),
     678        helper.reportedSizeForAllTypes());
    668679    EXPECT_EQ(2u * 2u * count + 1, helper.visitedObjects());
    669680}
     
    706717}
    707718
    708 class InstrumentedConvertibleToInt {
    709 public:
    710     InstrumentedConvertibleToInt() : m_notInstrumented(0) { }
    711     virtual ~InstrumentedConvertibleToInt() { }
     719class InstrumentedConvertibleToInt : public RefCounted<InstrumentedConvertibleToInt> {
     720public:
     721    InstrumentedConvertibleToInt() : m_notInstrumented(new NotInstrumented) { }
     722    virtual ~InstrumentedConvertibleToInt() { delete m_notInstrumented; }
    712723
    713724    virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     
    730741    InstrumentationTestHelper helper;
    731742
    732     typedef HashMap<InstrumentedConvertibleToInt*, InstrumentedConvertibleToInt> TestMap;
     743    typedef HashMap<RefPtr<InstrumentedConvertibleToInt>, int> TestMap;
    733744    OwnPtr<TestMap> value(adoptPtr(new TestMap()));
    734     Vector<OwnPtr<InstrumentedConvertibleToInt> > keysVector;
    735     Vector<OwnPtr<NotInstrumented> > valuesVector;
    736745    size_t count = 10;
    737     for (size_t i = 0; i < count; ++i) {
    738         keysVector.append(adoptPtr(new InstrumentedConvertibleToInt()));
    739         valuesVector.append(adoptPtr(new NotInstrumented()));
    740         value->set(keysVector[i].get(), InstrumentedConvertibleToInt()).iterator->value.m_notInstrumented = valuesVector[i].get();
    741     }
     746    for (size_t i = 0; i < count; ++i)
     747        value->set(adoptRef(new InstrumentedConvertibleToInt()), 0);
    742748    InstrumentedOwner<TestMap* > root(value.get());
    743749    helper.addRootObject(root);
     
    758764    InstrumentedOwner<EnumToStringMap* > root(value.get());
    759765    helper.addRootObject(root);
    760     EXPECT_EQ(sizeof(EnumToStringMap) + sizeof(EnumToStringMap::ValueType) * value->capacity() + (sizeof(StringImpl) + 1) * value->size(), helper.reportedSizeForAllTypes());
     766    EXPECT_EQ(sizeof(EnumToStringMap)
     767        + sizeof(EnumToStringMap::ValueType) * value->capacity()
     768        + (sizeof(StringImpl) + 1) * value->size(),
     769        helper.reportedSizeForAllTypes());
    761770    EXPECT_EQ(count + 1, helper.visitedObjects());
    762771}
     
    766775    InstrumentationTestHelper helper;
    767776
    768     typedef HashCountedSet<Instrumented*> TestSet;
     777    typedef HashCountedSet<RefPtr<InstrumentedRefCounted> > TestSet;
    769778    OwnPtr<TestSet> set(adoptPtr(new TestSet()));
    770     Vector<OwnPtr<Instrumented> > keysVector;
    771779    size_t count = 10;
    772780    for (size_t i = 0; i < count; ++i) {
    773         keysVector.append(adoptPtr(new Instrumented()));
     781        RefPtr<InstrumentedRefCounted> instrumentedRefCounted = adoptRef(new InstrumentedRefCounted());
    774782        for (size_t j = 0; j <= i; j++)
    775             set->add(keysVector.last().get());
     783            set->add(instrumentedRefCounted);
    776784    }
    777785    InstrumentedOwner<TestSet* > root(set.get());
    778786    helper.addRootObject(root);
    779     EXPECT_EQ(sizeof(TestSet) + sizeof(HashMap<Instrumented*, unsigned>::ValueType) * set->capacity() + (sizeof(Instrumented) + sizeof(NotInstrumented))  * set->size(), helper.reportedSizeForAllTypes());
     787    EXPECT_EQ(sizeof(TestSet)
     788        + sizeof(HashMap<RefPtr<InstrumentedRefCounted>, unsigned>::ValueType) * set->capacity()
     789        + (sizeof(InstrumentedRefCounted) + sizeof(NotInstrumented))  * set->size(),
     790        helper.reportedSizeForAllTypes());
    780791    EXPECT_EQ(2u * count + 1, helper.visitedObjects());
    781792}
     
    790801    EXPECT_EQ(sizeof(int) * 1000 + sizeof(ArrayBuffer), helper.reportedSizeForAllTypes());
    791802    EXPECT_EQ(2u, helper.visitedObjects());
    792     EXPECT_EQ(1u, helper.linksCount(WTF::RefPtrMember));
     803    EXPECT_EQ(2u, helper.linksCount(WTF::RetainingPointer));
    793804}
    794805
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp

    r143913 r144527  
    249249    Helper helper(receiver.serializer());
    250250    void* childObject = helper.addNode("Child", "child", false);
    251     helper.addEdge(childObject, "pointerToChild", WTF::OwnPtrMember);
     251    helper.addEdge(childObject, "pointerToChild", WTF::RetainingPointer);
    252252    helper.addNode("Parent", "parent", true);
    253253    helper.done();
     
    286286    receiver.printGraph();
    287287    EXPECT_EQ(String("[6,0,1,0,0,5,0,4,0,3,9,0,3,0,0,9,0,2,0,0,10,0,5,0,1]"), receiver.dumpNodes());
    288     EXPECT_EQ(String("[2,7,1,1,8,2,1,8,3,1,0,4]"), receiver.dumpEdges());
     288    EXPECT_EQ(String("[2,7,1,2,8,2,2,8,3,1,0,4]"), receiver.dumpEdges());
    289289    EXPECT_EQ(String("[]"), receiver.dumpBaseToRealNodeId());
    290290}
Note: See TracChangeset for help on using the changeset viewer.