summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-01 23:20:20 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-01 23:20:20 +0000
commit33047f18fb4d05e45a6a28e706a605ddccc591f6 (patch)
treefc79c483b777007677dcbdb843f300e602277978 /content/browser
parentb05df6b03e0d5dc552a96578ea6a8a7e47af407c (diff)
downloadchromium_src-33047f18fb4d05e45a6a28e706a605ddccc591f6.zip
chromium_src-33047f18fb4d05e45a6a28e706a605ddccc591f6.tar.gz
chromium_src-33047f18fb4d05e45a6a28e706a605ddccc591f6.tar.bz2
Collect profiler stats from all browser child processes.
R=jar Bug=104770 TEST=about:profiler after lauching a plug-in or GPU should show tracking data for plugin-gpu processes Review URL: http://codereview.chromium.org/8588023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112571 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/browser_child_process_host.cc2
-rwxr-xr-xcontent/browser/profiler_controller_impl.cc149
-rwxr-xr-xcontent/browser/profiler_controller_impl.h56
-rwxr-xr-xcontent/browser/profiler_message_filter.cc46
-rwxr-xr-xcontent/browser/profiler_message_filter.h38
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc6
6 files changed, 297 insertions, 0 deletions
diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc
index 35ed45c..09b77ee 100644
--- a/content/browser/browser_child_process_host.cc
+++ b/content/browser/browser_child_process_host.cc
@@ -13,6 +13,7 @@
#include "base/process_util.h"
#include "base/stl_util.h"
#include "base/string_util.h"
+#include "content/browser/profiler_message_filter.h"
#include "content/browser/renderer_host/resource_message_filter.h"
#include "content/browser/trace_message_filter.h"
#include "content/common/plugin_messages.h"
@@ -68,6 +69,7 @@ BrowserChildProcessHost::BrowserChildProcessHost(
#endif
disconnect_was_alive_(false) {
AddFilter(new TraceMessageFilter);
+ AddFilter(new ProfilerMessageFilter);
g_child_process_list.Get().push_back(this);
}
diff --git a/content/browser/profiler_controller_impl.cc b/content/browser/profiler_controller_impl.cc
new file mode 100755
index 0000000..3bfb12a
--- /dev/null
+++ b/content/browser/profiler_controller_impl.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/profiler_controller_impl.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "content/browser/browser_child_process_host.h"
+#include "content/common/child_process_info.h"
+#include "content/common/child_process_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/profiler_subscriber.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/process_type.h"
+
+using content::BrowserThread;
+
+namespace content {
+
+content::ProfilerController* content::ProfilerController::GetInstance() {
+ return ProfilerControllerImpl::GetInstance();
+}
+
+ProfilerControllerImpl* ProfilerControllerImpl::GetInstance() {
+ return Singleton<ProfilerControllerImpl>::get();
+}
+
+ProfilerControllerImpl::ProfilerControllerImpl() : subscriber_(NULL) {
+}
+
+ProfilerControllerImpl::~ProfilerControllerImpl() {
+}
+
+void ProfilerControllerImpl::OnPendingProcesses(int sequence_number,
+ int pending_processes,
+ bool end) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (subscriber_)
+ subscriber_->OnPendingProcesses(sequence_number, pending_processes, end);
+}
+
+void ProfilerControllerImpl::OnProfilerDataCollected(
+ int sequence_number,
+ base::DictionaryValue* profiler_data) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&ProfilerControllerImpl::OnProfilerDataCollected,
+ base::Unretained(this),
+ sequence_number,
+ profiler_data));
+ return;
+ }
+
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (subscriber_)
+ subscriber_->OnProfilerDataCollected(sequence_number, profiler_data);
+}
+
+void ProfilerControllerImpl::Register(ProfilerSubscriber* subscriber) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!subscriber_);
+ subscriber_ = subscriber;
+}
+
+void ProfilerControllerImpl::Unregister(ProfilerSubscriber* subscriber) {
+ if (subscriber == subscriber_)
+ subscriber_ = NULL;
+}
+
+void ProfilerControllerImpl::GetProfilerDataFromChildProcesses(
+ int sequence_number) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ int pending_processes = 0;
+ for (BrowserChildProcessHost::Iterator child_process_host;
+ !child_process_host.Done(); ++child_process_host) {
+ const std::string process_type =
+ content::GetProcessTypeNameInEnglish(child_process_host->type());
+ ++pending_processes;
+ if (!child_process_host->Send(new ChildProcessMsg_GetChildProfilerData(
+ sequence_number, process_type))) {
+ --pending_processes;
+ }
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(
+ &ProfilerControllerImpl::OnPendingProcesses,
+ base::Unretained(this),
+ sequence_number,
+ pending_processes,
+ true));
+}
+
+void ProfilerControllerImpl::GetProfilerData(int sequence_number) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ int pending_processes = 0;
+ const std::string render_process_type =
+ content::GetProcessTypeNameInEnglish(content::PROCESS_TYPE_RENDERER);
+
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ ++pending_processes;
+ if (!it.GetCurrentValue()->Send(new ChildProcessMsg_GetChildProfilerData(
+ sequence_number, render_process_type))) {
+ --pending_processes;
+ }
+ }
+ OnPendingProcesses(sequence_number, pending_processes, false);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ProfilerControllerImpl::GetProfilerDataFromChildProcesses,
+ base::Unretained(this),
+ sequence_number));
+}
+
+void ProfilerControllerImpl::SetProfilerStatusInChildProcesses(bool enable) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ for (BrowserChildProcessHost::Iterator child_process_host;
+ !child_process_host.Done(); ++child_process_host) {
+ child_process_host->Send(new ChildProcessMsg_SetProfilerStatus(enable));
+ }
+}
+
+void ProfilerControllerImpl::SetProfilerStatus(bool enable) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ProfilerControllerImpl::SetProfilerStatusInChildProcesses,
+ base::Unretained(this),
+ enable));
+
+ for (content::RenderProcessHost::iterator it(
+ content::RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ it.GetCurrentValue()->Send(new ChildProcessMsg_SetProfilerStatus(enable));
+ }
+}
+} // namespace content
diff --git a/content/browser/profiler_controller_impl.h b/content/browser/profiler_controller_impl.h
new file mode 100755
index 0000000..eca522a
--- /dev/null
+++ b/content/browser/profiler_controller_impl.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_PROFILER_CONTROLLER_IMPL_H_
+#define CONTENT_BROWSER_PROFILER_CONTROLLER_IMPL_H_
+
+#include "base/memory/singleton.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/profiler_controller.h"
+
+namespace content {
+
+// ProfilerController's implementation.
+class CONTENT_EXPORT ProfilerControllerImpl : public ProfilerController {
+ public:
+ static ProfilerControllerImpl* GetInstance();
+
+ // Normally instantiated when the child process is launched. Only one instance
+ // should be created per process.
+ ProfilerControllerImpl();
+ virtual ~ProfilerControllerImpl();
+
+ // Send number of pending processes to subscriber_. |end| is set to true if it
+ // is the last time. This is called on UI thread.
+ void OnPendingProcesses(int sequence_number, int pending_processes, bool end);
+
+ // Send profiler_data back to subscriber_. subscriber_ assumes the ownership
+ // of profiler_data. This is called on UI thread.
+ void OnProfilerDataCollected(int sequence_number,
+ base::DictionaryValue* profiler_data);
+
+ // ProfilerController implementation:
+ virtual void Register(ProfilerSubscriber* subscriber) OVERRIDE;
+ virtual void Unregister(ProfilerSubscriber* subscriber) OVERRIDE;
+ virtual void GetProfilerData(int sequence_number) OVERRIDE;
+ virtual void SetProfilerStatus(bool enable) OVERRIDE;
+
+ private:
+ friend struct DefaultSingletonTraits<ProfilerControllerImpl>;
+
+ // Contact child processes and get their profiler data.
+ void GetProfilerDataFromChildProcesses(int sequence_number);
+
+ // Contact child processes and set profiler status to |enable|.
+ void SetProfilerStatusInChildProcesses(bool enable);
+
+ ProfilerSubscriber* subscriber_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfilerControllerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_PROFILER_CONTROLLER_IMPL_H_
+
diff --git a/content/browser/profiler_message_filter.cc b/content/browser/profiler_message_filter.cc
new file mode 100755
index 0000000..f11b670
--- /dev/null
+++ b/content/browser/profiler_message_filter.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/profiler_message_filter.h"
+
+#include "base/tracked_objects.h"
+#include "base/values.h"
+#include "content/browser/profiler_controller_impl.h"
+#include "content/common/child_process_messages.h"
+
+using content::BrowserThread;
+
+ProfilerMessageFilter::ProfilerMessageFilter() {
+}
+
+ProfilerMessageFilter::~ProfilerMessageFilter() {
+}
+
+void ProfilerMessageFilter::OnChannelConnected(int32 peer_pid) {
+ BrowserMessageFilter::OnChannelConnected(peer_pid);
+
+ bool enable = tracked_objects::ThreadData::tracking_status();
+ Send(new ChildProcessMsg_SetProfilerStatus(enable));
+}
+
+bool ProfilerMessageFilter::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(ProfilerMessageFilter, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ChildProfilerData,
+ OnChildProfilerData)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+ return handled;
+}
+
+void ProfilerMessageFilter::OnChildProfilerData(
+ int sequence_number,
+ const base::DictionaryValue& profiler_data) {
+ base::DictionaryValue* dictionary_value = new base::DictionaryValue;
+ dictionary_value->MergeDictionary(&profiler_data);
+ // OnProfilerDataCollected assumes the ownership of profiler_data.
+ content::ProfilerControllerImpl::GetInstance()->OnProfilerDataCollected(
+ sequence_number, dictionary_value);
+}
diff --git a/content/browser/profiler_message_filter.h b/content/browser/profiler_message_filter.h
new file mode 100755
index 0000000..3790527
--- /dev/null
+++ b/content/browser/profiler_message_filter.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_PROFILER_MESSAGE_FILTER_H_
+#define CONTENT_BROWSER_PROFILER_MESSAGE_FILTER_H_
+
+#include <string>
+
+#include "content/browser/browser_message_filter.h"
+
+namespace base {
+class DictionaryValue;
+}
+
+// This class sends and receives profiler messages in the browser process.
+class ProfilerMessageFilter : public BrowserMessageFilter {
+ public:
+ ProfilerMessageFilter();
+ virtual ~ProfilerMessageFilter();
+
+ // BrowserMessageFilter implementation.
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+
+ // BrowserMessageFilter implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) OVERRIDE;
+
+ private:
+ // Message handlers.
+ void OnChildProfilerData(int sequence_number,
+ const base::DictionaryValue& profiler_data);
+
+ DISALLOW_COPY_AND_ASSIGN(ProfilerMessageFilter);
+};
+
+#endif // CONTENT_BROWSER_PROFILER_MESSAGE_FILTER_H_
+
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index d65edbd..31f2bf7 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -33,6 +33,7 @@
#include "base/sys_info.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
+#include "base/tracked_objects.h"
#include "content/browser/appcache/appcache_dispatcher_host.h"
#include "content/browser/browser_child_process_host.h"
#include "content/browser/browser_context.h"
@@ -48,6 +49,7 @@
#include "content/browser/in_process_webkit/indexed_db_dispatcher_host.h"
#include "content/browser/mime_registry_message_filter.h"
#include "content/browser/plugin_service.h"
+#include "content/browser/profiler_message_filter.h"
#include "content/browser/renderer_host/blob_message_filter.h"
#include "content/browser/renderer_host/clipboard_message_filter.h"
#include "content/browser/renderer_host/database_message_filter.h"
@@ -537,6 +539,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
GetID(), GetBrowserContext()->GetQuotaManager(),
content::GetContentClient()->browser()->CreateQuotaPermissionContext()));
channel_->AddFilter(new GamepadBrowserMessageFilter);
+ channel_->AddFilter(new ProfilerMessageFilter());
}
int RenderProcessHostImpl::GetNextRoutingID() {
@@ -941,6 +944,9 @@ void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
IPC::Logging::GetInstance()->Enabled()));
#endif
+ bool enable = tracked_objects::ThreadData::tracking_status();
+ Send(new ChildProcessMsg_SetProfilerStatus(enable));
+
// Make sure the child checks with us before exiting, so that we do not try
// to schedule a new navigation in a swapped out and exiting renderer.
Send(new ChildProcessMsg_AskBeforeShutdown());