Commit 106dd071 authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

Second reland of "Encapsulate Chrome thread profiling setup into a single class"

Fixes Android test failure by avoiding implicit creation of the render
thread. Also moves the decision on whether to profile extension processes into
the StackSamplingConfiguration, and cleans up comments.

This is a reland of f8ad6e3e.

Original change's description:
> 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/907508
> Reviewed-by: Mike Wittman <wittman@chromium.org>
> Commit-Queue: Mike Wittman <wittman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#535170}

Bug: 808588
Change-Id: Id34e6a3e57c144697413ecced43146bf3e6521e9
Reviewed-on: https://chromium-review.googlesource.com/917197
Commit-Queue: Mike Wittman <wittman@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537023}
parent 00128786
......@@ -177,6 +177,8 @@ static_library("common") {
"ssl_insecure_content.h",
"stack_sampling_configuration.cc",
"stack_sampling_configuration.h",
"thread_profiler.cc",
"thread_profiler.h",
"trace_event_args_whitelist.cc",
"trace_event_args_whitelist.h",
"tts_messages.h",
......@@ -277,6 +279,10 @@ static_library("common") {
"//url",
]
deps = [
"//components/metrics:child_call_stacks",
]
if (enable_plugins) {
public_deps += [ "//ppapi/shared_impl" ]
}
......@@ -430,7 +436,7 @@ static_library("common") {
}
if (is_win) {
deps = [
deps += [
"//chrome/common/win:eventlog_messages",
"//chrome_elf:chrome_elf_main_include",
"//components/crash/content/app:crash_export_thunk_include",
......@@ -484,9 +490,7 @@ static_library("common") {
}
if (is_linux) {
deps = [
"//sandbox/linux:sandbox_services",
]
deps += [ "//sandbox/linux:sandbox_services" ]
}
if (enable_cdm_host_verification) {
......
......@@ -19,6 +19,9 @@ include_rules = [
"+components/favicon_base",
"+components/flags_ui/flags_ui_switches.h",
"+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/metrics_pref_names.h",
"+components/nacl/common",
......@@ -46,6 +49,7 @@ include_rules = [
"+rlz/features/features.h",
"+sandbox/linux/services/credentials.h",
"+services/network/public/cpp",
"+services/service_manager/public",
"+services/service_manager/sandbox",
"+third_party/boringssl/src/include",
"+third_party/WebKit/public/platform/web_client_hints_types.mojom.h",
......
......@@ -12,11 +12,16 @@
#include "chrome/common/chrome_switches.h"
#include "components/version_info/version_info.h"
#include "content/public/common/content_switches.h"
#include "extensions/features/features.h"
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/switches.h"
#endif
namespace {
base::LazyInstance<StackSamplingConfiguration>::Leaky g_configuration =
......@@ -47,6 +52,15 @@ bool IsBrowserProcess() {
return process_type.empty();
}
// True if the command line corresponds to an extension renderer process.
bool IsExtensionRenderer(const base::CommandLine& command_line) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
return command_line.HasSwitch(extensions::switches::kExtensionProcess);
#else
return false;
#endif
}
bool ShouldEnableProfilerForNextRendererProcess() {
// Enable for every N-th renderer process, where N = 5.
return base::RandInt(0, 4) == 0;
......@@ -131,6 +145,9 @@ void StackSamplingConfiguration::AppendCommandLineSwitchForChildProcess(
return;
if (process_type == switches::kGpuProcess ||
(process_type == switches::kRendererProcess &&
// Do not start the profiler for extension processes since profiling the
// compositor thread in them is not useful.
!IsExtensionRenderer(*command_line) &&
ShouldEnableProfilerForNextRendererProcess())) {
command_line->AppendSwitch(switches::kStartStackProfiler);
}
......
......@@ -28,25 +28,6 @@ class StackSamplingConfiguration {
GetSamplingParamsForCurrentProcess() const;
// Returns true if the profiler should be started for the current process.
//
// This method must first be called from the main thread while the process is
// single-threaded. It is thereafter safe to call it concurrently from other
// threads.
//
// This method can be used via the following pattern:
// if
// (StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) {
// // start the profiler.
// }
//
// This method is currently called unsynchronized from two different threads
// (UI thread and IO thread). This is okay due to the following reasons.
//
// 1) The profile configuration (which is constant) is guaranteed to have
// already been created when this method is called from the IO thread, because
// of the access for the UI thread sampling.
//
// 2) The only other data accessed in this method is the command line.
bool IsProfilerEnabledForCurrentProcess() const;
// Get the synthetic field trial configuration. Returns true if a synthetic
......@@ -93,6 +74,9 @@ class StackSamplingConfiguration {
// Generates sampling profiler configurations for all processes.
static ProfileConfiguration GenerateConfiguration();
// NOTE: all state in this class must be const and initialized at construction
// time to ensure thread-safe access post-construction.
// In the browser process this represents the configuration to use across all
// Chrome processes. In the child processes it is always
// PROFILE_FROM_COMMAND_LINE.
......
// 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());
if (!StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess())
return;
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 @@
#include "chrome/gpu/chrome_content_gpu_client.h"
#include <string>
#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 "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/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/connector.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_paths.h"
......@@ -35,53 +27,9 @@
#include "ui/ozone/public/surface_factory_ozone.h"
#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()
: stack_sampling_profiler_(
base::PlatformThread::CurrentId(),
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();
: main_thread_profiler_(ThreadProfiler::CreateAndStartOnMainThread(
metrics::CallStackProfileParams::GPU_MAIN_THREAD)) {
#if defined(OS_CHROMEOS)
protected_buffer_manager_ = std::make_unique<arc::ProtectedBufferManager>();
#endif
......@@ -118,16 +66,15 @@ void ChromeContentGpuClient::GpuServiceInitialized(
base::Unretained(protected_buffer_manager_.get())));
#endif
metrics::mojom::CallStackProfileCollectorPtr browser_interface;
content::ChildThread::Get()->GetConnector()->BindInterface(
content::mojom::kBrowserServiceName, &browser_interface);
g_call_stack_profile_collector.Get().SetParentProfileCollector(
std::move(browser_interface));
ThreadProfiler::SetServiceManagerConnectorForChildProcess(
content::ChildThread::Get()->GetConnector());
}
void ChromeContentGpuClient::PostIOThreadCreated(
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)
......
......@@ -6,10 +6,11 @@
#define CHROME_GPU_CHROME_CONTENT_GPU_CLIENT_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/single_thread_task_runner.h"
#include "chrome/common/thread_profiler.h"
#include "content/public/gpu/content_gpu_client.h"
#if defined(OS_CHROMEOS)
......@@ -52,8 +53,8 @@ class ChromeContentGpuClient : public content::ContentGpuClient {
::arc::mojom::ProtectedBufferManagerRequest request);
#endif
// Used to profile process startup.
base::StackSamplingProfiler stack_sampling_profiler_;
// Used to profile main thread startup.
std::unique_ptr<ThreadProfiler> main_thread_profiler_;
#if defined(OS_CHROMEOS)
gpu::GpuPreferences gpu_preferences_;
......
......@@ -15,11 +15,9 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.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_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
......@@ -40,7 +38,7 @@
#include "chrome/common/profiling/memlog_allocator_shim.h"
#include "chrome/common/render_messages.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/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
......@@ -80,7 +78,6 @@
#include "components/dom_distiller/core/url_constants.h"
#include "components/error_page/common/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/pdf/renderer/pepper_pdf_host.h"
#include "components/safe_browsing/renderer/threat_dom_details.h"
......@@ -229,35 +226,6 @@ const char kFlashYouTubeRewriteUMA[] = "Plugin.Flash.YouTubeRewrite";
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) {
UMA_HISTOGRAM_ENUMERATION(internal::kFlashYouTubeRewriteUMA, status,
internal::NUM_PLUGIN_ERROR);
......@@ -533,6 +501,9 @@ void ChromeContentRendererClient::RenderThreadStarted() {
leak_detector_remote_client_.reset(new LeakDetectorRemoteClient());
thread->AddObserver(leak_detector_remote_client_.get());
#endif
ThreadProfiler::SetServiceManagerConnectorForChildProcess(
thread->GetConnector());
}
void ChromeContentRendererClient::RenderFrameCreated(
......@@ -1247,17 +1218,10 @@ void ChromeContentRendererClient::PrepareErrorPageInternal(
void ChromeContentRendererClient::PostCompositorThreadCreated(
base::SingleThreadTaskRunner* compositor_thread_task_runner) {
// Do not start the profiler for extension processes.
if (IsStandaloneExtensionProcess())
return;
metrics::mojom::CallStackProfileCollectorPtr browser_interface;
content::ChildThread::Get()->GetConnector()->BindInterface(
content::mojom::kBrowserServiceName, &browser_interface);
g_call_stack_profile_collector.Get().SetParentProfileCollector(
std::move(browser_interface));
compositor_thread_task_runner->PostTask(
FROM_HERE, base::BindOnce(&StartCompositorThreadProfiling));
FROM_HERE,
base::BindOnce(&ThreadProfiler::StartOnChildThread,
metrics::CallStackProfileParams::COMPOSITOR_THREAD));
}
bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
......
......@@ -103,11 +103,11 @@ static_library("metrics") {
]
public_deps = [
":call_stack_profile_params",
"//third_party/metrics_proto",
]
deps = [
":call_stack_profile_params",
"//base",
"//base:base_static",
"//components/prefs",
......
......@@ -558,6 +558,12 @@ CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() {
CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() {
}
StackSamplingProfiler::CompletedCallback
CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcess(
CallStackProfileParams* params) {
return internal::GetProfilerCallback(params);
}
StackSamplingProfiler::CompletedCallback CallStackProfileMetricsProvider::
GetProfilerCallbackForBrowserProcessUIThreadStartup() {
return internal::GetProfilerCallback(&g_ui_thread_sampling_params);
......
......@@ -53,6 +53,12 @@ class CallStackProfileMetricsProvider : public MetricsProvider {
CallStackProfileMetricsProvider();
~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
// parameters for UI thread of browser process startup sampling. The callback
// should be immediately passed to the StackSamplingProfiler, and should not
......
......@@ -55,6 +55,8 @@ void ChildCallStackProfileCollector::SetParentProfileCollector(
DCHECK(retain_profiles_);
retain_profiles_ = false;
task_runner_ = base::ThreadTaskRunnerHandle::Get();
// This should only be set one time per child process.
DCHECK(!parent_collector_);
parent_collector_ = std::move(parent_collector);
if (parent_collector_) {
for (ProfilesState& state : profiles_) {
......
......@@ -289,6 +289,10 @@ void RenderViewTest::SetUp() {
std::string flags("--expose-gc");
v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.size()));
// Ensure that this looks like the renderer process based on the command line.
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kProcessType, switches::kRendererProcess);
// Ensure that we register any necessary schemes when initializing WebKit,
// since we are using a MockRenderThread.
RenderThreadImpl::RegisterSchemes();
......
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