Commit f8ad6e3e authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

Reland "Encapsulate Chrome thread profiling setup into a single class"

This is a reland of aa63fc1d.

Original change's description:
> Encapsulate Chrome thread profiling setup into a single class
>
> Creates a simple abstraction around the fairly complex profiling setup.
> This CL switches over the GPU and renderer process usage to this class.
> The browser process usage will be converted to use this class after it
> is extended to support periodic profiling (in a follow-on CL).
>
> Bug: 808588
> Change-Id: I6195571bf3ddd08291f288f475569bd9a88795ef
> Reviewed-on: https://chromium-review.googlesource.com/905451
> Reviewed-by: Scott Violet <sky@chromium.org>
> Reviewed-by: Alexei Svitkine <asvitkine@chromium.org>
> Commit-Queue: Mike Wittman <wittman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#535125}

TBR=sky

Bug: 808588
Change-Id: I34f1910116c4e7a500e353c27b85bf7534be43c7
Reviewed-on: https://chromium-review.googlesource.com/907508Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#535170}
parent 618456e7
...@@ -179,6 +179,8 @@ static_library("common") { ...@@ -179,6 +179,8 @@ static_library("common") {
"ssl_insecure_content.h", "ssl_insecure_content.h",
"stack_sampling_configuration.cc", "stack_sampling_configuration.cc",
"stack_sampling_configuration.h", "stack_sampling_configuration.h",
"thread_profiler.cc",
"thread_profiler.h",
"trace_event_args_whitelist.cc", "trace_event_args_whitelist.cc",
"trace_event_args_whitelist.h", "trace_event_args_whitelist.h",
"tts_messages.h", "tts_messages.h",
...@@ -279,6 +281,10 @@ static_library("common") { ...@@ -279,6 +281,10 @@ static_library("common") {
"//url", "//url",
] ]
deps = [
"//components/metrics:child_call_stacks",
]
if (enable_plugins) { if (enable_plugins) {
public_deps += [ "//ppapi/shared_impl" ] public_deps += [ "//ppapi/shared_impl" ]
} }
...@@ -431,7 +437,7 @@ static_library("common") { ...@@ -431,7 +437,7 @@ static_library("common") {
} }
if (is_win) { if (is_win) {
deps = [ deps += [
"//chrome/common/win:eventlog_messages", "//chrome/common/win:eventlog_messages",
"//chrome_elf:chrome_elf_main_include", "//chrome_elf:chrome_elf_main_include",
"//components/crash/content/app:crash_export_thunk_include", "//components/crash/content/app:crash_export_thunk_include",
...@@ -485,9 +491,7 @@ static_library("common") { ...@@ -485,9 +491,7 @@ static_library("common") {
} }
if (is_linux) { if (is_linux) {
deps = [ deps += [ "//sandbox/linux:sandbox_services" ]
"//sandbox/linux:sandbox_services",
]
} }
if (enable_cdm_host_verification) { if (enable_cdm_host_verification) {
......
...@@ -19,6 +19,9 @@ include_rules = [ ...@@ -19,6 +19,9 @@ include_rules = [
"+components/favicon_base", "+components/favicon_base",
"+components/flags_ui/flags_ui_switches.h", "+components/flags_ui/flags_ui_switches.h",
"+components/gcm_driver", "+components/gcm_driver",
"+components/metrics/call_stack_profile_metrics_provider.h",
"+components/metrics/call_stack_profile_params.h",
"+components/metrics/child_call_stack_profile_collector.h",
"+components/metrics/client_info.h", "+components/metrics/client_info.h",
"+components/metrics/metrics_pref_names.h", "+components/metrics/metrics_pref_names.h",
"+components/nacl/common", "+components/nacl/common",
...@@ -46,6 +49,7 @@ include_rules = [ ...@@ -46,6 +49,7 @@ include_rules = [
"+rlz/features/features.h", "+rlz/features/features.h",
"+sandbox/linux/services/credentials.h", "+sandbox/linux/services/credentials.h",
"+services/network/public/cpp", "+services/network/public/cpp",
"+services/service_manager/public",
"+services/service_manager/sandbox", "+services/service_manager/sandbox",
"+third_party/boringssl/src/include", "+third_party/boringssl/src/include",
"+third_party/WebKit/public/platform/web_client_hints_types.mojom.h", "+third_party/WebKit/public/platform/web_client_hints_types.mojom.h",
......
// Copyright 2018 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 "chrome/common/thread_profiler.h"
#include <string>
#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/threading/platform_thread.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "chrome/common/stack_sampling_configuration.h"
#include "components/metrics/call_stack_profile_metrics_provider.h"
#include "components/metrics/call_stack_profile_params.h"
#include "components/metrics/child_call_stack_profile_collector.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
namespace {
// Only used by child processes.
base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky
g_child_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER;
// The profiler object is stored in a SequenceLocalStorageSlot on child threads
// to give it the same lifetime as the threads.
base::LazyInstance<
base::SequenceLocalStorageSlot<std::unique_ptr<ThreadProfiler>>>::Leaky
g_child_thread_profiler_sequence_local_storage = LAZY_INSTANCE_INITIALIZER;
base::StackSamplingProfiler::SamplingParams GetSamplingParams() {
base::StackSamplingProfiler::SamplingParams params;
params.initial_delay = base::TimeDelta::FromMilliseconds(0);
params.bursts = 1;
params.samples_per_burst = 300;
params.sampling_interval = base::TimeDelta::FromMilliseconds(100);
return params;
}
metrics::CallStackProfileParams::Process GetProcess() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty())
return metrics::CallStackProfileParams::BROWSER_PROCESS;
if (process_type == switches::kRendererProcess)
return metrics::CallStackProfileParams::RENDERER_PROCESS;
if (process_type == switches::kGpuProcess)
return metrics::CallStackProfileParams::GPU_PROCESS;
if (process_type == switches::kUtilityProcess)
return metrics::CallStackProfileParams::UTILITY_PROCESS;
if (process_type == switches::kZygoteProcess)
return metrics::CallStackProfileParams::ZYGOTE_PROCESS;
if (process_type == switches::kPpapiPluginProcess)
return metrics::CallStackProfileParams::PPAPI_PLUGIN_PROCESS;
if (process_type == switches::kPpapiBrokerProcess)
return metrics::CallStackProfileParams::PPAPI_BROKER_PROCESS;
return metrics::CallStackProfileParams::UNKNOWN_PROCESS;
}
} // namespace
ThreadProfiler::~ThreadProfiler() {}
// static
std::unique_ptr<ThreadProfiler> ThreadProfiler::CreateAndStartOnMainThread(
metrics::CallStackProfileParams::Thread thread) {
return std::unique_ptr<ThreadProfiler>(new ThreadProfiler(thread));
}
// static
void ThreadProfiler::StartOnChildThread(
metrics::CallStackProfileParams::Thread thread) {
auto profiler = std::unique_ptr<ThreadProfiler>(new ThreadProfiler(thread));
g_child_thread_profiler_sequence_local_storage.Get().Set(std::move(profiler));
}
void ThreadProfiler::SetServiceManagerConnectorForChildProcess(
service_manager::Connector* connector) {
DCHECK_NE(metrics::CallStackProfileParams::BROWSER_PROCESS, GetProcess());
metrics::mojom::CallStackProfileCollectorPtr browser_interface;
connector->BindInterface(content::mojom::kBrowserServiceName,
&browser_interface);
g_child_call_stack_profile_collector.Get().SetParentProfileCollector(
std::move(browser_interface));
}
ThreadProfiler::ThreadProfiler(metrics::CallStackProfileParams::Thread thread)
: startup_profile_params_(GetProcess(),
thread,
metrics::CallStackProfileParams::PROCESS_STARTUP,
metrics::CallStackProfileParams::MAY_SHUFFLE) {
if (!StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess())
return;
startup_profiler_ = std::make_unique<base::StackSamplingProfiler>(
base::PlatformThread::CurrentId(), GetSamplingParams(),
BindRepeating(&ThreadProfiler::ReceiveStartupProfiles,
GetReceiverCallback(&startup_profile_params_)));
startup_profiler_->Start();
}
base::StackSamplingProfiler::CompletedCallback
ThreadProfiler::GetReceiverCallback(
metrics::CallStackProfileParams* profile_params) {
profile_params->start_timestamp = base::TimeTicks::Now();
// TODO(wittman): Simplify the approach to getting the profiler callback
// across CallStackProfileMetricsProvider and
// ChildCallStackProfileCollector. Ultimately both should expose functions
// like
//
// void ReceiveCompletedProfiles(
// const metrics::CallStackProfileParams& profile_params,
// base::TimeTicks profile_start_time,
// base::StackSamplingProfiler::CallStackProfiles profiles);
//
// and this function should bind the passed profile_params and
// base::TimeTicks::Now() to those functions.
if (GetProcess() == metrics::CallStackProfileParams::BROWSER_PROCESS) {
return metrics::CallStackProfileMetricsProvider::
GetProfilerCallbackForBrowserProcess(profile_params);
}
return g_child_call_stack_profile_collector.Get()
.ChildCallStackProfileCollector::GetProfilerCallback(*profile_params);
}
// static
base::Optional<base::StackSamplingProfiler::SamplingParams>
ThreadProfiler::ReceiveStartupProfiles(
const base::StackSamplingProfiler::CompletedCallback& receiver_callback,
base::StackSamplingProfiler::CallStackProfiles profiles) {
receiver_callback.Run(std::move(profiles));
return base::Optional<base::StackSamplingProfiler::SamplingParams>();
}
// Copyright 2018 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 CHROME_COMMON_THREAD_PROFILER_H_
#define CHROME_COMMON_THREAD_PROFILER_H_
#include <memory>
#include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/single_thread_task_runner.h"
#include "components/metrics/call_stack_profile_params.h"
namespace service_manager {
class Connector;
}
// ThreadProfiler performs startup and periodic profiling of Chrome
// threads.
class ThreadProfiler {
public:
~ThreadProfiler();
// Creates a profiler for a main thread and immediately starts it. This
// function should only be used when profiling the main thread of a
// process. The returned profiler must be destroyed prior to thread exit to
// stop the profiling. SetMainThreadTaskRunner() should be called after the
// message loop has been started on the thread.
static std::unique_ptr<ThreadProfiler> CreateAndStartOnMainThread(
metrics::CallStackProfileParams::Thread thread);
// Creates a profiler for a child thread and immediately starts it. This
// should be called from a task posted on the child thread immediately after
// thread start. The thread will be profiled until exit.
static void StartOnChildThread(
metrics::CallStackProfileParams::Thread thread);
// This function must be called within child processes to supply the Service
// Manager's connector, to bind the interface through which profiles are sent
// back to the browser process.
//
// Note that the metrics::CallStackProfileCollector interface also must be
// exposed to the child process, and metrics::mojom::CallStackProfileCollector
// declared in chrome_content_browser_manifest_overlay.json, for the binding
// to succeed.
static void SetServiceManagerConnectorForChildProcess(
service_manager::Connector* connector);
private:
// Creates the profiler.
explicit ThreadProfiler(metrics::CallStackProfileParams::Thread thread);
// Gets the completed callback for the ultimate receiver of the profiles.
base::StackSamplingProfiler::CompletedCallback GetReceiverCallback(
metrics::CallStackProfileParams* profile_params);
// Receives |profiles| from the StackSamplingProfiler and forwards them on to
// the original |receiver_callback|. Note that we must obtain and bind the
// original receiver callback prior to the start of collection because the
// collection start time is currently recorded when obtaining the callback in
// some collection scenarios. The implementation contains a TODO to fix this.
static base::Optional<base::StackSamplingProfiler::SamplingParams>
ReceiveStartupProfiles(
const base::StackSamplingProfiler::CompletedCallback& receiver_callback,
base::StackSamplingProfiler::CallStackProfiles profiles);
// TODO(wittman): Make const after cleaning up the existing continuous
// collection support.
metrics::CallStackProfileParams startup_profile_params_;
std::unique_ptr<base::StackSamplingProfiler> startup_profiler_;
DISALLOW_COPY_AND_ASSIGN(ThreadProfiler);
};
#endif // CHROME_COMMON_THREAD_PROFILER_H_
...@@ -4,20 +4,12 @@ ...@@ -4,20 +4,12 @@
#include "chrome/gpu/chrome_content_gpu_client.h" #include "chrome/gpu/chrome_content_gpu_client.h"
#include <string>
#include <utility> #include <utility>
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/threading/platform_thread.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/common/stack_sampling_configuration.h"
#include "components/metrics/child_call_stack_profile_collector.h"
#include "content/public/child/child_thread.h" #include "content/public/child/child_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/connector.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS) #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_paths.h" #include "media/cdm/cdm_paths.h"
...@@ -35,53 +27,9 @@ ...@@ -35,53 +27,9 @@
#include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_factory_ozone.h"
#endif #endif
namespace {
base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky
g_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER;
// The profiler object is stored in a SequenceLocalStorageSlot on the IO thread
// so that it will be destroyed when the IO thread stops.
base::LazyInstance<base::SequenceLocalStorageSlot<
std::unique_ptr<base::StackSamplingProfiler>>>::Leaky
io_thread_sampling_profiler = LAZY_INSTANCE_INITIALIZER;
// Starts to profile the IO thread.
void StartIOThreadProfiling() {
StackSamplingConfiguration* config = StackSamplingConfiguration::Get();
if (config->IsProfilerEnabledForCurrentProcess()) {
auto profiler = std::make_unique<base::StackSamplingProfiler>(
base::PlatformThread::CurrentId(),
config->GetSamplingParamsForCurrentProcess(),
g_call_stack_profile_collector.Get().GetProfilerCallback(
metrics::CallStackProfileParams(
metrics::CallStackProfileParams::GPU_PROCESS,
metrics::CallStackProfileParams::IO_THREAD,
metrics::CallStackProfileParams::PROCESS_STARTUP,
metrics::CallStackProfileParams::MAY_SHUFFLE)));
profiler->Start();
io_thread_sampling_profiler.Get().Set(std::move(profiler));
}
}
} // namespace
ChromeContentGpuClient::ChromeContentGpuClient() ChromeContentGpuClient::ChromeContentGpuClient()
: stack_sampling_profiler_( : main_thread_profiler_(ThreadProfiler::CreateAndStartOnMainThread(
base::PlatformThread::CurrentId(), metrics::CallStackProfileParams::GPU_MAIN_THREAD)) {
StackSamplingConfiguration::Get()
->GetSamplingParamsForCurrentProcess(),
g_call_stack_profile_collector.Get().GetProfilerCallback(
metrics::CallStackProfileParams(
metrics::CallStackProfileParams::GPU_PROCESS,
metrics::CallStackProfileParams::GPU_MAIN_THREAD,
metrics::CallStackProfileParams::PROCESS_STARTUP,
metrics::CallStackProfileParams::MAY_SHUFFLE))) {
if (StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess())
stack_sampling_profiler_.Start();
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
protected_buffer_manager_ = std::make_unique<arc::ProtectedBufferManager>(); protected_buffer_manager_ = std::make_unique<arc::ProtectedBufferManager>();
#endif #endif
...@@ -118,16 +66,15 @@ void ChromeContentGpuClient::GpuServiceInitialized( ...@@ -118,16 +66,15 @@ void ChromeContentGpuClient::GpuServiceInitialized(
base::Unretained(protected_buffer_manager_.get()))); base::Unretained(protected_buffer_manager_.get())));
#endif #endif
metrics::mojom::CallStackProfileCollectorPtr browser_interface; ThreadProfiler::SetServiceManagerConnectorForChildProcess(
content::ChildThread::Get()->GetConnector()->BindInterface( content::ChildThread::Get()->GetConnector());
content::mojom::kBrowserServiceName, &browser_interface);
g_call_stack_profile_collector.Get().SetParentProfileCollector(
std::move(browser_interface));
} }
void ChromeContentGpuClient::PostIOThreadCreated( void ChromeContentGpuClient::PostIOThreadCreated(
base::SingleThreadTaskRunner* io_task_runner) { base::SingleThreadTaskRunner* io_task_runner) {
io_task_runner->PostTask(FROM_HERE, base::BindOnce(&StartIOThreadProfiling)); io_task_runner->PostTask(
FROM_HERE, base::BindOnce(&ThreadProfiler::StartOnChildThread,
metrics::CallStackProfileParams::IO_THREAD));
} }
#if BUILDFLAG(ENABLE_LIBRARY_CDMS) #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
......
...@@ -6,10 +6,11 @@ ...@@ -6,10 +6,11 @@
#define CHROME_GPU_CHROME_CONTENT_GPU_CLIENT_H_ #define CHROME_GPU_CHROME_CONTENT_GPU_CLIENT_H_
#include <memory> #include <memory>
#include <string>
#include "base/macros.h" #include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "chrome/common/thread_profiler.h"
#include "content/public/gpu/content_gpu_client.h" #include "content/public/gpu/content_gpu_client.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -52,8 +53,8 @@ class ChromeContentGpuClient : public content::ContentGpuClient { ...@@ -52,8 +53,8 @@ class ChromeContentGpuClient : public content::ContentGpuClient {
::arc::mojom::ProtectedBufferManagerRequest request); ::arc::mojom::ProtectedBufferManagerRequest request);
#endif #endif
// Used to profile process startup. // Used to profile main thread startup.
base::StackSamplingProfiler stack_sampling_profiler_; std::unique_ptr<ThreadProfiler> main_thread_profiler_;
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
gpu::GpuPreferences gpu_preferences_; gpu::GpuPreferences gpu_preferences_;
......
...@@ -15,11 +15,9 @@ ...@@ -15,11 +15,9 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics_action.h" #include "base/metrics/user_metrics_action.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -40,7 +38,7 @@ ...@@ -40,7 +38,7 @@
#include "chrome/common/profiling/memlog_allocator_shim.h" #include "chrome/common/profiling/memlog_allocator_shim.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "chrome/common/secure_origin_whitelist.h" #include "chrome/common/secure_origin_whitelist.h"
#include "chrome/common/stack_sampling_configuration.h" #include "chrome/common/thread_profiler.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h" #include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
...@@ -80,7 +78,6 @@ ...@@ -80,7 +78,6 @@
#include "components/dom_distiller/core/url_constants.h" #include "components/dom_distiller/core/url_constants.h"
#include "components/error_page/common/error.h" #include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h" #include "components/error_page/common/localized_error.h"
#include "components/metrics/child_call_stack_profile_collector.h"
#include "components/network_hints/renderer/prescient_networking_dispatcher.h" #include "components/network_hints/renderer/prescient_networking_dispatcher.h"
#include "components/pdf/renderer/pepper_pdf_host.h" #include "components/pdf/renderer/pepper_pdf_host.h"
#include "components/safe_browsing/renderer/threat_dom_details.h" #include "components/safe_browsing/renderer/threat_dom_details.h"
...@@ -229,35 +226,6 @@ const char kFlashYouTubeRewriteUMA[] = "Plugin.Flash.YouTubeRewrite"; ...@@ -229,35 +226,6 @@ const char kFlashYouTubeRewriteUMA[] = "Plugin.Flash.YouTubeRewrite";
namespace { namespace {
base::LazyInstance<metrics::ChildCallStackProfileCollector>::Leaky
g_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER;
// The profiler object is stored in a SequenceLocalStorageSlot on the compositor
// thread so that it will be destroyed when the compositor thread stops.
base::LazyInstance<base::SequenceLocalStorageSlot<
std::unique_ptr<base::StackSamplingProfiler>>>::Leaky
g_compositor_thread_sampling_profiler = LAZY_INSTANCE_INITIALIZER;
// Starts to profile the compositor thread.
void StartCompositorThreadProfiling() {
StackSamplingConfiguration* config = StackSamplingConfiguration::Get();
if (!config->IsProfilerEnabledForCurrentProcess())
return;
auto profiler_callback =
g_call_stack_profile_collector.Get().GetProfilerCallback(
metrics::CallStackProfileParams(
metrics::CallStackProfileParams::RENDERER_PROCESS,
metrics::CallStackProfileParams::COMPOSITOR_THREAD,
metrics::CallStackProfileParams::PROCESS_STARTUP,
metrics::CallStackProfileParams::MAY_SHUFFLE));
auto profiler = std::make_unique<base::StackSamplingProfiler>(
base::PlatformThread::CurrentId(),
config->GetSamplingParamsForCurrentProcess(), profiler_callback);
profiler->Start();
g_compositor_thread_sampling_profiler.Get().Set(std::move(profiler));
}
void RecordYouTubeRewriteUMA(internal::YouTubeRewriteStatus status) { void RecordYouTubeRewriteUMA(internal::YouTubeRewriteStatus status) {
UMA_HISTOGRAM_ENUMERATION(internal::kFlashYouTubeRewriteUMA, status, UMA_HISTOGRAM_ENUMERATION(internal::kFlashYouTubeRewriteUMA, status,
internal::NUM_PLUGIN_ERROR); internal::NUM_PLUGIN_ERROR);
...@@ -1250,14 +1218,14 @@ void ChromeContentRendererClient::PostCompositorThreadCreated( ...@@ -1250,14 +1218,14 @@ void ChromeContentRendererClient::PostCompositorThreadCreated(
// Do not start the profiler for extension processes. // Do not start the profiler for extension processes.
if (IsStandaloneExtensionProcess()) if (IsStandaloneExtensionProcess())
return; return;
metrics::mojom::CallStackProfileCollectorPtr browser_interface;
content::ChildThread::Get()->GetConnector()->BindInterface( ThreadProfiler::SetServiceManagerConnectorForChildProcess(
content::mojom::kBrowserServiceName, &browser_interface); content::ChildThread::Get()->GetConnector());
g_call_stack_profile_collector.Get().SetParentProfileCollector(
std::move(browser_interface));
compositor_thread_task_runner->PostTask( compositor_thread_task_runner->PostTask(
FROM_HERE, base::BindOnce(&StartCompositorThreadProfiling)); FROM_HERE,
base::BindOnce(&ThreadProfiler::StartOnChildThread,
metrics::CallStackProfileParams::COMPOSITOR_THREAD));
} }
bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() { bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
......
...@@ -103,11 +103,11 @@ static_library("metrics") { ...@@ -103,11 +103,11 @@ static_library("metrics") {
] ]
public_deps = [ public_deps = [
":call_stack_profile_params",
"//third_party/metrics_proto", "//third_party/metrics_proto",
] ]
deps = [ deps = [
":call_stack_profile_params",
"//base", "//base",
"//base:base_static", "//base:base_static",
"//components/prefs", "//components/prefs",
......
...@@ -558,6 +558,12 @@ CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() { ...@@ -558,6 +558,12 @@ CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() {
CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() { CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() {
} }
StackSamplingProfiler::CompletedCallback
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
CallStackProfileParams* params) {
return internal::GetProfilerCallback(params);
}
StackSamplingProfiler::CompletedCallback CallStackProfileMetricsProvider:: StackSamplingProfiler::CompletedCallback CallStackProfileMetricsProvider::
GetProfilerCallbackForBrowserProcessUIThreadStartup() { GetProfilerCallbackForBrowserProcessUIThreadStartup() {
return internal::GetProfilerCallback(&g_ui_thread_sampling_params); return internal::GetProfilerCallback(&g_ui_thread_sampling_params);
......
...@@ -53,6 +53,12 @@ class CallStackProfileMetricsProvider : public MetricsProvider { ...@@ -53,6 +53,12 @@ class CallStackProfileMetricsProvider : public MetricsProvider {
CallStackProfileMetricsProvider(); CallStackProfileMetricsProvider();
~CallStackProfileMetricsProvider() override; ~CallStackProfileMetricsProvider() override;
// Returns a callback for use with StackSamplingProfiler that sets up
// parameters for general browser process sampling. The callback should be
// immediately passed to the StackSamplingProfiler, and should not be reused.
static base::StackSamplingProfiler::CompletedCallback
GetProfilerCallbackForBrowserProcess(CallStackProfileParams* params);
// Returns a callback for use with StackSamplingProfiler that sets up // Returns a callback for use with StackSamplingProfiler that sets up
// parameters for UI thread of browser process startup sampling. The callback // parameters for UI thread of browser process startup sampling. The callback
// should be immediately passed to the StackSamplingProfiler, and should not // should be immediately passed to the StackSamplingProfiler, and should not
......
...@@ -55,6 +55,8 @@ void ChildCallStackProfileCollector::SetParentProfileCollector( ...@@ -55,6 +55,8 @@ void ChildCallStackProfileCollector::SetParentProfileCollector(
DCHECK(retain_profiles_); DCHECK(retain_profiles_);
retain_profiles_ = false; retain_profiles_ = false;
task_runner_ = base::ThreadTaskRunnerHandle::Get(); task_runner_ = base::ThreadTaskRunnerHandle::Get();
// This should only be set one time per child process.
DCHECK(!parent_collector_);
parent_collector_ = std::move(parent_collector); parent_collector_ = std::move(parent_collector);
if (parent_collector_) { if (parent_collector_) {
for (ProfilesState& state : profiles_) { for (ProfilesState& state : profiles_) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment