OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "InspectorHeapProfilerAgent.h" | 32 #include "InspectorHeapProfilerAgent.h" |
33 | 33 |
34 #include "InjectedScript.h" | 34 #include "InjectedScript.h" |
35 #include "InjectedScriptHost.h" | 35 #include "InjectedScriptHost.h" |
36 #include "InspectorState.h" | 36 #include "InspectorState.h" |
37 #include "InstrumentingAgents.h" | 37 #include "InstrumentingAgents.h" |
38 #include "ScriptProfiler.h" | 38 #include "ScriptProfiler.h" |
39 #include "WebCoreMemoryInstrumentation.h" | 39 #include "WebCoreMemoryInstrumentation.h" |
| 40 #include "core/platform/Timer.h" |
| 41 #include <wtf/CurrentTime.h> |
40 #include <wtf/MemoryInstrumentationHashMap.h> | 42 #include <wtf/MemoryInstrumentationHashMap.h> |
41 | 43 |
42 namespace WebCore { | 44 namespace WebCore { |
43 | 45 |
44 namespace HeapProfilerAgentState { | 46 namespace HeapProfilerAgentState { |
45 static const char profileHeadersRequested[] = "profileHeadersRequested"; | 47 static const char profileHeadersRequested[] = "profileHeadersRequested"; |
46 } | 48 } |
47 | 49 |
48 static const char* const UserInitiatedProfileNameHeap = "org.webkit.profiles.use
r-initiated"; | 50 static const char* const UserInitiatedProfileNameHeap = "org.webkit.profiles.use
r-initiated"; |
49 | 51 |
| 52 class InspectorHeapProfilerAgent::HeapStatsUpdateTask { |
| 53 public: |
| 54 HeapStatsUpdateTask(InspectorHeapProfilerAgent*); |
| 55 void startTimer(); |
| 56 void resetTimer() { m_timer.stop(); } |
| 57 void onTimer(Timer<HeapStatsUpdateTask>*); |
| 58 |
| 59 private: |
| 60 InspectorHeapProfilerAgent* m_heapProfilerAgent; |
| 61 Timer<HeapStatsUpdateTask> m_timer; |
| 62 }; |
| 63 |
50 PassOwnPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(Instru
mentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, Inj
ectedScriptManager* injectedScriptManager) | 64 PassOwnPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(Instru
mentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, Inj
ectedScriptManager* injectedScriptManager) |
51 { | 65 { |
52 return adoptPtr(new InspectorHeapProfilerAgent(instrumentingAgents, inspecto
rState, injectedScriptManager)); | 66 return adoptPtr(new InspectorHeapProfilerAgent(instrumentingAgents, inspecto
rState, injectedScriptManager)); |
53 } | 67 } |
54 | 68 |
55 InspectorHeapProfilerAgent::InspectorHeapProfilerAgent(InstrumentingAgents* inst
rumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager*
injectedScriptManager) | 69 InspectorHeapProfilerAgent::InspectorHeapProfilerAgent(InstrumentingAgents* inst
rumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager*
injectedScriptManager) |
56 : InspectorBaseAgent<InspectorHeapProfilerAgent>("HeapProfiler", instrumenti
ngAgents, inspectorState) | 70 : InspectorBaseAgent<InspectorHeapProfilerAgent>("HeapProfiler", instrumenti
ngAgents, inspectorState) |
57 , m_injectedScriptManager(injectedScriptManager) | 71 , m_injectedScriptManager(injectedScriptManager) |
58 , m_frontend(0) | 72 , m_frontend(0) |
59 , m_nextUserInitiatedHeapSnapshotNumber(1) | 73 , m_nextUserInitiatedHeapSnapshotNumber(1) |
60 { | 74 { |
61 m_instrumentingAgents->setInspectorHeapProfilerAgent(this); | 75 m_instrumentingAgents->setInspectorHeapProfilerAgent(this); |
62 } | 76 } |
63 | 77 |
64 InspectorHeapProfilerAgent::~InspectorHeapProfilerAgent() | 78 InspectorHeapProfilerAgent::~InspectorHeapProfilerAgent() |
65 { | 79 { |
66 m_instrumentingAgents->setInspectorHeapProfilerAgent(0); | 80 m_instrumentingAgents->setInspectorHeapProfilerAgent(0); |
67 } | 81 } |
68 | 82 |
69 void InspectorHeapProfilerAgent::clearProfiles(ErrorString*) | 83 void InspectorHeapProfilerAgent::clearProfiles(ErrorString*) |
70 { | 84 { |
71 m_snapshots.clear(); | 85 m_snapshots.clear(); |
72 m_nextUserInitiatedHeapSnapshotNumber = 1; | 86 m_nextUserInitiatedHeapSnapshotNumber = 1; |
73 resetFrontendProfiles(); | 87 resetFrontendProfiles(); |
74 m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects(); | 88 m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects(); |
75 } | 89 } |
76 | 90 |
77 void InspectorHeapProfilerAgent::resetFrontendProfiles() | 91 void InspectorHeapProfilerAgent::resetFrontendProfiles() |
78 { | 92 { |
| 93 stopTrackingHeapObjects(0); |
79 if (!m_frontend) | 94 if (!m_frontend) |
80 return; | 95 return; |
81 if (!m_state->getBoolean(HeapProfilerAgentState::profileHeadersRequested)) | 96 if (!m_state->getBoolean(HeapProfilerAgentState::profileHeadersRequested)) |
82 return; | 97 return; |
83 if (m_snapshots.isEmpty()) | 98 if (m_snapshots.isEmpty()) |
84 m_frontend->resetProfiles(); | 99 m_frontend->resetProfiles(); |
85 } | 100 } |
86 | 101 |
87 void InspectorHeapProfilerAgent::setFrontend(InspectorFrontend* frontend) | 102 void InspectorHeapProfilerAgent::setFrontend(InspectorFrontend* frontend) |
88 { | 103 { |
(...skipping 18 matching lines...) Expand all Loading... |
107 | 122 |
108 PassRefPtr<TypeBuilder::HeapProfiler::ProfileHeader> InspectorHeapProfilerAgent:
:createSnapshotHeader(const ScriptHeapSnapshot& snapshot) | 123 PassRefPtr<TypeBuilder::HeapProfiler::ProfileHeader> InspectorHeapProfilerAgent:
:createSnapshotHeader(const ScriptHeapSnapshot& snapshot) |
109 { | 124 { |
110 RefPtr<TypeBuilder::HeapProfiler::ProfileHeader> header = TypeBuilder::HeapP
rofiler::ProfileHeader::create() | 125 RefPtr<TypeBuilder::HeapProfiler::ProfileHeader> header = TypeBuilder::HeapP
rofiler::ProfileHeader::create() |
111 .setUid(snapshot.uid()) | 126 .setUid(snapshot.uid()) |
112 .setTitle(snapshot.title()); | 127 .setTitle(snapshot.title()); |
113 header->setMaxJSObjectId(snapshot.maxSnapshotJSObjectId()); | 128 header->setMaxJSObjectId(snapshot.maxSnapshotJSObjectId()); |
114 return header.release(); | 129 return header.release(); |
115 } | 130 } |
116 | 131 |
| 132 InspectorHeapProfilerAgent::HeapStatsUpdateTask::HeapStatsUpdateTask(InspectorHe
apProfilerAgent* heapProfilerAgent) |
| 133 : m_heapProfilerAgent(heapProfilerAgent) |
| 134 , m_timer(this, &HeapStatsUpdateTask::onTimer) |
| 135 { |
| 136 } |
| 137 |
| 138 void InspectorHeapProfilerAgent::HeapStatsUpdateTask::onTimer(Timer<HeapStatsUpd
ateTask>*) |
| 139 { |
| 140 // The timer is stopped on m_heapProfilerAgent destruction, |
| 141 // so this method will never be called after m_heapProfilerAgent has been de
stroyed. |
| 142 m_heapProfilerAgent->requestHeapStatsUpdate(); |
| 143 } |
| 144 |
| 145 void InspectorHeapProfilerAgent::HeapStatsUpdateTask::startTimer() |
| 146 { |
| 147 ASSERT(!m_timer.isActive()); |
| 148 m_timer.startRepeating(0.05); |
| 149 } |
| 150 |
| 151 class InspectorHeapProfilerAgent::HeapStatsStream : public ScriptProfiler::Outpu
tStream { |
| 152 public: |
| 153 HeapStatsStream(InspectorHeapProfilerAgent* heapProfilerAgent) |
| 154 : m_heapProfilerAgent(heapProfilerAgent) |
| 155 { |
| 156 } |
| 157 |
| 158 virtual void write(const uint32_t* chunk, const int size) OVERRIDE |
| 159 { |
| 160 ASSERT(chunk); |
| 161 ASSERT(size > 0); |
| 162 m_heapProfilerAgent->pushHeapStatsUpdate(chunk, size); |
| 163 } |
| 164 private: |
| 165 InspectorHeapProfilerAgent* m_heapProfilerAgent; |
| 166 }; |
| 167 |
| 168 void InspectorHeapProfilerAgent::startTrackingHeapObjects(ErrorString*) |
| 169 { |
| 170 if (m_heapStatsUpdateTask) |
| 171 return; |
| 172 ScriptProfiler::startTrackingHeapObjects(); |
| 173 m_heapStatsUpdateTask = adoptPtr(new HeapStatsUpdateTask(this)); |
| 174 m_heapStatsUpdateTask->startTimer(); |
| 175 } |
| 176 |
| 177 void InspectorHeapProfilerAgent::requestHeapStatsUpdate() |
| 178 { |
| 179 if (!m_frontend) |
| 180 return; |
| 181 HeapStatsStream stream(this); |
| 182 SnapshotObjectId lastSeenObjectId = ScriptProfiler::requestHeapStatsUpdate(&
stream); |
| 183 m_frontend->lastSeenObjectId(lastSeenObjectId, WTF::currentTimeMS()); |
| 184 } |
| 185 |
| 186 void InspectorHeapProfilerAgent::pushHeapStatsUpdate(const uint32_t* const data,
const int size) |
| 187 { |
| 188 if (!m_frontend) |
| 189 return; |
| 190 RefPtr<TypeBuilder::Array<int> > statsDiff = TypeBuilder::Array<int>::create
(); |
| 191 for (int i = 0; i < size; ++i) |
| 192 statsDiff->addItem(data[i]); |
| 193 m_frontend->heapStatsUpdate(statsDiff.release()); |
| 194 } |
| 195 |
| 196 void InspectorHeapProfilerAgent::stopTrackingHeapObjects(ErrorString*) |
| 197 { |
| 198 if (!m_heapStatsUpdateTask) |
| 199 return; |
| 200 ScriptProfiler::stopTrackingHeapObjects(); |
| 201 m_heapStatsUpdateTask->resetTimer(); |
| 202 m_heapStatsUpdateTask.clear(); |
| 203 } |
| 204 |
117 void InspectorHeapProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<TypeBuil
der::Array<TypeBuilder::HeapProfiler::ProfileHeader> >& headers) | 205 void InspectorHeapProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<TypeBuil
der::Array<TypeBuilder::HeapProfiler::ProfileHeader> >& headers) |
118 { | 206 { |
119 m_state->setBoolean(HeapProfilerAgentState::profileHeadersRequested, true); | 207 m_state->setBoolean(HeapProfilerAgentState::profileHeadersRequested, true); |
120 headers = TypeBuilder::Array<TypeBuilder::HeapProfiler::ProfileHeader>::crea
te(); | 208 headers = TypeBuilder::Array<TypeBuilder::HeapProfiler::ProfileHeader>::crea
te(); |
121 | 209 |
122 IdToHeapSnapshotMap::iterator snapshotsEnd = m_snapshots.end(); | 210 IdToHeapSnapshotMap::iterator snapshotsEnd = m_snapshots.end(); |
123 for (IdToHeapSnapshotMap::iterator it = m_snapshots.begin(); it != snapshots
End; ++it) | 211 for (IdToHeapSnapshotMap::iterator it = m_snapshots.begin(); it != snapshots
End; ++it) |
124 headers->addItem(createSnapshotHeader(*it->value)); | 212 headers->addItem(createSnapshotHeader(*it->value)); |
125 } | 213 } |
126 | 214 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 { | 322 { |
235 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::InspectorPr
ofilerAgent); | 323 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::InspectorPr
ofilerAgent); |
236 InspectorBaseAgent<InspectorHeapProfilerAgent>::reportMemoryUsage(memoryObje
ctInfo); | 324 InspectorBaseAgent<InspectorHeapProfilerAgent>::reportMemoryUsage(memoryObje
ctInfo); |
237 info.addMember(m_injectedScriptManager, "injectedScriptManager"); | 325 info.addMember(m_injectedScriptManager, "injectedScriptManager"); |
238 info.addWeakPointer(m_frontend); | 326 info.addWeakPointer(m_frontend); |
239 info.addMember(m_snapshots, "snapshots"); | 327 info.addMember(m_snapshots, "snapshots"); |
240 } | 328 } |
241 | 329 |
242 } // namespace WebCore | 330 } // namespace WebCore |
243 | 331 |
OLD | NEW |