OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 | 32 |
33 | 33 |
34 #include "HeapGraphSerializer.h" | 34 #include "HeapGraphSerializer.h" |
35 | 35 |
36 #include "WebCoreMemoryInstrumentation.h" | |
37 #include <wtf/MemoryInstrumentationHashMap.h> | |
38 #include <wtf/MemoryInstrumentationVector.h> | |
39 #include <wtf/MemoryObjectInfo.h> | |
40 #include <wtf/text/CString.h> | 36 #include <wtf/text/CString.h> |
41 #include <wtf/text/WTFString.h> | 37 #include <wtf/text/WTFString.h> |
42 | 38 |
43 namespace WebCore { | 39 namespace WebCore { |
44 | 40 |
45 HeapGraphSerializer::HeapGraphSerializer(Client* client) | 41 HeapGraphSerializer::HeapGraphSerializer(Client* client) |
46 : m_client(client) | 42 : m_client(client) |
47 , m_strings(Strings::create()) | 43 , m_strings(Strings::create()) |
48 , m_edges(Edges::create()) | 44 , m_edges(Edges::create()) |
49 , m_nodeEdgesCount(0) | 45 , m_nodeEdgesCount(0) |
50 , m_nodes(Nodes::create()) | 46 , m_nodes(Nodes::create()) |
51 , m_baseToRealNodeIdMap(BaseToRealNodeIdMap::create()) | 47 , m_baseToRealNodeIdMap(BaseToRealNodeIdMap::create()) |
52 , m_typeStrings(InspectorObject::create()) | 48 , m_typeStrings(InspectorObject::create()) |
53 , m_leafCount(0) | 49 , m_leafCount(0) |
54 { | 50 { |
55 ASSERT(m_client); | 51 ASSERT(m_client); |
56 m_strings->addItem(String()); // An empty string with 0 index. | 52 m_strings->addItem(String()); // An empty string with 0 index. |
57 | 53 |
58 memset(m_edgeTypes, 0, sizeof(m_edgeTypes)); | |
59 | |
60 m_edgeTypes[WTF::PointerMember] = registerTypeString("weak"); | |
61 m_edgeTypes[WTF::RetainingPointer] = registerTypeString("property"); | |
62 | |
63 // FIXME: It is used as a magic constant for 'object' node type. | 54 // FIXME: It is used as a magic constant for 'object' node type. |
64 registerTypeString("object"); | 55 registerTypeString("object"); |
65 | 56 |
66 m_unknownClassNameId = registerString("unknown"); | 57 m_unknownClassNameId = registerString("unknown"); |
67 } | 58 } |
68 | 59 |
69 HeapGraphSerializer::~HeapGraphSerializer() | 60 HeapGraphSerializer::~HeapGraphSerializer() |
70 { | 61 { |
71 } | 62 } |
72 | 63 |
(...skipping 22 matching lines...) Expand all Loading... |
95 .setBaseToRealNodeId(m_baseToRealNodeIdMap.release()); | 86 .setBaseToRealNodeId(m_baseToRealNodeIdMap.release()); |
96 | 87 |
97 m_client->addNativeSnapshotChunk(chunk.release()); | 88 m_client->addNativeSnapshotChunk(chunk.release()); |
98 | 89 |
99 m_strings = Strings::create(); | 90 m_strings = Strings::create(); |
100 m_edges = Edges::create(); | 91 m_edges = Edges::create(); |
101 m_nodes = Nodes::create(); | 92 m_nodes = Nodes::create(); |
102 m_baseToRealNodeIdMap = BaseToRealNodeIdMap::create(); | 93 m_baseToRealNodeIdMap = BaseToRealNodeIdMap::create(); |
103 } | 94 } |
104 | 95 |
105 void HeapGraphSerializer::reportNode(const WTF::MemoryObjectInfo& info) | |
106 { | |
107 ASSERT(info.reportedPointer()); | |
108 reportNodeImpl(info, m_nodeEdgesCount); | |
109 m_nodeEdgesCount = 0; | |
110 if (info.isRoot()) | |
111 m_roots.append(info.reportedPointer()); | |
112 pushUpdateIfNeeded(); | |
113 } | |
114 | |
115 int HeapGraphSerializer::reportNodeImpl(const WTF::MemoryObjectInfo& info, int e
dgesCount) | |
116 { | |
117 int nodeId = toNodeId(info.reportedPointer()); | |
118 int classNameId = info.classNameId(); | |
119 m_nodes->addItem(classNameId ? classNameId : m_unknownClassNameId); | |
120 m_nodes->addItem(info.nameId()); | |
121 m_nodes->addItem(nodeId); | |
122 m_nodes->addItem(info.objectSize()); | |
123 m_nodes->addItem(edgesCount); | |
124 | |
125 return nodeId; | |
126 } | |
127 | |
128 void HeapGraphSerializer::reportEdge(const void* to, const char* name, WTF::Memb
erType memberType) | |
129 { | |
130 ASSERT(to); | |
131 reportEdgeImpl(toNodeId(to), name, m_edgeTypes[memberType]); | |
132 pushUpdateIfNeeded(); | |
133 } | |
134 | |
135 void HeapGraphSerializer::reportEdgeImpl(const int toNodeId, const char* name, i
nt memberType) | 96 void HeapGraphSerializer::reportEdgeImpl(const int toNodeId, const char* name, i
nt memberType) |
136 { | 97 { |
137 ASSERT(memberType >= 0); | 98 ASSERT(memberType >= 0); |
138 ASSERT(memberType < WTF::LastMemberTypeEntry); | |
139 | 99 |
140 m_edges->addItem(memberType); | 100 m_edges->addItem(memberType); |
141 m_edges->addItem(registerString(name)); | 101 m_edges->addItem(registerString(name)); |
142 m_edges->addItem(toNodeId); | 102 m_edges->addItem(toNodeId); |
143 | 103 |
144 ++m_nodeEdgesCount; | 104 ++m_nodeEdgesCount; |
145 } | 105 } |
146 | 106 |
147 void HeapGraphSerializer::reportLeaf(const WTF::MemoryObjectInfo& info, const ch
ar* edgeName) | |
148 { | |
149 int nodeId = reportNodeImpl(info, 0); | |
150 reportEdgeImpl(nodeId, edgeName, m_edgeTypes[WTF::RetainingPointer]); | |
151 pushUpdateIfNeeded(); | |
152 } | |
153 | |
154 void HeapGraphSerializer::reportBaseAddress(const void* base, const void* real) | 107 void HeapGraphSerializer::reportBaseAddress(const void* base, const void* real) |
155 { | 108 { |
156 m_baseToRealNodeIdMap->addItem(toNodeId(base)); | 109 m_baseToRealNodeIdMap->addItem(toNodeId(base)); |
157 m_baseToRealNodeIdMap->addItem(toNodeId(real)); | 110 m_baseToRealNodeIdMap->addItem(toNodeId(real)); |
158 } | 111 } |
159 | 112 |
160 PassRefPtr<InspectorObject> HeapGraphSerializer::finish() | 113 PassRefPtr<InspectorObject> HeapGraphSerializer::finish() |
161 { | 114 { |
162 addRootNode(); | 115 addRootNode(); |
163 pushUpdate(); | 116 pushUpdate(); |
(...skipping 26 matching lines...) Expand all Loading... |
190 "}"; | 143 "}"; |
191 | 144 |
192 RefPtr<InspectorValue> metaValue = InspectorValue::parseJSON(metaString); | 145 RefPtr<InspectorValue> metaValue = InspectorValue::parseJSON(metaString); |
193 RefPtr<InspectorObject> meta; | 146 RefPtr<InspectorObject> meta; |
194 metaValue->asObject(&meta); | 147 metaValue->asObject(&meta); |
195 ASSERT(meta); | 148 ASSERT(meta); |
196 meta->setObject("type_strings", m_typeStrings); | 149 meta->setObject("type_strings", m_typeStrings); |
197 return meta.release(); | 150 return meta.release(); |
198 } | 151 } |
199 | 152 |
200 void HeapGraphSerializer::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
const | |
201 { | |
202 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Inspector); | |
203 info.ignoreMember(m_stringToIndex); | |
204 info.ignoreMember(m_strings); | |
205 info.ignoreMember(m_edges); | |
206 info.ignoreMember(m_nodes); | |
207 info.ignoreMember(m_baseToRealNodeIdMap); | |
208 info.ignoreMember(m_roots); | |
209 } | |
210 | |
211 int HeapGraphSerializer::registerString(const char* string) | 153 int HeapGraphSerializer::registerString(const char* string) |
212 { | 154 { |
213 if (!string) | 155 if (!string) |
214 return 0; | 156 return 0; |
215 int length = strlen(string); | 157 int length = strlen(string); |
216 if (length > 256) | 158 if (length > 256) |
217 length = 256; | 159 length = 256; |
218 StringMap::AddResult result = m_stringToIndex.add(String(string, length), m_
stringToIndex.size() + 1); | 160 StringMap::AddResult result = m_stringToIndex.add(String(string, length), m_
stringToIndex.size() + 1); |
219 if (result.isNewEntry) | 161 if (result.isNewEntry) |
220 m_strings->addItem(string); | 162 m_strings->addItem(string); |
(...skipping 11 matching lines...) Expand all Loading... |
232 { | 174 { |
233 if (!to) | 175 if (!to) |
234 return s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount++; | 176 return s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount++; |
235 | 177 |
236 Address2NodeId::AddResult result = m_address2NodeIdMap.add(to, s_firstNodeId
+ m_leafCount + m_address2NodeIdMap.size()); | 178 Address2NodeId::AddResult result = m_address2NodeIdMap.add(to, s_firstNodeId
+ m_leafCount + m_address2NodeIdMap.size()); |
237 return result.iterator->value; | 179 return result.iterator->value; |
238 } | 180 } |
239 | 181 |
240 void HeapGraphSerializer::addRootNode() | 182 void HeapGraphSerializer::addRootNode() |
241 { | 183 { |
242 for (size_t i = 0; i < m_roots.size(); i++) | |
243 reportEdgeImpl(toNodeId(m_roots[i]), 0, m_edgeTypes[WTF::PointerMember])
; | |
244 | |
245 m_nodes->addItem(registerString("Root")); | 184 m_nodes->addItem(registerString("Root")); |
246 m_nodes->addItem(0); | 185 m_nodes->addItem(0); |
247 m_nodes->addItem(s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount); | 186 m_nodes->addItem(s_firstNodeId + m_address2NodeIdMap.size() + m_leafCount); |
248 m_nodes->addItem(0); | 187 m_nodes->addItem(0); |
249 m_nodes->addItem(m_roots.size()); | 188 m_nodes->addItem(m_roots.size()); |
250 } | 189 } |
251 | 190 |
252 } // namespace WebCore | 191 } // namespace WebCore |
253 | 192 |
OLD | NEW |