Log Message
Web Inspector: Native Memory Instrumentation: reportLeaf method doesn't report the leaf node properly. https://bugs.webkit.org/show_bug.cgi?id=109554
In some cases leaves have no pointer so with the old schema we can't generate nodeId for them because we can't insert 0 into hashmap. It happens when we call addPrivateBuffer method. Drive by fix: I introduced a client interface for the HeapGraphSerializer. It helps me to do the tests for the serializer. Reviewed by Yury Semikhatsky. It is covered by newly added tests in TestWebKitAPI. Source/WebCore: * inspector/HeapGraphSerializer.cpp: (WebCore::HeapGraphSerializer::HeapGraphSerializer): (WebCore::HeapGraphSerializer::pushUpdate): (WebCore::HeapGraphSerializer::reportNode): (WebCore::HeapGraphSerializer::toNodeId): (WebCore::HeapGraphSerializer::addRootNode): * inspector/HeapGraphSerializer.h: (HeapGraphSerializer): (Client): (WebCore::HeapGraphSerializer::Client::~Client): * inspector/InspectorMemoryAgent.cpp: (WebCore): (WebCore::InspectorMemoryAgent::getProcessMemoryDistributionImpl): Tools: * TestWebKitAPI/TestWebKitAPI.gypi: * TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp: Added. (TestWebKitAPI): (HeapGraphReceiver): (TestWebKitAPI::HeapGraphReceiver::HeapGraphReceiver): (TestWebKitAPI::HeapGraphReceiver::printGraph): (TestWebKitAPI::HeapGraphReceiver::dumpNodes): (TestWebKitAPI::HeapGraphReceiver::dumpEdges): (TestWebKitAPI::HeapGraphReceiver::dumpBaseToRealNodeId): (TestWebKitAPI::HeapGraphReceiver::dumpStrings): (TestWebKitAPI::HeapGraphReceiver::serializer): (TestWebKitAPI::HeapGraphReceiver::chunkPart): (TestWebKitAPI::HeapGraphReceiver::dumpPart): (TestWebKitAPI::HeapGraphReceiver::stringValue): (TestWebKitAPI::HeapGraphReceiver::intValue): (TestWebKitAPI::HeapGraphReceiver::nodeToString): (TestWebKitAPI::HeapGraphReceiver::edgeToString): (TestWebKitAPI::HeapGraphReceiver::printNode): (Helper): (TestWebKitAPI::Helper::Helper): (TestWebKitAPI::Helper::addNode): (TestWebKitAPI::Helper::addEdge): (TestWebKitAPI::Helper::done): (Object): (TestWebKitAPI::Helper::Object::Object): (TestWebKitAPI::TEST): (Owner): (TestWebKitAPI::Owner::Owner): (TestWebKitAPI::Owner::reportMemoryUsage):
Modified Paths
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp
- trunk/Source/WebCore/inspector/HeapGraphSerializer.h
- trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp
- trunk/Tools/ChangeLog
- trunk/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp
Added Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (143174 => 143175)
--- trunk/Source/WebCore/ChangeLog 2013-02-18 09:30:22 UTC (rev 143174)
+++ trunk/Source/WebCore/ChangeLog 2013-02-18 09:54:33 UTC (rev 143175)
@@ -1,3 +1,32 @@
+2013-02-13 Ilya Tikhonovsky <[email protected]>
+
+ Web Inspector: Native Memory Instrumentation: reportLeaf method doesn't report the leaf node properly.
+ https://bugs.webkit.org/show_bug.cgi?id=109554
+
+ In some cases leaves have no pointer so with the old schema we can't generate nodeId for them because we
+ can't insert 0 into hashmap. It happens when we call addPrivateBuffer method.
+
+ Drive by fix: I introduced a client interface for the HeapGraphSerializer.
+ It helps me to do the tests for the serializer.
+
+ Reviewed by Yury Semikhatsky.
+
+ It is covered by newly added tests in TestWebKitAPI.
+
+ * inspector/HeapGraphSerializer.cpp:
+ (WebCore::HeapGraphSerializer::HeapGraphSerializer):
+ (WebCore::HeapGraphSerializer::pushUpdate):
+ (WebCore::HeapGraphSerializer::reportNode):
+ (WebCore::HeapGraphSerializer::toNodeId):
+ (WebCore::HeapGraphSerializer::addRootNode):
+ * inspector/HeapGraphSerializer.h:
+ (HeapGraphSerializer):
+ (Client):
+ (WebCore::HeapGraphSerializer::Client::~Client):
+ * inspector/InspectorMemoryAgent.cpp:
+ (WebCore):
+ (WebCore::InspectorMemoryAgent::getProcessMemoryDistributionImpl):
+
2013-02-18 Sheriff Bot <[email protected]>
Unreviewed, rolling out r143100.
Modified: trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp (143174 => 143175)
--- trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp 2013-02-18 09:30:22 UTC (rev 143174)
+++ trunk/Source/WebCore/inspector/HeapGraphSerializer.cpp 2013-02-18 09:54:33 UTC (rev 143175)
@@ -43,15 +43,16 @@
namespace WebCore {
-HeapGraphSerializer::HeapGraphSerializer(InspectorFrontend::Memory* frontend)
- : m_frontend(frontend)
+HeapGraphSerializer::HeapGraphSerializer(Client* client)
+ : m_client(client)
, m_strings(Strings::create())
, m_edges(Edges::create())
, m_nodeEdgesCount(0)
, m_nodes(Nodes::create())
, m_baseToRealNodeIdMap(BaseToRealNodeIdMap::create())
+ , m_leafCount(0)
{
- ASSERT(m_frontend);
+ ASSERT(m_client);
m_strings->addItem(String()); // An empty string with 0 index.
memset(m_edgeTypes, 0, sizeof(m_edgeTypes));
@@ -91,7 +92,7 @@
.setEdges(m_edges.release())
.setBaseToRealNodeId(m_baseToRealNodeIdMap.release());
- m_frontend->addNativeSnapshotChunk(chunk);
+ m_client->addNativeSnapshotChunk(chunk.release());
m_strings = Strings::create();
m_edges = Edges::create();
@@ -101,6 +102,7 @@
void HeapGraphSerializer::reportNode(const WTF::MemoryObjectInfo& info)
{
+ ASSERT(info.reportedPointer());
reportNodeImpl(info, m_nodeEdgesCount);
m_nodeEdgesCount = 0;
if (info.isRoot())
@@ -182,8 +184,10 @@
int HeapGraphSerializer::toNodeId(const void* to)
{
- ASSERT(to);
- Address2NodeId::AddResult result = m_address2NodeIdMap.add(to, m_address2NodeIdMap.size());
+ if (!to)
+ return s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount++;
+
+ Address2NodeId::AddResult result = m_address2NodeIdMap.add(to, s_firstNodeId + m_leafCount + m_address2NodeIdMap.size());
return result.iterator->value;
}
@@ -194,7 +198,7 @@
m_nodes->addItem(addString("Root"));
m_nodes->addItem(0);
- m_nodes->addItem(m_address2NodeIdMap.size());
+ m_nodes->addItem(s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount);
m_nodes->addItem(0);
m_nodes->addItem(m_roots.size());
}
Modified: trunk/Source/WebCore/inspector/HeapGraphSerializer.h (143174 => 143175)
--- trunk/Source/WebCore/inspector/HeapGraphSerializer.h 2013-02-18 09:30:22 UTC (rev 143174)
+++ trunk/Source/WebCore/inspector/HeapGraphSerializer.h 2013-02-18 09:54:33 UTC (rev 143175)
@@ -43,14 +43,17 @@
namespace WebCore {
-class HeapGraphEdge;
-class HeapGraphNode;
-class InspectorObject;
-
class HeapGraphSerializer {
WTF_MAKE_NONCOPYABLE(HeapGraphSerializer);
public:
- explicit HeapGraphSerializer(InspectorFrontend::Memory*);
+
+ class Client {
+ public:
+ virtual ~Client() { }
+ virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnapshotChunk>) = 0;
+ };
+
+ explicit HeapGraphSerializer(Client*);
~HeapGraphSerializer();
void reportNode(const WTF::MemoryObjectInfo&);
void reportEdge(const void*, const char*, WTF::MemberType);
@@ -73,7 +76,7 @@
void reportEdgeImpl(const int toNodeId, const char* name, int memberType);
int reportNodeImpl(const WTF::MemoryObjectInfo&, int edgesCount);
- InspectorFrontend::Memory* m_frontend;
+ Client* m_client;
typedef HashMap<String, int> StringMap;
StringMap m_stringToIndex;
@@ -100,6 +103,9 @@
size_t m_edgeTypes[WTF::LastMemberTypeEntry];
int m_unknownClassNameId;
+ int m_leafCount;
+
+ static const int s_firstNodeId = 1;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp (143174 => 143175)
--- trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp 2013-02-18 09:30:22 UTC (rev 143174)
+++ trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp 2013-02-18 09:54:33 UTC (rev 143175)
@@ -333,11 +333,31 @@
info.addMember(m_page, "page");
}
+namespace {
+
+class FrontendWrapper : public HeapGraphSerializer::Client {
+public:
+ explicit FrontendWrapper(InspectorFrontend::Memory* frontend) : m_frontend(frontend) { }
+ virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnapshotChunk> heapSnapshotChunk) OVERRIDE
+ {
+ m_frontend->addNativeSnapshotChunk(heapSnapshotChunk);
+ }
+private:
+ InspectorFrontend::Memory* m_frontend;
+};
+
+}
+
void InspectorMemoryAgent::getProcessMemoryDistributionImpl(bool reportGraph, TypeNameToSizeMap* memoryInfo)
{
OwnPtr<HeapGraphSerializer> graphSerializer;
- if (reportGraph)
- graphSerializer = adoptPtr(new HeapGraphSerializer(m_frontend));
+ OwnPtr<FrontendWrapper> frontendWrapper;
+
+ if (reportGraph) {
+ frontendWrapper = adoptPtr(new FrontendWrapper(m_frontend));
+ graphSerializer = adoptPtr(new HeapGraphSerializer(frontendWrapper.get()));
+ }
+
MemoryInstrumentationClientImpl memoryInstrumentationClient(graphSerializer.get());
m_inspectorClient->getAllocatedObjects(memoryInstrumentationClient.allocatedObjects());
MemoryInstrumentationImpl memoryInstrumentation(&memoryInstrumentationClient);
@@ -355,6 +375,8 @@
if (graphSerializer) {
memoryInstrumentation.addRootObject(graphSerializer.get());
graphSerializer->finish();
+ graphSerializer.release(); // Release it earlier than frontendWrapper
+ frontendWrapper.release();
}
m_inspectorClient->dumpUncountedAllocatedObjects(memoryInstrumentationClient.countedObjects());
Modified: trunk/Tools/ChangeLog (143174 => 143175)
--- trunk/Tools/ChangeLog 2013-02-18 09:30:22 UTC (rev 143174)
+++ trunk/Tools/ChangeLog 2013-02-18 09:54:33 UTC (rev 143175)
@@ -1,3 +1,48 @@
+2013-02-13 Ilya Tikhonovsky <[email protected]>
+
+ Web Inspector: Native Memory Instrumentation: reportLeaf method doesn't report the leaf node properly.
+ https://bugs.webkit.org/show_bug.cgi?id=109554
+
+ In some cases leaves have no pointer so with the old schema we can't generate nodeId for them because we
+ can't insert 0 into hashmap. It happens when we call addPrivateBuffer method.
+
+ Drive by fix: I introduced a client interface for the HeapGraphSerializer.
+ It helps me to do the tests for the serializer.
+
+ Reviewed by Yury Semikhatsky.
+
+ It is covered by newly added tests in TestWebKitAPI.
+
+ * TestWebKitAPI/TestWebKitAPI.gypi:
+ * TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp: Added.
+ (TestWebKitAPI):
+ (HeapGraphReceiver):
+ (TestWebKitAPI::HeapGraphReceiver::HeapGraphReceiver):
+ (TestWebKitAPI::HeapGraphReceiver::printGraph):
+ (TestWebKitAPI::HeapGraphReceiver::dumpNodes):
+ (TestWebKitAPI::HeapGraphReceiver::dumpEdges):
+ (TestWebKitAPI::HeapGraphReceiver::dumpBaseToRealNodeId):
+ (TestWebKitAPI::HeapGraphReceiver::dumpStrings):
+ (TestWebKitAPI::HeapGraphReceiver::serializer):
+ (TestWebKitAPI::HeapGraphReceiver::chunkPart):
+ (TestWebKitAPI::HeapGraphReceiver::dumpPart):
+ (TestWebKitAPI::HeapGraphReceiver::stringValue):
+ (TestWebKitAPI::HeapGraphReceiver::intValue):
+ (TestWebKitAPI::HeapGraphReceiver::nodeToString):
+ (TestWebKitAPI::HeapGraphReceiver::edgeToString):
+ (TestWebKitAPI::HeapGraphReceiver::printNode):
+ (Helper):
+ (TestWebKitAPI::Helper::Helper):
+ (TestWebKitAPI::Helper::addNode):
+ (TestWebKitAPI::Helper::addEdge):
+ (TestWebKitAPI::Helper::done):
+ (Object):
+ (TestWebKitAPI::Helper::Object::Object):
+ (TestWebKitAPI::TEST):
+ (Owner):
+ (TestWebKitAPI::Owner::Owner):
+ (TestWebKitAPI::Owner::reportMemoryUsage):
+
2013-02-18 Ryosuke Niwa <[email protected]>
WKR build fix. Always use ascii since irclib/ircbot doesn't support unicode.
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp (143174 => 143175)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp 2013-02-18 09:30:22 UTC (rev 143174)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp 2013-02-18 09:54:33 UTC (rev 143175)
@@ -77,6 +77,11 @@
'<@(TestWebKitAPI_files)',
],
'conditions': [
+ ['component!="shared_library"', {
+ 'sources': [
+ '../Tests/WebCore/HeapGraphSerializerTest.cpp'
+ ],
+ }],
['inside_chromium_build==1 and component=="shared_library"', {
'sources': [
# To satisfy linking of WTF::currentTime() etc. in shared library configuration,
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp (0 => 143175)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp 2013-02-18 09:54:33 UTC (rev 143175)
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include "config.h"
+#include "WTFStringUtilities.h"
+#include <gtest/gtest.h>
+
+#include "HeapGraphSerializer.h"
+#include "MemoryInstrumentationImpl.h"
+#include <wtf/MemoryInstrumentation.h>
+#include <wtf/MemoryInstrumentationHashSet.h>
+#include <wtf/MemoryInstrumentationString.h>
+#include <wtf/MemoryObjectInfo.h>
+
+namespace TestWebKitAPI {
+
+using namespace WebCore;
+
+static WTF::MemoryObjectType g_defaultObjectType = "DefaultObjectType";
+
+class HeapGraphReceiver : public HeapGraphSerializer::Client {
+public:
+ HeapGraphReceiver() : m_serializer(this) { }
+
+ virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnapshotChunk> heapSnapshotChunk) OVERRIDE
+ {
+ ASSERT(!m_heapSnapshotChunk);
+ m_heapSnapshotChunk = heapSnapshotChunk;
+ m_strings = chunkPart("strings");
+ m_edges = chunkPart("edges");
+ m_nodes = chunkPart("nodes");
+
+ // Reset platform depended size field values.
+ for (InspectorArray::iterator i = m_nodes->begin(); i != m_nodes->end(); i += s_nodeFieldCount)
+ *(i + s_sizeOffset) = InspectorBasicValue::create(0);
+
+ m_id2index.clear();
+
+ for (unsigned index = 0; index < m_nodes->length(); index += s_nodeFieldCount)
+ m_id2index.add(intValue(m_nodes.get(), index + s_idOffset), index);
+ }
+
+ void printGraph()
+ {
+ EXPECT_TRUE(m_heapSnapshotChunk);
+ int processedEdgesCount = 0;
+ for (unsigned index = 0; index < m_nodes->length(); index += s_nodeFieldCount)
+ processedEdgesCount += printNode(index, processedEdgesCount);
+ }
+
+ String dumpNodes() { return dumpPart("nodes"); }
+ String dumpEdges() { return dumpPart("edges"); }
+ String dumpBaseToRealNodeId() { return dumpPart("baseToRealNodeId"); }
+ String dumpStrings() { return dumpPart("strings"); }
+
+ HeapGraphSerializer* serializer() { return &m_serializer; }
+
+private:
+ PassRefPtr<InspectorArray> chunkPart(String partName)
+ {
+ EXPECT_TRUE(m_heapSnapshotChunk);
+ RefPtr<InspectorObject> chunk = *reinterpret_cast<RefPtr<InspectorObject>*>(&m_heapSnapshotChunk);
+ RefPtr<InspectorValue> partValue = chunk->get(partName);
+ RefPtr<InspectorArray> partArray;
+ EXPECT_TRUE(partValue->asArray(&partArray));
+ return partArray.release();
+ }
+
+ String dumpPart(String partName)
+ {
+ return chunkPart(partName)->toJSONString().replace("\"", "'");
+ }
+
+ String stringValue(InspectorArray* array, int index)
+ {
+ RefPtr<InspectorValue> inspectorValue = array->get(index);
+ String value;
+ EXPECT_TRUE(inspectorValue->asString(&value));
+ return value;
+ }
+
+ int intValue(InspectorArray* array, int index)
+ {
+ RefPtr<InspectorValue> inspectorValue = array->get(index);
+ int value;
+ EXPECT_TRUE(inspectorValue->asNumber(&value));
+ return value;
+ }
+
+ String nodeToString(unsigned nodeIndex)
+ {
+ StringBuilder builder;
+ builder.append("node: ");
+ builder.appendNumber(intValue(m_nodes.get(), nodeIndex + s_idOffset));
+ builder.append(" with className:'");
+ builder.append(stringValue(m_strings.get(), intValue(m_nodes.get(), nodeIndex + s_classNameOffset)));
+ builder.append("' and name: '");
+ builder.append(stringValue(m_strings.get(), intValue(m_nodes.get(), nodeIndex + s_nameOffset)));
+ builder.append("'");
+ return builder.toString();
+ }
+
+ String edgeToString(unsigned edgeOrdinal)
+ {
+ unsigned edgeIndex = edgeOrdinal * s_edgeFieldCount;
+ StringBuilder builder;
+ builder.append("'");
+ builder.append(stringValue(m_strings.get(), intValue(m_edges.get(), edgeIndex + s_edgeTypeOffset)));
+ builder.append("' edge '");
+ builder.append(stringValue(m_strings.get(), intValue(m_edges.get(), edgeIndex + s_edgeNameOffset)));
+ builder.append("' points to ");
+ int nodeId = intValue(m_edges.get(), edgeIndex + s_toNodeIdOffset);
+ builder.append(nodeToString(m_id2index.get(nodeId)));
+ return builder.toString();
+ }
+
+ int printNode(unsigned nodeIndex, unsigned processedEdgesCount)
+ {
+ String nodeString = nodeToString(nodeIndex);
+ unsigned edgeCount = intValue(m_nodes.get(), nodeIndex + s_edgeCountOffset);
+
+ printf("%s\n", nodeString.utf8().data());
+ for (unsigned i = 0; i < edgeCount; ++i) {
+ String edgeText = edgeToString(i + processedEdgesCount);
+ printf("\thas %s\n", edgeText.utf8().data());
+ }
+ return edgeCount;
+ }
+
+ HeapGraphSerializer m_serializer;
+ RefPtr<TypeBuilder::Memory::HeapSnapshotChunk> m_heapSnapshotChunk;
+
+ RefPtr<InspectorArray> m_strings;
+ RefPtr<InspectorArray> m_nodes;
+ RefPtr<InspectorArray> m_edges;
+ HashMap<int, int> m_id2index;
+
+ static const int s_nodeFieldCount = 5;
+ static const int s_classNameOffset = 0;
+ static const int s_nameOffset = 1;
+ static const int s_idOffset = 2;
+ static const int s_sizeOffset = 3;
+ static const int s_edgeCountOffset = 4;
+
+ static const int s_edgeFieldCount = 3;
+ static const int s_edgeTypeOffset = 0;
+ static const int s_edgeNameOffset = 1;
+ static const int s_toNodeIdOffset = 2;
+};
+
+class Helper {
+public:
+ Helper(HeapGraphSerializer* serializer) : m_serializer(serializer), m_currentPointer(0) { }
+ void* addNode(const char* className, const char* name, bool isRoot)
+ {
+ WTF::MemoryObjectInfo info(0, g_defaultObjectType, ++m_currentPointer);
+ info.setClassName(className);
+ info.setName(name);
+ if (isRoot)
+ info.markAsRoot();
+ m_serializer->reportNode(info);
+ return m_currentPointer;
+ }
+
+ void addEdge(void* to, const char* edgeName, WTF::MemberType memberType)
+ {
+ m_serializer->reportEdge(to, edgeName, memberType);
+ }
+
+ void done()
+ {
+ m_serializer->finish();
+ }
+
+private:
+ HeapGraphSerializer* m_serializer;
+
+ class Object {
+ public:
+ Object() { m_data[0] = 0; }
+ char m_data[sizeof(void*)];
+ };
+ Object* m_currentPointer;
+};
+
+TEST(HeapGraphSerializerTest, snapshotWithoutUserObjects)
+{
+ HeapGraphReceiver receiver;
+ Helper helper(receiver.serializer());
+ helper.done();
+ receiver.printGraph();
+ EXPECT_EQ(String("['','weak','ownRef','countRef','unknown','Root']"), receiver.dumpStrings());
+ EXPECT_EQ(String("[5,0,1,0,0]"), receiver.dumpNodes()); // Only Root object.
+ EXPECT_EQ(String("[]"), receiver.dumpEdges()); // No edges.
+ EXPECT_EQ(String("[]"), receiver.dumpBaseToRealNodeId()); // No id maps.
+}
+
+TEST(HeapGraphSerializerTest, oneRootUserObject)
+{
+ HeapGraphReceiver receiver;
+ Helper helper(receiver.serializer());
+ helper.addNode("ClassName", "objectName", true);
+ helper.done();
+ receiver.printGraph();
+ EXPECT_EQ(String("['','weak','ownRef','countRef','unknown','ClassName','objectName','Root']"), receiver.dumpStrings());
+ EXPECT_EQ(String("[5,6,1,0,0,7,0,2,0,1]"), receiver.dumpNodes());
+ EXPECT_EQ(String("[1,0,1]"), receiver.dumpEdges());
+ EXPECT_EQ(String("[]"), receiver.dumpBaseToRealNodeId());
+}
+
+TEST(HeapGraphSerializerTest, twoUserObjectsWithEdge)
+{
+ HeapGraphReceiver receiver;
+ Helper helper(receiver.serializer());
+ void* childObject = helper.addNode("Child", "child", false);
+ helper.addEdge(childObject, "pointerToChild", WTF::OwnPtrMember);
+ helper.addNode("Parent", "parent", true);
+ helper.done();
+ receiver.printGraph();
+ EXPECT_EQ(String("['','weak','ownRef','countRef','unknown','Child','child','pointerToChild','Parent','parent','Root']"), receiver.dumpStrings());
+ EXPECT_EQ(String("[5,6,1,0,0,8,9,2,0,1,10,0,3,0,1]"), receiver.dumpNodes());
+ EXPECT_EQ(String("[2,7,1,1,0,2]"), receiver.dumpEdges());
+ EXPECT_EQ(String("[]"), receiver.dumpBaseToRealNodeId());
+}
+
+class Owner {
+public:
+ Owner()
+ {
+ m_strings.add("first element");
+ m_strings.add("second element");
+ }
+ void reportMemoryUsage(WTF::MemoryObjectInfo* memoryObjectInfo) const
+ {
+ WTF::MemoryClassInfo info(memoryObjectInfo, this, g_defaultObjectType);
+ info.addMember(m_strings, "strings");
+ }
+private:
+ HashSet<String> m_strings;
+};
+
+TEST(HeapGraphSerializerTest, hashSetWithTwoStrings)
+{
+ HeapGraphReceiver receiver;
+ MemoryInstrumentationClientImpl memoryInstrumentationClient(receiver.serializer());
+ MemoryInstrumentationImpl memoryInstrumentation(&memoryInstrumentationClient);
+
+ Owner owner;
+ memoryInstrumentation.addRootObject(&owner);
+ receiver.serializer()->finish();
+ receiver.printGraph();
+ EXPECT_EQ(String("[5,0,1,0,0,8,0,4,0,3,9,0,3,0,0,9,0,2,0,0,10,0,5,0,1]"), receiver.dumpNodes());
+ EXPECT_EQ(String("[2,6,1,1,7,2,1,7,3,1,0,4]"), receiver.dumpEdges());
+ EXPECT_EQ(String("[]"), receiver.dumpBaseToRealNodeId());
+}
+
+} // namespace
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
