blob: 322eb99e4aa067515b95e2af666dafbe82df3507 [file] [log] [blame]
mnaganov@chromium.org00743c32010-08-23 09:35:21 +00001/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000031
abecsi@webkit.org62340002010-11-24 14:38:47 +000032#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000033
yurys@chromium.org83110c82012-03-15 16:44:09 +000034#include "InspectorProfilerAgent.h"
35
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000036#include "Console.h"
mkwst@chromium.org236e8982012-12-11 16:10:06 +000037#include "ConsoleAPITypes.h"
38#include "ConsoleTypes.h"
yurys@chromium.orga1270f82012-02-08 15:51:53 +000039#include "InjectedScript.h"
loislo@chromium.orgf59b0302012-02-16 14:23:51 +000040#include "InjectedScriptHost.h"
yurys@chromium.org7382e722011-01-14 14:57:21 +000041#include "InspectorConsoleAgent.h"
loislo@chromium.orgb3d4ff42010-08-24 12:26:55 +000042#include "InspectorFrontend.h"
yurys@chromium.org0928fb92011-03-12 07:21:34 +000043#include "InspectorState.h"
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000044#include "InspectorValues.h"
yurys@chromium.org29626f82011-03-04 15:15:45 +000045#include "InstrumentingAgents.h"
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000046#include "KURL.h"
47#include "Page.h"
yurys@chromium.org7f1e51a2011-03-30 15:26:22 +000048#include "PageScriptDebugServer.h"
mnaganov@chromium.org06106af2010-08-26 18:27:24 +000049#include "ScriptHeapSnapshot.h"
yurys@chromium.orga1270f82012-02-08 15:51:53 +000050#include "ScriptObject.h"
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000051#include "ScriptProfile.h"
52#include "ScriptProfiler.h"
commit-queue@webkit.org77a038f2012-09-25 01:05:43 +000053#include "WorkerScriptDebugServer.h"
caseq@chromium.org5249d112012-12-18 11:43:35 +000054#include <wtf/CurrentTime.h>
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000055#include <wtf/OwnPtr.h>
zimmermann@webkit.orgbbfe2a52010-10-14 19:48:45 +000056#include <wtf/text/StringConcatenate.h>
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000057
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000058namespace WebCore {
59
yurys@chromium.org0928fb92011-03-12 07:21:34 +000060namespace ProfilerAgentState {
61static const char userInitiatedProfiling[] = "userInitiatedProfiling";
62static const char profilerEnabled[] = "profilerEnabled";
yurys@chromium.org9b845a12013-02-20 12:15:51 +000063static const char profileHeadersRequested[] = "profileHeadersRequested";
yurys@chromium.org0928fb92011-03-12 07:21:34 +000064}
65
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000066static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
67static const char* const CPUProfileType = "CPU";
mnaganov@chromium.org06106af2010-08-26 18:27:24 +000068static const char* const HeapProfileType = "HEAP";
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000069
yurys@chromium.orgf58fc042012-02-29 15:42:10 +000070
71class PageProfilerAgent : public InspectorProfilerAgent {
72public:
apavlov@chromium.orgc7e14332012-12-25 09:00:28 +000073 PageProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager)
yurys@chromium.orgf58fc042012-02-29 15:42:10 +000074 : InspectorProfilerAgent(instrumentingAgents, consoleAgent, state, injectedScriptManager), m_inspectedPage(inspectedPage) { }
75 virtual ~PageProfilerAgent() { }
76
77private:
commit-queue@webkit.org77a038f2012-09-25 01:05:43 +000078 virtual void recompileScript()
79 {
80 PageScriptDebugServer::shared().recompileAllJSFunctionsSoon();
81 }
82
yurys@chromium.orgf58fc042012-02-29 15:42:10 +000083 virtual void startProfiling(const String& title)
84 {
85 ScriptProfiler::startForPage(m_inspectedPage, title);
86 }
87
88 virtual PassRefPtr<ScriptProfile> stopProfiling(const String& title)
89 {
90 return ScriptProfiler::stopForPage(m_inspectedPage, title);
91 }
92
93 Page* m_inspectedPage;
94};
95
apavlov@chromium.orgc7e14332012-12-25 09:00:28 +000096PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000097{
yurys@chromium.orgf58fc042012-02-29 15:42:10 +000098 return adoptPtr(new PageProfilerAgent(instrumentingAgents, consoleAgent, inspectedPage, inspectorState, injectedScriptManager));
mnaganov@chromium.org00743c32010-08-23 09:35:21 +000099}
100
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000101#if ENABLE(WORKERS)
102class WorkerProfilerAgent : public InspectorProfilerAgent {
103public:
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000104 WorkerProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, WorkerGlobalScope* workerGlobalScope, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager)
105 : InspectorProfilerAgent(instrumentingAgents, consoleAgent, state, injectedScriptManager), m_workerGlobalScope(workerGlobalScope) { }
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000106 virtual ~WorkerProfilerAgent() { }
107
108private:
commit-queue@webkit.org77a038f2012-09-25 01:05:43 +0000109 virtual void recompileScript() { }
110
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000111 virtual void startProfiling(const String& title)
112 {
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000113 ScriptProfiler::startForWorkerGlobalScope(m_workerGlobalScope, title);
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000114 }
115
116 virtual PassRefPtr<ScriptProfile> stopProfiling(const String& title)
117 {
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000118 return ScriptProfiler::stopForWorkerGlobalScope(m_workerGlobalScope, title);
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000119 }
120
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000121 WorkerGlobalScope* m_workerGlobalScope;
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000122};
123
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000124PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, WorkerGlobalScope* workerGlobalScope, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000125{
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000126 return adoptPtr(new WorkerProfilerAgent(instrumentingAgents, consoleAgent, workerGlobalScope, inspectorState, injectedScriptManager));
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000127}
128#endif
129
apavlov@chromium.orgc7e14332012-12-25 09:00:28 +0000130InspectorProfilerAgent::InspectorProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
pfeldman@chromium.org2f44edb2011-11-29 14:43:10 +0000131 : InspectorBaseAgent<InspectorProfilerAgent>("Profiler", instrumentingAgents, inspectorState)
yurys@chromium.org29626f82011-03-04 15:15:45 +0000132 , m_consoleAgent(consoleAgent)
mnaganov@chromium.org90b24e82011-10-17 13:21:12 +0000133 , m_injectedScriptManager(injectedScriptManager)
loislo@chromium.orgb3d4ff42010-08-24 12:26:55 +0000134 , m_frontend(0)
yurys@chromium.org591972a2011-01-27 14:03:18 +0000135 , m_enabled(false)
caseq@chromium.org5249d112012-12-18 11:43:35 +0000136 , m_recordingCPUProfile(false)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000137 , m_currentUserInitiatedProfileNumber(-1)
138 , m_nextUserInitiatedProfileNumber(1)
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000139 , m_nextUserInitiatedHeapSnapshotNumber(1)
caseq@chromium.org5249d112012-12-18 11:43:35 +0000140 , m_profileNameIdleTimeMap(ScriptProfiler::currentProfileNameIdleTimeMap())
141 , m_previousTaskEndTime(0.0)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000142{
yurys@chromium.org29626f82011-03-04 15:15:45 +0000143 m_instrumentingAgents->setInspectorProfilerAgent(this);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000144}
145
146InspectorProfilerAgent::~InspectorProfilerAgent()
147{
yurys@chromium.org29626f82011-03-04 15:15:45 +0000148 m_instrumentingAgents->setInspectorProfilerAgent(0);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000149}
150
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000151void InspectorProfilerAgent::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, unsigned columnNumber, const String& sourceURL)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000152{
153 RefPtr<ScriptProfile> profile = prpProfile;
154 m_profiles.add(profile->uid(), profile);
yurys@chromium.org9b845a12013-02-20 12:15:51 +0000155 if (m_frontend && m_state->getBoolean(ProfilerAgentState::profileHeadersRequested))
loislo@chromium.orgb3d4ff42010-08-24 12:26:55 +0000156 m_frontend->addProfileHeader(createProfileHeader(*profile));
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000157 addProfileFinishedMessageToConsole(profile, lineNumber, columnNumber, sourceURL);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000158}
159
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000160void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, unsigned columnNumber, const String& sourceURL)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000161{
mnaganov@chromium.org83d221f2011-01-21 14:41:54 +0000162 if (!m_frontend)
163 return;
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000164 RefPtr<ScriptProfile> profile = prpProfile;
eustas@chromium.orgea9efbb2013-02-21 11:39:17 +0000165 String message = makeString(profile->title(), '#', String::number(profile->uid()));
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000166 m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, ProfileEndMessageType, DebugMessageLevel, message, sourceURL, lineNumber, columnNumber);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000167}
168
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000169void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, unsigned columnNumber, const String& sourceURL)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000170{
mnaganov@chromium.org83d221f2011-01-21 14:41:54 +0000171 if (!m_frontend)
172 return;
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000173 m_consoleAgent->addMessageToConsole(ConsoleAPIMessageSource, ProfileMessageType, DebugMessageLevel, title, sourceURL, lineNumber, columnNumber);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000174}
175
pfeldman@chromium.orgb35e6872011-03-10 16:36:53 +0000176void InspectorProfilerAgent::collectGarbage(WebCore::ErrorString*)
177{
178 ScriptProfiler::collectGarbage();
179}
180
loislo@chromium.orged5533c2012-05-05 06:52:38 +0000181PassRefPtr<TypeBuilder::Profiler::ProfileHeader> InspectorProfilerAgent::createProfileHeader(const ScriptProfile& profile)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000182{
loislo@chromium.orged5533c2012-05-05 06:52:38 +0000183 return TypeBuilder::Profiler::ProfileHeader::create()
184 .setTypeId(TypeBuilder::Profiler::ProfileHeader::TypeId::CPU)
185 .setUid(profile.uid())
186 .setTitle(profile.title())
187 .release();
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000188}
189
loislo@chromium.orged5533c2012-05-05 06:52:38 +0000190PassRefPtr<TypeBuilder::Profiler::ProfileHeader> InspectorProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot)
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000191{
loislo@chromium.orged5533c2012-05-05 06:52:38 +0000192 RefPtr<TypeBuilder::Profiler::ProfileHeader> header = TypeBuilder::Profiler::ProfileHeader::create()
193 .setTypeId(TypeBuilder::Profiler::ProfileHeader::TypeId::HEAP)
194 .setUid(snapshot.uid())
195 .setTitle(snapshot.title());
196 header->setMaxJSObjectId(snapshot.maxSnapshotJSObjectId());
197 return header.release();
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000198}
199
pfeldman@chromium.orgf988d462011-12-01 11:33:10 +0000200void InspectorProfilerAgent::causesRecompilation(ErrorString*, bool* result)
201{
202 *result = ScriptProfiler::causesRecompilation();
203}
204
205void InspectorProfilerAgent::isSampling(ErrorString*, bool* result)
206{
207 *result = ScriptProfiler::isSampling();
208}
209
210void InspectorProfilerAgent::hasHeapProfiler(ErrorString*, bool* result)
211{
212 *result = ScriptProfiler::hasHeapProfiler();
213}
214
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000215void InspectorProfilerAgent::enable(ErrorString*)
216{
217 if (enabled())
218 return;
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000219 m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000220 enable(false);
221}
222
223void InspectorProfilerAgent::disable(ErrorString*)
224{
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000225 m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000226 disable();
227}
228
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000229void InspectorProfilerAgent::disable()
230{
231 if (!m_enabled)
232 return;
233 m_enabled = false;
yurys@chromium.org9b845a12013-02-20 12:15:51 +0000234 m_state->setBoolean(ProfilerAgentState::profileHeadersRequested, false);
commit-queue@webkit.org77a038f2012-09-25 01:05:43 +0000235 recompileScript();
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000236}
237
238void InspectorProfilerAgent::enable(bool skipRecompile)
239{
240 if (m_enabled)
241 return;
242 m_enabled = true;
243 if (!skipRecompile)
commit-queue@webkit.org77a038f2012-09-25 01:05:43 +0000244 recompileScript();
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000245}
246
247String InspectorProfilerAgent::getCurrentUserInitiatedProfileName(bool incrementProfileNumber)
248{
249 if (incrementProfileNumber)
250 m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++;
251
zimmermann@webkit.orgbbfe2a52010-10-14 19:48:45 +0000252 return makeString(UserInitiatedProfileName, '.', String::number(m_currentUserInitiatedProfileNumber));
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000253}
254
loislo@chromium.orged5533c2012-05-05 06:52:38 +0000255void InspectorProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Profiler::ProfileHeader> >& headers)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000256{
yurys@chromium.org9b845a12013-02-20 12:15:51 +0000257 m_state->setBoolean(ProfilerAgentState::profileHeadersRequested, true);
loislo@chromium.orged5533c2012-05-05 06:52:38 +0000258 headers = TypeBuilder::Array<TypeBuilder::Profiler::ProfileHeader>::create();
commit-queue@webkit.org178f8e02012-04-05 13:25:04 +0000259
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000260 ProfilesMap::iterator profilesEnd = m_profiles.end();
261 for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it)
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000262 headers->addItem(createProfileHeader(*it->value));
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000263 HeapSnapshotsMap::iterator snapshotsEnd = m_snapshots.end();
264 for (HeapSnapshotsMap::iterator it = m_snapshots.begin(); it != snapshotsEnd; ++it)
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000265 headers->addItem(createSnapshotHeader(*it->value));
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000266}
267
mnaganov@chromium.orgaf7ad7a2010-11-29 23:37:08 +0000268namespace {
269
270class OutputStream : public ScriptHeapSnapshot::OutputStream {
271public:
pfeldman@chromium.org7e420b52011-03-21 07:54:32 +0000272 OutputStream(InspectorFrontend::Profiler* frontend, unsigned uid)
mnaganov@chromium.orgaf7ad7a2010-11-29 23:37:08 +0000273 : m_frontend(frontend), m_uid(uid) { }
274 void Write(const String& chunk) { m_frontend->addHeapSnapshotChunk(m_uid, chunk); }
275 void Close() { m_frontend->finishHeapSnapshot(m_uid); }
276private:
yurys@chromium.org3fb16632011-03-03 05:43:34 +0000277 InspectorFrontend::Profiler* m_frontend;
pfeldman@chromium.org7e420b52011-03-21 07:54:32 +0000278 int m_uid;
mnaganov@chromium.orgaf7ad7a2010-11-29 23:37:08 +0000279};
280
281} // namespace
282
commit-queue@webkit.org24efed32013-01-17 18:50:59 +0000283void InspectorProfilerAgent::getCPUProfile(ErrorString* errorString, int rawUid, RefPtr<TypeBuilder::Profiler::CPUProfile>& profileObject)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000284{
yurys@chromium.orgc22f7452012-02-06 07:39:40 +0000285 unsigned uid = static_cast<unsigned>(rawUid);
commit-queue@webkit.org24efed32013-01-17 18:50:59 +0000286 ProfilesMap::iterator it = m_profiles.find(uid);
287 if (it == m_profiles.end()) {
288 *errorString = "Profile wasn't found";
289 return;
290 }
291 profileObject = TypeBuilder::Profiler::CPUProfile::create();
292 profileObject->setHead(it->value->buildInspectorObjectForHead());
commit-queue@webkit.org24efed32013-01-17 18:50:59 +0000293 profileObject->setIdleTime(it->value->idleTime());
294}
295
296void InspectorProfilerAgent::getHeapSnapshot(ErrorString* errorString, int rawUid)
297{
298 unsigned uid = static_cast<unsigned>(rawUid);
299 HeapSnapshotsMap::iterator it = m_snapshots.find(uid);
300 if (it == m_snapshots.end()) {
301 *errorString = "Profile wasn't found";
302 return;
303 }
304 RefPtr<ScriptHeapSnapshot> snapshot = it->value;
305 if (m_frontend) {
306 OutputStream stream(m_frontend, uid);
307 snapshot->writeJSON(&stream);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000308 }
309}
310
yurys@chromium.orgc22f7452012-02-06 07:39:40 +0000311void InspectorProfilerAgent::removeProfile(ErrorString*, const String& type, int rawUid)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000312{
yurys@chromium.orgc22f7452012-02-06 07:39:40 +0000313 unsigned uid = static_cast<unsigned>(rawUid);
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000314 if (type == CPUProfileType) {
315 if (m_profiles.contains(uid))
316 m_profiles.remove(uid);
317 } else if (type == HeapProfileType) {
318 if (m_snapshots.contains(uid))
319 m_snapshots.remove(uid);
320 }
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000321}
322
323void InspectorProfilerAgent::resetState()
324{
pfeldman@chromium.org6a1f9522011-11-22 09:52:10 +0000325 stop();
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000326 m_profiles.clear();
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000327 m_snapshots.clear();
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000328 m_currentUserInitiatedProfileNumber = 1;
329 m_nextUserInitiatedProfileNumber = 1;
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000330 m_nextUserInitiatedHeapSnapshotNumber = 1;
mnaganov@chromium.org57fe9f72011-01-20 16:21:35 +0000331 resetFrontendProfiles();
loislo@chromium.orgf59b0302012-02-16 14:23:51 +0000332 m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
mnaganov@chromium.org57fe9f72011-01-20 16:21:35 +0000333}
334
335void InspectorProfilerAgent::resetFrontendProfiles()
336{
yurys@chromium.org9b845a12013-02-20 12:15:51 +0000337 if (!m_frontend)
338 return;
339 if (!m_state->getBoolean(ProfilerAgentState::profileHeadersRequested))
340 return;
341 if (m_profiles.isEmpty() && m_snapshots.isEmpty())
loislo@chromium.org2c950cf2010-12-13 15:35:42 +0000342 m_frontend->resetProfiles();
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000343}
344
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000345void InspectorProfilerAgent::setFrontend(InspectorFrontend* frontend)
346{
347 m_frontend = frontend->profiler();
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000348}
349
350void InspectorProfilerAgent::clearFrontend()
351{
352 m_frontend = 0;
pfeldman@chromium.org6a1f9522011-11-22 09:52:10 +0000353 stop();
commit-queue@webkit.org50a59152012-01-13 17:43:17 +0000354 ErrorString error;
355 disable(&error);
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000356}
357
358void InspectorProfilerAgent::restore()
359{
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000360 // Need to restore enablement state here as in setFrontend m_state wasn't loaded yet.
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000361 restoreEnablement();
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000362 resetFrontendProfiles();
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000363 if (m_state->getBoolean(ProfilerAgentState::userInitiatedProfiling))
pfeldman@chromium.org6a1f9522011-11-22 09:52:10 +0000364 start();
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000365}
366
367void InspectorProfilerAgent::restoreEnablement()
368{
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000369 if (m_state->getBoolean(ProfilerAgentState::profilerEnabled)) {
yurys@chromium.org0928fb92011-03-12 07:21:34 +0000370 ErrorString error;
371 enable(&error);
372 }
373}
374
pfeldman@chromium.org6a1f9522011-11-22 09:52:10 +0000375void InspectorProfilerAgent::start(ErrorString*)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000376{
caseq@chromium.org5249d112012-12-18 11:43:35 +0000377 if (m_recordingCPUProfile)
mnaganov@chromium.orgccce4022010-11-08 13:38:46 +0000378 return;
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000379 if (!enabled()) {
yurys@chromium.org591972a2011-01-27 14:03:18 +0000380 enable(true);
yurys@chromium.org7f1e51a2011-03-30 15:26:22 +0000381 PageScriptDebugServer::shared().recompileAllJSFunctions(0);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000382 }
caseq@chromium.org5249d112012-12-18 11:43:35 +0000383 m_recordingCPUProfile = true;
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000384 String title = getCurrentUserInitiatedProfileName(true);
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000385 startProfiling(title);
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000386 addStartProfilingMessageToConsole(title, 0, 0, String());
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000387 toggleRecordButton(true);
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000388 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000389}
390
pfeldman@chromium.org6a1f9522011-11-22 09:52:10 +0000391void InspectorProfilerAgent::stop(ErrorString*)
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000392{
caseq@chromium.org5249d112012-12-18 11:43:35 +0000393 if (!m_recordingCPUProfile)
mnaganov@chromium.orgccce4022010-11-08 13:38:46 +0000394 return;
caseq@chromium.org5249d112012-12-18 11:43:35 +0000395 m_recordingCPUProfile = false;
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000396 String title = getCurrentUserInitiatedProfileName();
yurys@chromium.orgf58fc042012-02-29 15:42:10 +0000397 RefPtr<ScriptProfile> profile = stopProfiling(title);
pfeldman@chromium.org6a1f9522011-11-22 09:52:10 +0000398 if (profile)
joepeck@webkit.org379c8a12013-04-25 18:31:05 +0000399 addProfile(profile, 0, 0, String());
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000400 toggleRecordButton(false);
pfeldman@chromium.orgccc8cd932011-11-28 14:41:48 +0000401 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000402}
403
mnaganov@chromium.org8d2d9a42011-01-25 17:11:06 +0000404namespace {
405
406class HeapSnapshotProgress: public ScriptProfiler::HeapSnapshotProgress {
407public:
yurys@chromium.org3fb16632011-03-03 05:43:34 +0000408 explicit HeapSnapshotProgress(InspectorFrontend::Profiler* frontend)
mnaganov@chromium.org8d2d9a42011-01-25 17:11:06 +0000409 : m_frontend(frontend) { }
410 void Start(int totalWork)
411 {
412 m_totalWork = totalWork;
413 }
414 void Worked(int workDone)
415 {
416 if (m_frontend)
417 m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork);
418 }
419 void Done() { }
420 bool isCanceled() { return false; }
421private:
yurys@chromium.org3fb16632011-03-03 05:43:34 +0000422 InspectorFrontend::Profiler* m_frontend;
mnaganov@chromium.org8d2d9a42011-01-25 17:11:06 +0000423 int m_totalWork;
424};
425
426};
427
yurys@chromium.orgfb86ee82013-01-31 08:45:50 +0000428void InspectorProfilerAgent::takeHeapSnapshot(ErrorString*, const bool* reportProgress)
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000429{
zimmermann@webkit.orgbbfe2a52010-10-14 19:48:45 +0000430 String title = makeString(UserInitiatedProfileName, '.', String::number(m_nextUserInitiatedHeapSnapshotNumber));
431 ++m_nextUserInitiatedHeapSnapshotNumber;
432
yurys@chromium.orgfb86ee82013-01-31 08:45:50 +0000433 HeapSnapshotProgress progress(reportProgress && *reportProgress ? m_frontend : 0);
mnaganov@chromium.orgaa5ba812011-06-21 19:52:51 +0000434 RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title, &progress);
mnaganov@chromium.org06106af2010-08-26 18:27:24 +0000435 if (snapshot) {
436 m_snapshots.add(snapshot->uid(), snapshot);
437 if (m_frontend)
438 m_frontend->addProfileHeader(createSnapshotHeader(*snapshot));
439 }
440}
441
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000442void InspectorProfilerAgent::toggleRecordButton(bool isProfiling)
443{
loislo@chromium.orgb3d4ff42010-08-24 12:26:55 +0000444 if (m_frontend)
445 m_frontend->setRecordingProfile(isProfiling);
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000446}
447
yurys@chromium.org503c0f82012-05-11 15:05:42 +0000448void InspectorProfilerAgent::getObjectByHeapObjectId(ErrorString* error, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result)
mnaganov@chromium.org90b24e82011-10-17 13:21:12 +0000449{
yurys@chromium.org503c0f82012-05-11 15:05:42 +0000450 bool ok;
451 unsigned id = heapSnapshotObjectId.toUInt(&ok);
452 if (!ok) {
453 *error = "Invalid heap snapshot object id";
454 return;
455 }
yurys@chromium.orga1270f82012-02-08 15:51:53 +0000456 ScriptObject heapObject = ScriptProfiler::objectByHeapObjectId(id);
457 if (heapObject.hasNoValue()) {
yurys@chromium.org6ec28e22012-04-02 12:13:08 +0000458 *error = "Object is not available";
yurys@chromium.orga1270f82012-02-08 15:51:53 +0000459 return;
460 }
461 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState());
462 if (injectedScript.hasNoValue()) {
yurys@chromium.org6ec28e22012-04-02 12:13:08 +0000463 *error = "Object is not available. Inspected context is gone";
yurys@chromium.orga1270f82012-02-08 15:51:53 +0000464 return;
465 }
466 result = injectedScript.wrapObject(heapObject, objectGroup ? *objectGroup : "");
467 if (!result)
yurys@chromium.org6ec28e22012-04-02 12:13:08 +0000468 *error = "Failed to wrap object";
mnaganov@chromium.org90b24e82011-10-17 13:21:12 +0000469}
470
yurys@chromium.org503c0f82012-05-11 15:05:42 +0000471void InspectorProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId)
472{
473 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
474 if (injectedScript.hasNoValue()) {
475 *errorString = "Inspected context has gone";
476 return;
477 }
478 ScriptValue value = injectedScript.findObjectById(objectId);
479 if (value.hasNoValue() || value.isUndefined()) {
480 *errorString = "Object with given id not found";
481 return;
482 }
483 unsigned id = ScriptProfiler::getHeapObjectId(value);
484 *heapSnapshotObjectId = String::number(id);
485}
486
caseq@chromium.org5249d112012-12-18 11:43:35 +0000487void InspectorProfilerAgent::willProcessTask()
488{
489 if (!m_profileNameIdleTimeMap || !m_profileNameIdleTimeMap->size())
490 return;
491 if (!m_previousTaskEndTime)
492 return;
493
commit-queue@webkit.orga5f446a2013-08-16 19:33:59 +0000494 double idleTime = monotonicallyIncreasingTime() - m_previousTaskEndTime;
caseq@chromium.org5249d112012-12-18 11:43:35 +0000495 m_previousTaskEndTime = 0.0;
496 ProfileNameIdleTimeMap::iterator end = m_profileNameIdleTimeMap->end();
497 for (ProfileNameIdleTimeMap::iterator it = m_profileNameIdleTimeMap->begin(); it != end; ++it)
498 it->value += idleTime;
499}
500
501void InspectorProfilerAgent::didProcessTask()
502{
503 if (!m_profileNameIdleTimeMap || !m_profileNameIdleTimeMap->size())
504 return;
commit-queue@webkit.orga5f446a2013-08-16 19:33:59 +0000505 m_previousTaskEndTime = monotonicallyIncreasingTime();
caseq@chromium.org5249d112012-12-18 11:43:35 +0000506}
507
mnaganov@chromium.org00743c32010-08-23 09:35:21 +0000508} // namespace WebCore
509
abecsi@webkit.org62340002010-11-24 14:38:47 +0000510#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)