1e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block/* 2e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Copyright (C) 2010 Apple Inc. All rights reserved. 3e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Copyright (C) 2010 Google Inc. All rights reserved. 4e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 5e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Redistribution and use in source and binary forms, with or without 6e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * modification, are permitted provided that the following conditions 7e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * are met: 8e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 9e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 1. Redistributions of source code must retain the above copyright 10e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * notice, this list of conditions and the following disclaimer. 11e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 2. Redistributions in binary form must reproduce the above copyright 12e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * notice, this list of conditions and the following disclaimer in the 13e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * documentation and/or other materials provided with the distribution. 14e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * its contributors may be used to endorse or promote products derived 16e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * from this software without specific prior written permission. 17e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 18e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block */ 29e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 30e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "config.h" 31e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "InspectorProfilerAgent.h" 32e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 334576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR) 34e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 35e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "Console.h" 3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorConsoleAgent.h" 37e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "InspectorFrontend.h" 382bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "InspectorState.h" 39e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "InspectorValues.h" 4081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "InstrumentingAgents.h" 41e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "KURL.h" 42e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "Page.h" 432bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "PageScriptDebugServer.h" 442bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "ScriptController.h" 455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "ScriptHeapSnapshot.h" 46e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "ScriptProfile.h" 47e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "ScriptProfiler.h" 48e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include <wtf/OwnPtr.h> 49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/text/StringConcatenate.h> 50e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 51e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if USE(JSC) 52e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "JSDOMWindow.h" 53e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif 54e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 55e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blocknamespace WebCore { 56e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 572bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace ProfilerAgentState { 582bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char userInitiatedProfiling[] = "userInitiatedProfiling"; 592bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char profilerEnabled[] = "profilerEnabled"; 602bde8e466a4451c7319e3a072d118917957d6554Steve Block} 612bde8e466a4451c7319e3a072d118917957d6554Steve Block 62e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated"; 63e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* const CPUProfileType = "CPU"; 645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenstatic const char* const HeapProfileType = "HEAP"; 65e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 662bde8e466a4451c7319e3a072d118917957d6554Steve BlockPassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorState* inspectorState) 67e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 682bde8e466a4451c7319e3a072d118917957d6554Steve Block return adoptPtr(new InspectorProfilerAgent(instrumentingAgents, consoleAgent, inspectedPage, inspectorState)); 69e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 70e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 712bde8e466a4451c7319e3a072d118917957d6554Steve BlockInspectorProfilerAgent::InspectorProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorState* inspectorState) 7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_instrumentingAgents(instrumentingAgents) 7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_consoleAgent(consoleAgent) 7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_inspectedPage(inspectedPage) 752bde8e466a4451c7319e3a072d118917957d6554Steve Block , m_inspectorState(inspectorState) 76e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_frontend(0) 772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block , m_enabled(false) 78e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_recordingUserInitiatedProfile(false) 79e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_currentUserInitiatedProfileNumber(-1) 80e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_nextUserInitiatedProfileNumber(1) 815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen , m_nextUserInitiatedHeapSnapshotNumber(1) 82e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_instrumentingAgents->setInspectorProfilerAgent(this); 84e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 85e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 86e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockInspectorProfilerAgent::~InspectorProfilerAgent() 87e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 8881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_instrumentingAgents->setInspectorProfilerAgent(0); 89e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 90e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 91e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL) 92e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 93e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block RefPtr<ScriptProfile> profile = prpProfile; 94e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_profiles.add(profile->uid(), profile); 95e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_frontend) 96e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_frontend->addProfileHeader(createProfileHeader(*profile)); 97e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block addProfileFinishedMessageToConsole(profile, lineNumber, sourceURL); 98e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 99e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 100e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL) 101e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 102ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!m_frontend) 103ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 104e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block RefPtr<ScriptProfile> profile = prpProfile; 105e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block String title = profile->title(); 106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), '#', String::number(profile->uid()), "\" finished."); 10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_consoleAgent->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); 108e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 109e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 110e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL) 111e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 112ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!m_frontend) 113ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 11428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), "#0\" started."); 11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_consoleAgent->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); 116e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 117e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 1182bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::collectGarbage(WebCore::ErrorString*) 1192bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1202bde8e466a4451c7319e3a072d118917957d6554Steve Block ScriptProfiler::collectGarbage(); 1212bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1222bde8e466a4451c7319e3a072d118917957d6554Steve Block 123e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockPassRefPtr<InspectorObject> InspectorProfilerAgent::createProfileHeader(const ScriptProfile& profile) 124e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 125e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block RefPtr<InspectorObject> header = InspectorObject::create(); 126e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block header->setString("title", profile.title()); 127e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block header->setNumber("uid", profile.uid()); 128e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block header->setString("typeId", String(CPUProfileType)); 129e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return header; 130e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 131e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 1325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<InspectorObject> InspectorProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot) 1335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen RefPtr<InspectorObject> header = InspectorObject::create(); 1355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen header->setString("title", snapshot.title()); 1365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen header->setNumber("uid", snapshot.uid()); 1375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen header->setString("typeId", String(HeapProfileType)); 1385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return header; 1395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1412bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::enable(ErrorString*) 1422bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1432bde8e466a4451c7319e3a072d118917957d6554Steve Block if (enabled()) 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 1452bde8e466a4451c7319e3a072d118917957d6554Steve Block m_inspectorState->setBoolean(ProfilerAgentState::profilerEnabled, true); 1462bde8e466a4451c7319e3a072d118917957d6554Steve Block enable(false); 1472bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1482bde8e466a4451c7319e3a072d118917957d6554Steve Block 1492bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::disable(ErrorString*) 1502bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1512bde8e466a4451c7319e3a072d118917957d6554Steve Block m_inspectorState->setBoolean(ProfilerAgentState::profilerEnabled, false); 1522bde8e466a4451c7319e3a072d118917957d6554Steve Block disable(); 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1542bde8e466a4451c7319e3a072d118917957d6554Steve Block 155e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::disable() 156e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 157e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_enabled) 158e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 159e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_enabled = false; 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block PageScriptDebugServer::shared().recompileAllJSFunctionsSoon(); 161e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_frontend) 162e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_frontend->profilerWasDisabled(); 163e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 164e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 165e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::enable(bool skipRecompile) 166e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 167e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_enabled) 168e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 169e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_enabled = true; 170e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!skipRecompile) 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block PageScriptDebugServer::shared().recompileAllJSFunctionsSoon(); 172e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_frontend) 173e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_frontend->profilerWasEnabled(); 174e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 175e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 176e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockString InspectorProfilerAgent::getCurrentUserInitiatedProfileName(bool incrementProfileNumber) 177e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 178e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (incrementProfileNumber) 179e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++; 180e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return makeString(UserInitiatedProfileName, '.', String::number(m_currentUserInitiatedProfileNumber)); 182e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 183e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 18481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorProfilerAgent::getProfileHeaders(ErrorString*, RefPtr<InspectorArray>* headers) 185e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 186e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ProfilesMap::iterator profilesEnd = m_profiles.end(); 187e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it) 188e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block (*headers)->pushObject(createProfileHeader(*it->second)); 1895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen HeapSnapshotsMap::iterator snapshotsEnd = m_snapshots.end(); 1905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen for (HeapSnapshotsMap::iterator it = m_snapshots.begin(); it != snapshotsEnd; ++it) 1915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen (*headers)->pushObject(createSnapshotHeader(*it->second)); 1925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 194f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochnamespace { 195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochclass OutputStream : public ScriptHeapSnapshot::OutputStream { 197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochpublic: 1982bde8e466a4451c7319e3a072d118917957d6554Steve Block OutputStream(InspectorFrontend::Profiler* frontend, unsigned uid) 199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch : m_frontend(frontend), m_uid(uid) { } 200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void Write(const String& chunk) { m_frontend->addHeapSnapshotChunk(m_uid, chunk); } 201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void Close() { m_frontend->finishHeapSnapshot(m_uid); } 202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochprivate: 20381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch InspectorFrontend::Profiler* m_frontend; 2042bde8e466a4451c7319e3a072d118917957d6554Steve Block int m_uid; 205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}; 206f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 207f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} // namespace 208f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 20981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorProfilerAgent::getProfile(ErrorString*, const String& type, unsigned uid, RefPtr<InspectorObject>* profileObject) 2105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 2115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (type == CPUProfileType) { 2125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen ProfilesMap::iterator it = m_profiles.find(uid); 2135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (it != m_profiles.end()) { 2145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *profileObject = createProfileHeader(*it->second); 2155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead()); 2165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 2175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } else if (type == HeapProfileType) { 2185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen HeapSnapshotsMap::iterator it = m_snapshots.find(uid); 2195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (it != m_snapshots.end()) { 220f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RefPtr<ScriptHeapSnapshot> snapshot = it->second; 221f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch *profileObject = createSnapshotHeader(*snapshot); 222f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_frontend) { 223f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch OutputStream stream(m_frontend, uid); 224f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch snapshot->writeJSON(&stream); 225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 2265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 227e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 228e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 229e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 23081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorProfilerAgent::removeProfile(ErrorString*, const String& type, unsigned uid) 231e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 2325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (type == CPUProfileType) { 2335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (m_profiles.contains(uid)) 2345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_profiles.remove(uid); 2355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } else if (type == HeapProfileType) { 2365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (m_snapshots.contains(uid)) 2375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_snapshots.remove(uid); 2385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 239e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 240e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 241e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::resetState() 242e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 2432bde8e466a4451c7319e3a072d118917957d6554Steve Block stopUserInitiatedProfiling(); 244e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_profiles.clear(); 2455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_snapshots.clear(); 246e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentUserInitiatedProfileNumber = 1; 247e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_nextUserInitiatedProfileNumber = 1; 2485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_nextUserInitiatedHeapSnapshotNumber = 1; 249ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch resetFrontendProfiles(); 250ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 251ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 252ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid InspectorProfilerAgent::resetFrontendProfiles() 253ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 2542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_frontend 2552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block && m_profiles.begin() == m_profiles.end() 2562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block && m_snapshots.begin() == m_snapshots.end()) 257f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_frontend->resetProfiles(); 258e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 259e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 2602bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::setFrontend(InspectorFrontend* frontend) 2612bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2622bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend = frontend->profiler(); 2632bde8e466a4451c7319e3a072d118917957d6554Steve Block restoreEnablement(); 2642bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2652bde8e466a4451c7319e3a072d118917957d6554Steve Block 2662bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::clearFrontend() 2672bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2682bde8e466a4451c7319e3a072d118917957d6554Steve Block m_frontend = 0; 2692bde8e466a4451c7319e3a072d118917957d6554Steve Block stopUserInitiatedProfiling(); 2702bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2712bde8e466a4451c7319e3a072d118917957d6554Steve Block 2722bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::restore() 2732bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2742bde8e466a4451c7319e3a072d118917957d6554Steve Block // Need to restore enablement state here as in setFrontend m_inspectorState wasn't loaded yet. 2752bde8e466a4451c7319e3a072d118917957d6554Steve Block restoreEnablement(); 2762bde8e466a4451c7319e3a072d118917957d6554Steve Block 2772bde8e466a4451c7319e3a072d118917957d6554Steve Block // Revisit this. 2782bde8e466a4451c7319e3a072d118917957d6554Steve Block resetFrontendProfiles(); 2792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_inspectorState->getBoolean(ProfilerAgentState::userInitiatedProfiling)) 2802bde8e466a4451c7319e3a072d118917957d6554Steve Block startUserInitiatedProfiling(); 2812bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2822bde8e466a4451c7319e3a072d118917957d6554Steve Block 2832bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorProfilerAgent::restoreEnablement() 2842bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2852bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_inspectorState->getBoolean(ProfilerAgentState::profilerEnabled)) { 2862bde8e466a4451c7319e3a072d118917957d6554Steve Block ErrorString error; 2872bde8e466a4451c7319e3a072d118917957d6554Steve Block enable(&error); 2882bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2892bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2902bde8e466a4451c7319e3a072d118917957d6554Steve Block 291e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::startUserInitiatedProfiling() 292e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 29328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (m_recordingUserInitiatedProfile) 29428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return; 295e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!enabled()) { 2962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block enable(true); 2972bde8e466a4451c7319e3a072d118917957d6554Steve Block PageScriptDebugServer::shared().recompileAllJSFunctions(0); 298e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 299e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_recordingUserInitiatedProfile = true; 300e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block String title = getCurrentUserInitiatedProfileName(true); 301e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if USE(JSC) 30281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec(); 303e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#else 304e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ScriptState* scriptState = 0; 305e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif 306e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ScriptProfiler::start(scriptState, title); 307e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block addStartProfilingMessageToConsole(title, 0, String()); 308e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block toggleRecordButton(true); 3092bde8e466a4451c7319e3a072d118917957d6554Steve Block m_inspectorState->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); 310e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 311e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 31228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid InspectorProfilerAgent::stopUserInitiatedProfiling(bool ignoreProfile) 313e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 31428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!m_recordingUserInitiatedProfile) 31528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu return; 316e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_recordingUserInitiatedProfile = false; 317e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block String title = getCurrentUserInitiatedProfileName(); 318e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if USE(JSC) 31981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec(); 320e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#else 321e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Use null script state to avoid filtering by context security token. 322e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // All functions from all iframes should be visible from Inspector UI. 323e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ScriptState* scriptState = 0; 324e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif 325e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title); 32628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (profile) { 32728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!ignoreProfile) 32828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu addProfile(profile, 0, String()); 32928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu else 33028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu addProfileFinishedMessageToConsole(profile, 0, String()); 33128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu } 332e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block toggleRecordButton(false); 3332bde8e466a4451c7319e3a072d118917957d6554Steve Block m_inspectorState->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); 334e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 335e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 3362fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknamespace { 3372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3382fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockclass HeapSnapshotProgress: public ScriptProfiler::HeapSnapshotProgress { 3392fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockpublic: 34081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch explicit HeapSnapshotProgress(InspectorFrontend::Profiler* frontend) 3412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block : m_frontend(frontend) { } 3422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void Start(int totalWork) 3432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { 3442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_totalWork = totalWork; 3452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 3462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void Worked(int workDone) 3472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { 3482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_frontend) 3492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork); 3502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 3512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void Done() { } 3522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool isCanceled() { return false; } 3532fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockprivate: 35481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch InspectorFrontend::Profiler* m_frontend; 3552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int m_totalWork; 3562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 3572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 3592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 36081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorProfilerAgent::takeHeapSnapshot(ErrorString*, bool detailed) 3615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 362a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch String title = makeString(UserInitiatedProfileName, '.', String::number(m_nextUserInitiatedHeapSnapshotNumber)); 363a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++m_nextUserInitiatedHeapSnapshotNumber; 364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block HeapSnapshotProgress progress(m_frontend); 3662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title, detailed ? &progress : 0); 3675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (snapshot) { 3685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_snapshots.add(snapshot->uid(), snapshot); 3695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (m_frontend) 3705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_frontend->addProfileHeader(createSnapshotHeader(*snapshot)); 3715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 3725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 3735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 374e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid InspectorProfilerAgent::toggleRecordButton(bool isProfiling) 375e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 376e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_frontend) 377e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_frontend->setRecordingProfile(isProfiling); 378e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 379e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 380e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} // namespace WebCore 381e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 3824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR) 383