Source/WebCore/ChangeLog

 1o2013-02-12 Ilya Tikhonovsky <loislo@chromium.org>
 2
 3 Web Inspector: Native Memory Instrumentation: reportLeaf method doesn't report the leaf node properly.
 4 https://bugs.webkit.org/show_bug.cgi?id=109554
 5
 6 In some cases leafs have no pointer so with the old schema we can't generate nodeId for them because we
 7 can't insert 0 into hashmap. It happens when we call addPrivateBuffer method.
 8
 9 Drive by fix: I introduced a client interface for the HeapGraphSerializer.
 10 It helps me to do the tests for the serializer.
 11
 12 Reviewed by NOBODY (OOPS!).
 13
 14 It is covered by newly added tests in TestWebKitAPI.
 15
 16 * inspector/HeapGraphSerializer.cpp:
 17 (WebCore::HeapGraphSerializer::HeapGraphSerializer):
 18 (WebCore::HeapGraphSerializer::pushUpdate):
 19 (WebCore::HeapGraphSerializer::reportNode):
 20 (WebCore::HeapGraphSerializer::toNodeId):
 21 (WebCore::HeapGraphSerializer::addRootNode):
 22 * inspector/HeapGraphSerializer.h:
 23 (HeapGraphSerializerClient):
 24 (WebCore::HeapGraphSerializerClient::~HeapGraphSerializerClient):
 25 (HeapGraphSerializer):
 26 * inspector/InspectorMemoryAgent.cpp:
 27 (WebCore::InspectorMemoryAgent::getProcessMemoryDistributionImpl):
 28
1292013-02-11 John J. Barton <johnjbarton@chromium.org>
230
331 Web Inspector: Don't throw exceptions in WebInspector.Color

Source/WebCore/inspector/HeapGraphSerializer.cpp

4343
4444namespace WebCore {
4545
46 HeapGraphSerializer::HeapGraphSerializer(InspectorFrontend::Memory* frontend)
47  : m_frontend(frontend)
 46HeapGraphSerializer::HeapGraphSerializer(HeapGraphSerializerClient* client)
 47 : m_client(client)
4848 , m_strings(Strings::create())
4949 , m_edges(Edges::create())
5050 , m_nodeEdgesCount(0)
5151 , m_nodes(Nodes::create())
5252 , m_baseToRealNodeIdMap(BaseToRealNodeIdMap::create())
 53 , m_leafCount(0)
5354{
54  ASSERT(m_frontend);
 55 ASSERT(m_client);
5556 m_strings->addItem(String()); // An empty string with 0 index.
5657
5758 memset(m_edgeTypes, 0, sizeof(m_edgeTypes));

@@void HeapGraphSerializer::pushUpdate()
9192 .setEdges(m_edges.release())
9293 .setBaseToRealNodeId(m_baseToRealNodeIdMap.release());
9394
94  m_frontend->addNativeSnapshotChunk(chunk);
 95 m_client->addNativeSnapshotChunk(chunk.release());
9596
9697 m_strings = Strings::create();
9798 m_edges = Edges::create();

@@void HeapGraphSerializer::pushUpdate()
101102
102103void HeapGraphSerializer::reportNode(const WTF::MemoryObjectInfo& info)
103104{
 105 ASSERT(info.reportedPointer());
104106 reportNodeImpl(info, m_nodeEdgesCount);
105107 m_nodeEdgesCount = 0;
106108 if (info.isRoot())

@@int HeapGraphSerializer::addString(const String& string)
182184
183185int HeapGraphSerializer::toNodeId(const void* to)
184186{
185  ASSERT(to);
186  Address2NodeId::AddResult result = m_address2NodeIdMap.add(to, m_address2NodeIdMap.size());
 187 if (!to)
 188 return s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount++;
 189
 190 Address2NodeId::AddResult result = m_address2NodeIdMap.add(to, s_firstNodeId + m_leafCount + m_address2NodeIdMap.size());
187191 return result.iterator->value;
188192}
189193

@@void HeapGraphSerializer::addRootNode()
194198
195199 m_nodes->addItem(addString("Root"));
196200 m_nodes->addItem(0);
197  m_nodes->addItem(m_address2NodeIdMap.size());
 201 m_nodes->addItem(s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount);
198202 m_nodes->addItem(0);
199203 m_nodes->addItem(m_roots.size());
200204}

Source/WebCore/inspector/HeapGraphSerializer.h

4343
4444namespace WebCore {
4545
46 class HeapGraphEdge;
47 class HeapGraphNode;
48 class InspectorObject;
 46class HeapGraphSerializerClient {
 47public:
 48 virtual ~HeapGraphSerializerClient() { }
 49 virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnapshotChunk>) = 0;
 50};
4951
5052class HeapGraphSerializer {
5153 WTF_MAKE_NONCOPYABLE(HeapGraphSerializer);
5254public:
53  explicit HeapGraphSerializer(InspectorFrontend::Memory*);
 55 explicit HeapGraphSerializer(HeapGraphSerializerClient*);
5456 ~HeapGraphSerializer();
5557 void reportNode(const WTF::MemoryObjectInfo&);
5658 void reportEdge(const void*, const char*, WTF::MemberType);

@@private:
7375 void reportEdgeImpl(const int toNodeId, const char* name, int memberType);
7476 int reportNodeImpl(const WTF::MemoryObjectInfo&, int edgesCount);
7577
76  InspectorFrontend::Memory* m_frontend;
 78 HeapGraphSerializerClient* m_client;
7779
7880 typedef HashMap<String, int> StringMap;
7981 StringMap m_stringToIndex;

@@private:
100102
101103 size_t m_edgeTypes[WTF::LastMemberTypeEntry];
102104 int m_unknownClassNameId;
 105 int m_leafCount;
 106
 107 static const int s_firstNodeId = 1;
103108};
104109
105110} // namespace WebCore

Source/WebCore/inspector/InspectorMemoryAgent.cpp

@@void InspectorMemoryAgent::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
333333void InspectorMemoryAgent::getProcessMemoryDistributionImpl(bool reportGraph, TypeNameToSizeMap* memoryInfo)
334334{
335335 OwnPtr<HeapGraphSerializer> graphSerializer;
 336
 337 class FrontendWrapper : public HeapGraphSerializerClient {
 338 public:
 339 explicit FrontendWrapper(InspectorFrontend::Memory* frontend) : m_frontend(frontend) { }
 340 virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnapshotChunk> heapSnapshotChunk) OVERRIDE
 341 {
 342 m_frontend->addNativeSnapshotChunk(heapSnapshotChunk);
 343 }
 344 private:
 345 InspectorFrontend::Memory* m_frontend;
 346 } frontendWrapper(m_frontend);
 347
336348 if (reportGraph)
337  graphSerializer = adoptPtr(new HeapGraphSerializer(m_frontend));
 349 graphSerializer = adoptPtr(new HeapGraphSerializer(&frontendWrapper));
 350
338351 MemoryInstrumentationClientImpl memoryInstrumentationClient(graphSerializer.get());
339352 m_inspectorClient->getAllocatedObjects(memoryInstrumentationClient.allocatedObjects());
340353 MemoryInstrumentationImpl memoryInstrumentation(&memoryInstrumentationClient);

Tools/ChangeLog

 12013-02-12 Ilya Tikhonovsky <loislo@chromium.org>
 2
 3 Web Inspector: Native Memory Instrumentation: reportLeaf method doesn't report the leaf node properly.
 4 https://bugs.webkit.org/show_bug.cgi?id=109554
 5
 6 In some cases leafs have no pointer. As example when we report a leaf via addPrivateBuffer.
 7 This patch has new set of tests for HeapGraphSerializer.
 8
 9 Reviewed by NOBODY (OOPS!).
 10
 11 * TestWebKitAPI/TestWebKitAPI.gypi:
 12 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
 13 * TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp: Added.
 14 * TestWebKitAPI/win/TestWebKitAPI.vcproj:
 15
1162013-02-11 Jochen Eisinger <jochen@chromium.org>
217
318 [chromium] clear the webcache from within the TestRunner library

Tools/TestWebKitAPI/TestWebKitAPI.gypi

3131{
3232 'variables': {
3333 'TestWebKitAPI_files': [
 34 'Tests/WebCore/HeapGraphSerializerTest.cpp',
3435 'Tests/WebCore/LayoutUnit.cpp',
3536 'Tests/WTF/AtomicString.cpp',
3637 'Tests/WTF/CheckedArithmeticOperations.cpp',

Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

1414 0FC6C4CC141027E0005B7F0C /* RedBlackTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */; };
1515 0FC6C4CF141034AD005B7F0C /* MetaAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */; };
1616 14464013167A8305000BD218 /* LayoutUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14464012167A8305000BD218 /* LayoutUnit.cpp */; };
 17 788CB4AE348F4040827FCCD0 /* HeapGraphGeneratorTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 788CB4AE348F4040827FCCD0 /* HeapGraphGeneratorTest.cpp */; };
1718 14F3B11315E45EAB00210069 /* SaturatedArithmeticOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F3B11215E45EAB00210069 /* SaturatedArithmeticOperations.cpp */; };
1819 1A02C84F125D4A8400E3F4BD /* Find.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A02C84E125D4A8400E3F4BD /* Find.cpp */; };
1920 1A02C870125D4CFD00E3F4BD /* find.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1A02C84B125D4A5E00E3F4BD /* find.html */; };

272273 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RedBlackTree.cpp; path = WTF/RedBlackTree.cpp; sourceTree = "<group>"; };
273274 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MetaAllocator.cpp; path = WTF/MetaAllocator.cpp; sourceTree = "<group>"; };
274275 14464012167A8305000BD218 /* LayoutUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutUnit.cpp; sourceTree = "<group>"; };
 276 788CB4AE348F4040827FCCD0 /* HeapGraphGeneratorTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapGraphGeneratorTest.cpp; sourceTree = "<group>"; };
275277 14F3B11215E45EAB00210069 /* SaturatedArithmeticOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SaturatedArithmeticOperations.cpp; path = WTF/SaturatedArithmeticOperations.cpp; sourceTree = "<group>"; };
276278 1A02C84B125D4A5E00E3F4BD /* find.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = find.html; sourceTree = "<group>"; };
277279 1A02C84E125D4A8400E3F4BD /* Find.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Find.cpp; sourceTree = "<group>"; };

564566 children = (
565567 440A1D3814A0103A008A66F2 /* KURL.cpp */,
566568 14464012167A8305000BD218 /* LayoutUnit.cpp */,
 569 788CB4AE348F4040827FCCD0 /* HeapGraphGeneratorTest.cpp */,
567570 );
568571 path = WebCore;
569572 sourceTree = "<group>";

10141017 4BB4160216815B2600824238 /* JSWrapperForNodeInWebFrame.mm in Sources */,
10151018 440A1D3914A0103A008A66F2 /* KURL.cpp in Sources */,
10161019 14464013167A8305000BD218 /* LayoutUnit.cpp in Sources */,
 1020 788CB4AE348F4040827FCCD0 /* HeapGraphGeneratorTest.cpp in Sources */,
10171021 26300B1816755CD90066886D /* ListHashSet.cpp in Sources */,
10181022 52CB47411448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp in Sources */,
10191023 33DC8911141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp in Sources */,

Tools/TestWebKitAPI/Tests/WebCore/HeapGraphSerializerTest.cpp

 1/*
 2 * Copyright (C) 2013 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions are
 6 * met:
 7 *
 8 * * Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * * Redistributions in binary form must reproduce the above
 11 * copyright notice, this list of conditions and the following disclaimer
 12 * in the documentation and/or other materials provided with the
 13 * distribution.
 14 * * Neither the name of Google Inc. nor the names of its
 15 * contributors may be used to endorse or promote products derived from
 16 * this software without specific prior written permission.
 17 *
 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29 */
 30
 31#include "config.h"
 32#include "WTFStringUtilities.h"
 33#include <gtest/gtest.h>
 34
 35#include "HeapGraphSerializer.h"
 36#include "MemoryInstrumentationImpl.h"
 37#include <wtf/MemoryInstrumentation.h>
 38#include <wtf/MemoryInstrumentationHashSet.h>
 39#include <wtf/MemoryInstrumentationString.h>
 40#include <wtf/MemoryObjectInfo.h>
 41
 42namespace {
 43
 44using namespace WebCore;
 45
 46static WTF::MemoryObjectType g_defaultObjectType = "DefaultObjectType";
 47
 48class HeapGraphReceiver : public HeapGraphSerializerClient {
 49public:
 50 HeapGraphReceiver() : m_serializer(this)
 51 {
 52 m_currentPointer = 0;
 53 }
 54
 55 virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnapshotChunk> heapSnapshotChunk) OVERRIDE
 56 {
 57 m_heapSnapshotChunk = heapSnapshotChunk;
 58 m_strings = chunkPart("strings");
 59 m_edges = chunkPart("edges");
 60 m_nodes = chunkPart("nodes");
 61
 62 // Reset platform depended size field values.
 63 for (InspectorArray::iterator i = m_nodes->begin(); i != m_nodes->end(); i += s_nodeFieldCount)
 64 *(i + s_sizeOffset) = InspectorBasicValue::create(0);
 65
 66 m_id2index.clear();
 67
 68 for (int index = 0; index < m_nodes->length(); index += s_nodeFieldCount)
 69 m_id2index.add(intValue(m_nodes.get(), index + s_idOffset), index);
 70 }
 71
 72 void printGraph()
 73 {
 74 EXPECT_TRUE(m_heapSnapshotChunk);
 75 int processedEdgesCount = 0;
 76 for (unsigned index = 0; index < m_nodes->length(); index += s_nodeFieldCount)
 77 processedEdgesCount += printNode(index, processedEdgesCount);
 78 }
 79
 80 String dumpLastChunkNodes() { return dumpLastChunkPart("nodes"); }
 81 String dumpLastChunkEdges() { return dumpLastChunkPart("edges"); }
 82 String dumpLastChunkBaseToRealNodeId() { return dumpLastChunkPart("baseToRealNodeId"); }
 83 String dumpLastChunkStrings() { return dumpLastChunkPart("strings"); }
 84
 85 void* addNode(const char* className, const char* name, bool isRoot)
 86 {
 87 WTF::MemoryObjectInfo info(0, g_defaultObjectType, ++m_currentPointer);
 88 info.setClassName(className);
 89 info.setName(name);
 90 if (isRoot)
 91 info.markAsRoot();
 92 m_serializer.reportNode(info);
 93 return m_currentPointer;
 94 }
 95
 96 void addEdge(void* to, const char* edgeName, WTF::MemberType memberType)
 97 {
 98 m_serializer.reportEdge(to, edgeName, memberType);
 99 }
 100
 101 void done()
 102 {
 103 m_serializer.finish();
 104 printGraph();
 105 }
 106
 107 HeapGraphSerializer* heapGraphSerializer() { return &m_serializer; }
 108
 109private:
 110 PassRefPtr<InspectorArray> chunkPart(String partName)
 111 {
 112 EXPECT_TRUE(m_heapSnapshotChunk);
 113 RefPtr<InspectorObject> chunk = *reinterpret_cast<RefPtr<InspectorObject>*>(&m_heapSnapshotChunk);
 114 RefPtr<InspectorValue> partValue = chunk->get(partName);
 115 RefPtr<InspectorArray> partArray;
 116 EXPECT_TRUE(partValue->asArray(&partArray));
 117 return partArray.release();
 118 }
 119
 120 String dumpLastChunkPart(String partName)
 121 {
 122 return chunkPart(partName)->toJSONString().replace("\"", "'");
 123 }
 124
 125 String stringValue(InspectorArray* array, int index)
 126 {
 127 RefPtr<InspectorValue> inspectorValue = array->get(index);
 128 String value;
 129 EXPECT_TRUE(inspectorValue->asString(&value));
 130 return value;
 131 }
 132
 133 int intValue(InspectorArray* array, int index)
 134 {
 135 RefPtr<InspectorValue> inspectorValue = array->get(index);
 136 int value;
 137 EXPECT_TRUE(inspectorValue->asNumber(&value));
 138 return value;
 139 }
 140
 141 String node(unsigned nodeIndex)
 142 {
 143 StringBuilder builder;
 144 builder.append("node: ");
 145 builder.appendNumber(intValue(m_nodes.get(), nodeIndex + s_idOffset));
 146 builder.append(" with className:'");
 147 builder.append(stringValue(m_strings.get(), intValue(m_nodes.get(), nodeIndex + s_classNameOffset)));
 148 builder.append("' and name: '");
 149 builder.append(stringValue(m_strings.get(), intValue(m_nodes.get(), nodeIndex + s_nameOffset)));
 150 builder.append("'");
 151 return builder.toString();
 152 }
 153
 154 String edge(unsigned edgeOrdinal)
 155 {
 156 unsigned edgeIndex = edgeOrdinal * s_edgeFieldCount;
 157 StringBuilder builder;
 158 builder.append("'");
 159 builder.append(stringValue(m_strings.get(), intValue(m_edges.get(), edgeIndex + s_edgeTypeOffset)));
 160 builder.append("' edge '");
 161 builder.append(stringValue(m_strings.get(), intValue(m_edges.get(), edgeIndex + s_edgeNameOffset)));
 162 builder.append("' points to ");
 163 int nodeId = intValue(m_edges.get(), edgeIndex + s_toNodeIdOffset);
 164 builder.append(node(m_id2index.get(nodeId)));
 165 return builder.toString();
 166 }
 167
 168 int printNode(unsigned nodeIndex, unsigned processedEdgesCount)
 169 {
 170 String nodeString = node(nodeIndex);
 171 int edgeCount = intValue(m_nodes.get(), nodeIndex + s_edgeCountOffset);
 172
 173 printf("%s\n", nodeString.utf8().data());
 174 for (unsigned i = 0; i < edgeCount; ++i) {
 175 String edgeText = edge(i + processedEdgesCount);
 176 printf("\thas %s\n", edgeText.utf8().data());
 177 }
 178 return edgeCount;
 179 }
 180
 181 HeapGraphSerializer m_serializer;
 182 RefPtr<TypeBuilder::Memory::HeapSnapshotChunk> m_heapSnapshotChunk;
 183
 184 RefPtr<InspectorArray> m_strings;
 185 RefPtr<InspectorArray> m_nodes;
 186 RefPtr<InspectorArray> m_edges;
 187 HashMap<int, int> m_id2index;
 188
 189 class Object {
 190 char m_data[sizeof(void*)];
 191 };
 192 Object* m_currentPointer;
 193
 194 static const int s_nodeFieldCount = 5;
 195 static const int s_classNameOffset = 0;
 196 static const int s_nameOffset = 1;
 197 static const int s_idOffset = 2;
 198 static const int s_sizeOffset = 3;
 199 static const int s_edgeCountOffset = 4;
 200
 201 static const int s_edgeFieldCount = 3;
 202 static const int s_edgeTypeOffset = 0;
 203 static const int s_edgeNameOffset = 1;
 204 static const int s_toNodeIdOffset = 2;
 205};
 206
 207TEST(HeapGraphSerializerTest, snapshotWithoutUserObjects)
 208{
 209 HeapGraphReceiver receiver;
 210 receiver.done();
 211 EXPECT_EQ(String("['','weak','ownRef','countRef','unknown','Root']"), receiver.dumpLastChunkStrings());
 212 EXPECT_EQ(String("[5,0,1,0,0]"), receiver.dumpLastChunkNodes()); // Only Root object.
 213 EXPECT_EQ(String("[]"), receiver.dumpLastChunkEdges()); // No edges.
 214 EXPECT_EQ(String("[]"), receiver.dumpLastChunkBaseToRealNodeId()); // No id maps.
 215}
 216
 217TEST(HeapGraphSerializerTest, oneRootUserObject)
 218{
 219 HeapGraphReceiver receiver;
 220 receiver.addNode("ClassName", "objectName", true);
 221 receiver.done();
 222 EXPECT_EQ(String("['','weak','ownRef','countRef','unknown','ClassName','objectName','Root']"), receiver.dumpLastChunkStrings());
 223 EXPECT_EQ(String("[5,6,1,0,0,7,0,2,0,1]"), receiver.dumpLastChunkNodes());
 224 EXPECT_EQ(String("[1,0,1]"), receiver.dumpLastChunkEdges());
 225 EXPECT_EQ(String("[]"), receiver.dumpLastChunkBaseToRealNodeId());
 226}
 227
 228TEST(HeapGraphSerializerTest, twoUserObjectsWithEdge)
 229{
 230 HeapGraphReceiver receiver;
 231 void* childObject = receiver.addNode("Child", "child", false);
 232 receiver.addEdge(childObject, "pointerToChild", WTF::OwnPtrMember);
 233 receiver.addNode("Parent", "parent", true);
 234 receiver.done();
 235 EXPECT_EQ(String("['','weak','ownRef','countRef','unknown','Child','child','pointerToChild','Parent','parent','Root']"), receiver.dumpLastChunkStrings());
 236 EXPECT_EQ(String("[5,6,1,0,0,8,9,2,0,1,10,0,3,0,1]"), receiver.dumpLastChunkNodes());
 237 EXPECT_EQ(String("[2,7,1,1,0,2]"), receiver.dumpLastChunkEdges());
 238 EXPECT_EQ(String("[]"), receiver.dumpLastChunkBaseToRealNodeId());
 239}
 240
 241class Owner {
 242public:
 243 Owner()
 244 {
 245 m_strings.add("first element");
 246 m_strings.add("second element");
 247 }
 248 void reportMemoryUsage(WTF::MemoryObjectInfo* memoryObjectInfo) const
 249 {
 250 WTF::MemoryClassInfo info(memoryObjectInfo, this, g_defaultObjectType);
 251 info.addMember(m_strings, "strings");
 252 }
 253private:
 254 HashSet<String> m_strings;
 255};
 256
 257TEST(HeapGraphSerializerTest, hashSetWithTwoItems)
 258{
 259 HeapGraphReceiver receiver;
 260 MemoryInstrumentationClientImpl memoryInstrumentationClient(receiver.heapGraphSerializer());
 261 MemoryInstrumentationImpl memoryInstrumentation(&memoryInstrumentationClient);
 262
 263 Owner owner;
 264 memoryInstrumentation.addRootObject(&owner);
 265 receiver.done();
 266 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.dumpLastChunkNodes());
 267 EXPECT_EQ(String("[2,6,1,1,7,2,1,7,3,1,0,4]"), receiver.dumpLastChunkEdges());
 268 EXPECT_EQ(String("[]"), receiver.dumpLastChunkBaseToRealNodeId());
 269}
 270
 271} // namespace

Tools/TestWebKitAPI/win/TestWebKitAPI.vcproj

416416 </File>
417417 </Filter>
418418 <File
 419 RelativePath="..\Tests\WebCore\HeapGraphGeneratorTest.cpp"
 420 >
 421 </File>
 422 <File
419423 RelativePath="..\Tests\WebCore\LayoutUnit.cpp"
420424 >
421425 </File>