Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Side by Side Diff: Source/core/inspector/InspectorMemoryAgent.cpp

Issue 13973026: remove memoryinstrumentation Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: remove the rest part of MemoryInstrumentation Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/inspector/InspectorMemoryAgent.h ('k') | Source/core/inspector/InspectorOverlay.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 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 18 matching lines...) Expand all
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "InspectorMemoryAgent.h" 32 #include "InspectorMemoryAgent.h"
33 33
34 #include "BindingVisitors.h" 34 #include "BindingVisitors.h"
35 #include "CharacterData.h" 35 #include "CharacterData.h"
36 #include "Document.h" 36 #include "Document.h"
37 #include "EventListenerMap.h" 37 #include "EventListenerMap.h"
38 #include "Frame.h" 38 #include "Frame.h"
39 #include "HeapGraphSerializer.h"
40 #include "InspectorClient.h" 39 #include "InspectorClient.h"
41 #include "InspectorDOMStorageAgent.h" 40 #include "InspectorDOMStorageAgent.h"
42 #include "InspectorFrontend.h" 41 #include "InspectorFrontend.h"
43 #include "InspectorState.h" 42 #include "InspectorState.h"
44 #include "InspectorValues.h" 43 #include "InspectorValues.h"
45 #include "InstrumentingAgents.h" 44 #include "InstrumentingAgents.h"
46 #include "MemoryCache.h" 45 #include "MemoryCache.h"
47 #include "MemoryInstrumentationImpl.h"
48 #include "MemoryUsageSupport.h" 46 #include "MemoryUsageSupport.h"
49 #include "Node.h" 47 #include "Node.h"
50 #include "NodeTraversal.h" 48 #include "NodeTraversal.h"
51 #include "Page.h" 49 #include "Page.h"
52 #include "ScriptGCEvent.h" 50 #include "ScriptGCEvent.h"
53 #include "ScriptProfiler.h" 51 #include "ScriptProfiler.h"
54 #include "StyledElement.h" 52 #include "StyledElement.h"
55 #include <wtf/ArrayBufferView.h> 53 #include <wtf/ArrayBufferView.h>
56 #include <wtf/HashSet.h> 54 #include <wtf/HashSet.h>
57 #include <wtf/MemoryInstrumentationArrayBufferView.h>
58 #include <wtf/NonCopyingSort.h> 55 #include <wtf/NonCopyingSort.h>
59 #include <wtf/OwnPtr.h> 56 #include <wtf/OwnPtr.h>
60 #include <wtf/PassOwnPtr.h> 57 #include <wtf/PassOwnPtr.h>
61 #include <wtf/Vector.h> 58 #include <wtf/Vector.h>
62 #include <wtf/text/StringBuilder.h> 59 #include <wtf/text/StringBuilder.h>
63 #include <wtf/text/StringImpl.h> 60 #include <wtf/text/StringImpl.h>
64 #include <wtf/text/WTFString.h> 61 #include <wtf/text/WTFString.h>
65 62
66 // Use a type alias instead of 'using' here which would cause a conflict on Mac. 63 // Use a type alias instead of 'using' here which would cause a conflict on Mac.
67 typedef WebCore::TypeBuilder::Memory::MemoryBlock InspectorMemoryBlock; 64 typedef WebCore::TypeBuilder::Memory::MemoryBlock InspectorMemoryBlock;
68 typedef WebCore::TypeBuilder::Array<InspectorMemoryBlock> InspectorMemoryBlocks; 65 typedef WebCore::TypeBuilder::Array<InspectorMemoryBlock> InspectorMemoryBlocks;
69 66
70 namespace WebCore { 67 namespace WebCore {
71 68
72 namespace {
73
74 class MemoryUsageStatsGenerator {
75 public:
76 MemoryUsageStatsGenerator() { }
77
78 void dump(const TypeNameToSizeMap& sizesMap, InspectorMemoryBlocks* children )
79 {
80 m_sizesMap = sizesMap;
81
82 // FIXME: We filter out Rendering type because the coverage is not good enough at the moment
83 // and report RenderArena size instead.
84 for (TypeNameToSizeMap::iterator i = m_sizesMap.begin(); i != m_sizesMap .end(); ++i) {
85 if (i->key == PlatformMemoryTypes::Rendering) {
86 m_sizesMap.remove(i);
87 break;
88 }
89 }
90 Vector<String> objectTypes;
91 objectTypes.appendRange(m_sizesMap.keys().begin(), m_sizesMap.keys().end ());
92
93 for (Vector<String>::const_iterator i = objectTypes.begin(); i != object Types.end(); ++i)
94 updateParentSizes(*i, m_sizesMap.get(*i));
95
96 objectTypes.clear();
97 objectTypes.appendRange(m_sizesMap.keys().begin(), m_sizesMap.keys().end ());
98 nonCopyingSort(objectTypes.begin(), objectTypes.end(), stringCompare);
99
100 size_t index = 0;
101 while (index < objectTypes.size())
102 index = buildObjectForIndex(index, objectTypes, children);
103
104 }
105
106 private:
107 static bool stringCompare(const String& a, const String& b) { return WTF::co dePointCompare(a, b) < 0; }
108
109 void updateParentSizes(String objectType, const size_t size)
110 {
111 for (size_t dotPosition = objectType.reverseFind('.'); dotPosition != no tFound; dotPosition = objectType.reverseFind('.', dotPosition)) {
112 objectType = objectType.substring(0, dotPosition);
113 TypeNameToSizeMap::AddResult result = m_sizesMap.add(objectType, siz e);
114 if (!result.isNewEntry)
115 result.iterator->value += size;
116 }
117 }
118
119 size_t buildObjectForIndex(size_t index, const Vector<String>& objectTypes, InspectorMemoryBlocks* array)
120 {
121 String typeName = objectTypes[index];
122 size_t dotPosition = typeName.reverseFind('.');
123 String blockName = (dotPosition == notFound) ? typeName : typeName.subst ring(dotPosition + 1);
124 RefPtr<InspectorMemoryBlock> block = InspectorMemoryBlock::create().setN ame(blockName);
125 block->setSize(m_sizesMap.get(typeName));
126 String prefix = typeName;
127 prefix.append('.');
128 array->addItem(block);
129 ++index;
130 RefPtr<InspectorMemoryBlocks> children;
131 while (index < objectTypes.size() && objectTypes[index].startsWith(prefi x)) {
132 if (!children)
133 children = InspectorMemoryBlocks::create();
134 index = buildObjectForIndex(index, objectTypes, children.get());
135 }
136 if (children)
137 block->setChildren(children.release());
138 return index;
139 }
140
141 TypeNameToSizeMap m_sizesMap;
142 };
143
144 class ExternalStringsRoot : public ExternalStringVisitor {
145 public:
146 ExternalStringsRoot() : m_memoryClassInfo(0) { }
147
148 void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
149 {
150 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Externa lStrings);
151 m_memoryClassInfo = &info;
152 ScriptProfiler::visitExternalStrings(const_cast<ExternalStringsRoot*>(th is));
153 m_memoryClassInfo = 0;
154 info.ignoreMember(m_memoryClassInfo);
155 }
156
157 private:
158 virtual void visitJSExternalString(StringImpl* string)
159 {
160 m_memoryClassInfo->addMember(string, "externalString", WTF::RetainingPoi nter);
161 }
162
163 mutable MemoryClassInfo* m_memoryClassInfo;
164 };
165
166 class ExternalArraysRoot : public ExternalArrayVisitor {
167 public:
168 ExternalArraysRoot() : m_memoryClassInfo(0) { }
169
170 void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
171 {
172 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Externa lArrays);
173 m_memoryClassInfo = &info;
174 ScriptProfiler::visitExternalArrays(const_cast<ExternalArraysRoot*>(this ));
175 m_memoryClassInfo = 0;
176 info.ignoreMember(m_memoryClassInfo);
177 }
178
179 private:
180 virtual void visitJSExternalArray(ArrayBufferView* arrayBufferView)
181 {
182 m_memoryClassInfo->addMember(arrayBufferView, "externalArray", WTF::Reta iningPointer);
183 }
184
185 mutable MemoryClassInfo* m_memoryClassInfo;
186 };
187
188 } // namespace
189
190 InspectorMemoryAgent::~InspectorMemoryAgent() 69 InspectorMemoryAgent::~InspectorMemoryAgent()
191 { 70 {
192 } 71 }
193 72
194 void InspectorMemoryAgent::getDOMCounters(ErrorString*, int* documents, int* nod es, int* jsEventListeners) 73 void InspectorMemoryAgent::getDOMCounters(ErrorString*, int* documents, int* nod es, int* jsEventListeners)
195 { 74 {
196 *documents = InspectorCounters::counterValue(InspectorCounters::DocumentCoun ter); 75 *documents = InspectorCounters::counterValue(InspectorCounters::DocumentCoun ter);
197 *nodes = InspectorCounters::counterValue(InspectorCounters::NodeCounter); 76 *nodes = InspectorCounters::counterValue(InspectorCounters::NodeCounter);
198 *jsEventListeners = ThreadLocalInspectorCounters::current().counterValue(Thr eadLocalInspectorCounters::JSEventListenerCounter); 77 *jsEventListeners = ThreadLocalInspectorCounters::current().counterValue(Thr eadLocalInspectorCounters::JSEventListenerCounter);
199 } 78 }
200 79
201 static void reportJSHeapInfo(WTF::MemoryInstrumentationClient& memoryInstrumenta tionClient)
202 {
203 HeapInfo info;
204 ScriptGCEvent::getHeapSize(info);
205
206 memoryInstrumentationClient.countObjectSize(0, WebCoreMemoryTypes::JSHeapUse d, info.usedJSHeapSize);
207 memoryInstrumentationClient.countObjectSize(0, WebCoreMemoryTypes::JSHeapUnu sed, info.totalJSHeapSize - info.usedJSHeapSize);
208 }
209
210 static void reportRenderTreeInfo(WTF::MemoryInstrumentationClient& memoryInstrum entationClient, Page* page)
211 {
212 ArenaSize arenaSize = page->renderTreeSize();
213
214 memoryInstrumentationClient.countObjectSize(0, WebCoreMemoryTypes::RenderTre eUsed, arenaSize.treeSize);
215 memoryInstrumentationClient.countObjectSize(0, WebCoreMemoryTypes::RenderTre eUnused, arenaSize.allocated - arenaSize.treeSize);
216 }
217
218 namespace {
219
220 class DOMTreesIterator : public WrappedNodeVisitor {
221 public:
222 DOMTreesIterator(MemoryInstrumentationImpl& memoryInstrumentation, Page* pag e)
223 : m_page(page)
224 , m_memoryInstrumentation(memoryInstrumentation)
225 {
226 }
227
228 virtual void visitNode(Node* node) OVERRIDE
229 {
230 if (node->document() && node->document()->frame() && m_page != node->doc ument()->frame()->page())
231 return;
232
233 while (Node* parentNode = node->parentNode())
234 node = parentNode;
235
236 m_memoryInstrumentation.addRootObject(node);
237 }
238
239 void visitFrame(Frame* frame)
240 {
241 m_memoryInstrumentation.addRootObject(frame);
242 }
243
244 void visitBindings()
245 {
246 ScriptProfiler::collectBindingMemoryInfo(&m_memoryInstrumentation);
247 }
248
249 void visitMemoryCache()
250 {
251 m_memoryInstrumentation.addRootObject(memoryCache());
252 }
253
254
255 private:
256 Page* m_page;
257 MemoryInstrumentationImpl& m_memoryInstrumentation;
258 };
259
260 }
261
262 static void collectDomTreeInfo(MemoryInstrumentationImpl& memoryInstrumentation, Page* page)
263 {
264 ExternalStringsRoot stringsRoot;
265 memoryInstrumentation.addRootObject(stringsRoot);
266
267 ExternalArraysRoot arraysRoot;
268 memoryInstrumentation.addRootObject(arraysRoot);
269
270 DOMTreesIterator domTreesIterator(memoryInstrumentation, page);
271
272 ScriptProfiler::visitNodeWrappers(&domTreesIterator);
273
274 // Make sure all documents reachable from the main frame are accounted.
275 for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->travers eNext()) {
276 if (Document* doc = frame->document()) {
277 domTreesIterator.visitNode(doc);
278 domTreesIterator.visitFrame(frame);
279 }
280 }
281
282 domTreesIterator.visitBindings();
283 domTreesIterator.visitMemoryCache();
284 }
285
286 static void addPlatformComponentsInfo(TypeNameToSizeMap* memoryInfo)
287 {
288 Vector<MemoryUsageSupport::ComponentInfo> components;
289 MemoryUsageSupport::memoryUsageByComponents(components);
290 for (Vector<MemoryUsageSupport::ComponentInfo>::iterator it = components.beg in(); it != components.end(); ++it)
291 memoryInfo->add(it->m_name, it->m_sizeInBytes);
292 }
293
294 static void addMemoryInstrumentationDebugData(MemoryInstrumentationClientImpl* c lient, TypeNameToSizeMap* memoryInfo)
295 {
296 if (client->checkInstrumentedObjects()) {
297 memoryInfo->add("InstrumentedObjectsCount", client->totalCountedObjects( ));
298 memoryInfo->add("InstrumentedButNotAllocatedObjectsCount", client->total ObjectsNotInAllocatedSet());
299 }
300 }
301
302 void InspectorMemoryAgent::getProcessMemoryDistributionMap(TypeNameToSizeMap* me moryInfo)
303 {
304 getProcessMemoryDistributionImpl(false, memoryInfo);
305 }
306
307 void InspectorMemoryAgent::getProcessMemoryDistribution(ErrorString*, const bool * reportGraph, RefPtr<InspectorMemoryBlock>& processMemory, RefPtr<InspectorObje ct>& graphMetaInformation)
308 {
309 TypeNameToSizeMap memoryInfo;
310 graphMetaInformation = getProcessMemoryDistributionImpl(reportGraph && *repo rtGraph, &memoryInfo);
311
312 MemoryUsageStatsGenerator statsGenerator;
313 RefPtr<InspectorMemoryBlocks> children = InspectorMemoryBlocks::create();
314 statsGenerator.dump(memoryInfo, children.get());
315
316 processMemory = InspectorMemoryBlock::create().setName(WebCoreMemoryTypes::P rocessPrivateMemory);
317 processMemory->setChildren(children);
318
319 size_t privateBytes = 0;
320 size_t sharedBytes = 0;
321 MemoryUsageSupport::processMemorySizesInBytes(&privateBytes, &sharedBytes);
322 processMemory->setSize(privateBytes);
323 }
324
325 void InspectorMemoryAgent::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
326 {
327 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Inspector);
328 InspectorBaseAgent<InspectorMemoryAgent>::reportMemoryUsage(memoryObjectInfo );
329 info.addWeakPointer(m_inspectorClient);
330 info.addMember(m_page, "page");
331 }
332
333 namespace {
334
335 class FrontendWrapper : public HeapGraphSerializer::Client {
336 public:
337 explicit FrontendWrapper(InspectorFrontend::Memory* frontend) : m_frontend(f rontend) { }
338 virtual void addNativeSnapshotChunk(PassRefPtr<TypeBuilder::Memory::HeapSnap shotChunk> heapSnapshotChunk) OVERRIDE
339 {
340 m_frontend->addNativeSnapshotChunk(heapSnapshotChunk);
341 }
342 private:
343 InspectorFrontend::Memory* m_frontend;
344 };
345
346 }
347
348 PassRefPtr<InspectorObject> InspectorMemoryAgent::getProcessMemoryDistributionIm pl(bool reportGraph, TypeNameToSizeMap* memoryInfo)
349 {
350 RefPtr<InspectorObject> meta;
351 OwnPtr<HeapGraphSerializer> graphSerializer;
352 OwnPtr<FrontendWrapper> frontendWrapper;
353
354 if (reportGraph) {
355 frontendWrapper = adoptPtr(new FrontendWrapper(m_frontend));
356 graphSerializer = adoptPtr(new HeapGraphSerializer(frontendWrapper.get() ));
357 }
358
359 MemoryInstrumentationClientImpl memoryInstrumentationClient(graphSerializer. get());
360 m_inspectorClient->getAllocatedObjects(memoryInstrumentationClient.allocated Objects());
361 MemoryInstrumentationImpl memoryInstrumentation(&memoryInstrumentationClient );
362
363 reportJSHeapInfo(memoryInstrumentationClient);
364 reportRenderTreeInfo(memoryInstrumentationClient, m_page);
365 collectDomTreeInfo(memoryInstrumentation, m_page); // FIXME: collect for all pages?
366
367 PlatformMemoryInstrumentation::reportStaticMembersMemoryUsage(&memoryInstrum entation);
368 WebCoreMemoryInstrumentation::reportStaticMembersMemoryUsage(&memoryInstrume ntation);
369
370 memoryInstrumentation.addRootObject(this);
371 memoryInstrumentation.addRootObject(memoryInstrumentation);
372 memoryInstrumentation.addRootObject(memoryInstrumentationClient);
373 if (graphSerializer) {
374 memoryInstrumentation.addRootObject(graphSerializer.get());
375 meta = graphSerializer->finish();
376 graphSerializer.release(); // Release it earlier than frontendWrapper
377 frontendWrapper.release();
378 }
379
380 m_inspectorClient->dumpUncountedAllocatedObjects(memoryInstrumentationClient .countedObjects());
381
382 *memoryInfo = memoryInstrumentationClient.sizesMap();
383 addPlatformComponentsInfo(memoryInfo);
384 addMemoryInstrumentationDebugData(&memoryInstrumentationClient, memoryInfo);
385 return meta.release();
386 }
387
388 InspectorMemoryAgent::InspectorMemoryAgent(InstrumentingAgents* instrumentingAge nts, InspectorClient* client, InspectorCompositeState* state, Page* page) 80 InspectorMemoryAgent::InspectorMemoryAgent(InstrumentingAgents* instrumentingAge nts, InspectorClient* client, InspectorCompositeState* state, Page* page)
389 : InspectorBaseAgent<InspectorMemoryAgent>("Memory", instrumentingAgents, st ate) 81 : InspectorBaseAgent<InspectorMemoryAgent>("Memory", instrumentingAgents, st ate)
390 , m_inspectorClient(client) 82 , m_inspectorClient(client)
391 , m_page(page) 83 , m_page(page)
392 , m_frontend(0) 84 , m_frontend(0)
393 { 85 {
394 } 86 }
395 87
396 void InspectorMemoryAgent::setFrontend(InspectorFrontend* frontend) 88 void InspectorMemoryAgent::setFrontend(InspectorFrontend* frontend)
397 { 89 {
398 ASSERT(!m_frontend); 90 ASSERT(!m_frontend);
399 m_frontend = frontend->memory(); 91 m_frontend = frontend->memory();
400 } 92 }
401 93
402 void InspectorMemoryAgent::clearFrontend() 94 void InspectorMemoryAgent::clearFrontend()
403 { 95 {
404 m_frontend = 0; 96 m_frontend = 0;
405 } 97 }
406 98
407 } // namespace WebCore 99 } // namespace WebCore
408 100
OLDNEW
« no previous file with comments | « Source/core/inspector/InspectorMemoryAgent.h ('k') | Source/core/inspector/InspectorOverlay.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698