Commit 3f10e54a authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

Reland "[Sampling profiler] Factor out platform config 1/4"

This reverts commit 2c8b578a.

Reason for reland: originally reverted because the change was broken
by https://crrev.com/810801 and that change has since been reverted

Original change's description:
> [Sampling profiler] Factor out platform config 1/4
>
> First in a series factoring the ThreadProfiler platform specific
> configuration state from the code that takes action on the
> state. Defines an IsSupported function that is true if the profiler
> is supported on the chrome branding and channel for the platform.
>
> The end goal is to reduce the configuration complexity, to support
> enabling per-thread on Android.
> Bug: 1129939
> Change-Id: Ibbd6f4725804b40ac77e15aaa3bd15ad76a0e7b0
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425165
> Reviewed-by: ssid <ssid@chromium.org>
> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
> Commit-Queue: Mike Wittman <wittman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#810835}

TBR=etiennep@chromium.org, ssid@chromium.org

Bug: 1129939
Change-Id: Ie69c5c695bc286f070e34f70553ffd35562208b9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2436250Reviewed-by: default avatarssid <ssid@chromium.org>
Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Reviewed-by: default avatarEtienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811521}
parent 599f05b2
...@@ -741,9 +741,9 @@ TimeTicks StackSamplingProfiler::TestPeer::GetNextSampleTime( ...@@ -741,9 +741,9 @@ TimeTicks StackSamplingProfiler::TestPeer::GetNextSampleTime(
} }
// static // static
// The profiler is currently only implemented for Windows x64 and MacOSX. // The profiler is currently supported for Windows x64, MacOSX x64, and Android
// TODO(https://crbug.com/1004855): enable for Android arm. // ARM32.
bool StackSamplingProfiler::IsSupported() { bool StackSamplingProfiler::IsSupportedForCurrentPlatform() {
#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \ #if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \ (defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE)) (defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
......
...@@ -92,7 +92,7 @@ class BASE_EXPORT StackSamplingProfiler { ...@@ -92,7 +92,7 @@ class BASE_EXPORT StackSamplingProfiler {
// Returns true if the profiler is supported on the current platform // Returns true if the profiler is supported on the current platform
// configuration. // configuration.
static bool IsSupported(); static bool IsSupportedForCurrentPlatform();
// Creates a profiler for the the thread associated with |thread_token|, // Creates a profiler for the the thread associated with |thread_token|,
// generated by GetSamplingProfilerCurrentThreadToken(). // generated by GetSamplingProfilerCurrentThreadToken().
......
...@@ -15,6 +15,8 @@ source_set("profiler") { ...@@ -15,6 +15,8 @@ source_set("profiler") {
"main_thread_stack_sampling_profiler.cc", "main_thread_stack_sampling_profiler.cc",
"thread_profiler.cc", "thread_profiler.cc",
"thread_profiler_configuration.cc", "thread_profiler_configuration.cc",
"thread_profiler_platform_configuration.cc",
"thread_profiler_platform_configuration.h",
] ]
deps = [ deps = [
......
...@@ -132,7 +132,7 @@ bool ShouldSkipTestForMacOS11() { ...@@ -132,7 +132,7 @@ bool ShouldSkipTestForMacOS11() {
// DCHECK that that remains the case so these tests are re-enabled when the // DCHECK that that remains the case so these tests are re-enabled when the
// sampling profiler is re-enabled there. // sampling profiler is re-enabled there.
if (base::mac::IsAtLeastOS11()) { if (base::mac::IsAtLeastOS11()) {
DCHECK(!base::StackSamplingProfiler::IsSupported()); DCHECK(!base::StackSamplingProfiler::IsSupportedForCurrentPlatform());
return true; return true;
} }
#endif #endif
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/channel_info.h" #include "chrome/common/channel_info.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/profiler/thread_profiler_platform_configuration.h"
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "extensions/buildflags/buildflags.h" #include "extensions/buildflags/buildflags.h"
...@@ -66,21 +67,6 @@ bool IsBrowserTestModeEnabled() { ...@@ -66,21 +67,6 @@ bool IsBrowserTestModeEnabled() {
switches::kStartStackProfilerBrowserTest; switches::kStartStackProfilerBrowserTest;
} }
bool IsProfilerEnabledForChannel() {
#if defined(OS_ANDROID)
// Profiling is only enable in it's own dedicated browser tests on Android.
// TODO(crbug.com/1004855): Remove this logic to launch profiler.
return IsBrowserTestModeEnabled();
#elif BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Only run on canary and dev.
const version_info::Channel channel = chrome::GetChannel();
return channel == version_info::Channel::CANARY ||
channel == version_info::Channel::DEV;
#else
return true;
#endif
}
bool ShouldEnableProfilerForNextRendererProcess() { bool ShouldEnableProfilerForNextRendererProcess() {
// Ensure deterministic behavior for testing the profiler itself. // Ensure deterministic behavior for testing the profiler itself.
if (IsBrowserTestModeEnabled()) if (IsBrowserTestModeEnabled())
...@@ -93,7 +79,11 @@ bool ShouldEnableProfilerForNextRendererProcess() { ...@@ -93,7 +79,11 @@ bool ShouldEnableProfilerForNextRendererProcess() {
} // namespace } // namespace
ThreadProfilerConfiguration::ThreadProfilerConfiguration() ThreadProfilerConfiguration::ThreadProfilerConfiguration()
: configuration_(GenerateConfiguration()) {} : platform_configuration_(ThreadProfilerPlatformConfiguration::Create(
IsBrowserTestModeEnabled())),
configuration_(GenerateConfiguration(*platform_configuration_)) {}
ThreadProfilerConfiguration::~ThreadProfilerConfiguration() = default;
base::StackSamplingProfiler::SamplingParams base::StackSamplingProfiler::SamplingParams
ThreadProfilerConfiguration::GetSamplingParams() const { ThreadProfilerConfiguration::GetSamplingParams() const {
...@@ -129,10 +119,10 @@ bool ThreadProfilerConfiguration::GetSyntheticFieldTrial( ...@@ -129,10 +119,10 @@ bool ThreadProfilerConfiguration::GetSyntheticFieldTrial(
std::string* group_name) const { std::string* group_name) const {
DCHECK(IsBrowserProcess()); DCHECK(IsBrowserProcess());
if (!base::StackSamplingProfiler::IsSupported()) if (!platform_configuration_->IsSupported(BUILDFLAG(GOOGLE_CHROME_BRANDING),
return false; chrome::GetChannel())) {
if (!IsProfilerEnabledForChannel())
return false; return false;
}
*trial_name = "SyntheticStackProfilingConfiguration"; *trial_name = "SyntheticStackProfilingConfiguration";
*group_name = std::string(); *group_name = std::string();
...@@ -220,14 +210,16 @@ ThreadProfilerConfiguration::ChooseConfiguration( ...@@ -220,14 +210,16 @@ ThreadProfilerConfiguration::ChooseConfiguration(
// static // static
ThreadProfilerConfiguration::ProfileConfiguration ThreadProfilerConfiguration::ProfileConfiguration
ThreadProfilerConfiguration::GenerateConfiguration() { ThreadProfilerConfiguration::GenerateConfiguration(
const ThreadProfilerPlatformConfiguration& platform_configuration) {
if (!IsBrowserProcess()) if (!IsBrowserProcess())
return PROFILE_FROM_COMMAND_LINE; return PROFILE_FROM_COMMAND_LINE;
if (!base::StackSamplingProfiler::IsSupported()) const version_info::Channel channel = chrome::GetChannel();
return PROFILE_DISABLED; if (!platform_configuration.IsSupported(BUILDFLAG(GOOGLE_CHROME_BRANDING),
if (!IsProfilerEnabledForChannel()) channel)) {
return PROFILE_DISABLED; return PROFILE_DISABLED;
}
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Allow profiling if the Android Java/native unwinder module is available at // Allow profiling if the Android Java/native unwinder module is available at
......
...@@ -15,6 +15,8 @@ namespace base { ...@@ -15,6 +15,8 @@ namespace base {
class CommandLine; class CommandLine;
} // namespace base } // namespace base
class ThreadProfilerPlatformConfiguration;
// ThreadProfilerConfiguration chooses a configuration for the enable state of // ThreadProfilerConfiguration chooses a configuration for the enable state of
// the stack sampling profiler across all processes. This configuration is // the stack sampling profiler across all processes. This configuration is
// determined once at browser process startup. Configurations for child // determined once at browser process startup. Configurations for child
...@@ -22,6 +24,7 @@ class CommandLine; ...@@ -22,6 +24,7 @@ class CommandLine;
class ThreadProfilerConfiguration { class ThreadProfilerConfiguration {
public: public:
ThreadProfilerConfiguration(); ThreadProfilerConfiguration();
~ThreadProfilerConfiguration();
// Get the stack sampling params to use. // Get the stack sampling params to use.
base::StackSamplingProfiler::SamplingParams GetSamplingParams() const; base::StackSamplingProfiler::SamplingParams GetSamplingParams() const;
...@@ -72,11 +75,15 @@ class ThreadProfilerConfiguration { ...@@ -72,11 +75,15 @@ class ThreadProfilerConfiguration {
const std::vector<Variation>& variations); const std::vector<Variation>& variations);
// Generates sampling profiler configurations for all processes. // Generates sampling profiler configurations for all processes.
static ProfileConfiguration GenerateConfiguration(); static ProfileConfiguration GenerateConfiguration(
const ThreadProfilerPlatformConfiguration& platform_configuration);
// NOTE: all state in this class must be const and initialized at construction // NOTE: all state in this class must be const and initialized at construction
// time to ensure thread-safe access post-construction. // time to ensure thread-safe access post-construction.
const std::unique_ptr<ThreadProfilerPlatformConfiguration>
platform_configuration_;
// In the browser process this represents the configuration to use across all // In the browser process this represents the configuration to use across all
// Chrome processes. In the child processes it is always // Chrome processes. In the child processes it is always
// PROFILE_FROM_COMMAND_LINE. // PROFILE_FROM_COMMAND_LINE.
......
// Copyright 2020 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/profiler/thread_profiler_platform_configuration.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "build/build_config.h"
namespace {
// The default configuration to use in the absence of special circumstances on a
// specific platform.
class DefaultPlatformConfiguration
: public ThreadProfilerPlatformConfiguration {
public:
explicit DefaultPlatformConfiguration(bool browser_test_mode_enabled);
protected:
bool IsSupportedForChannel(bool is_chrome_branded,
version_info::Channel channel) const override;
bool browser_test_mode_enabled() const { return browser_test_mode_enabled_; }
private:
const bool browser_test_mode_enabled_;
};
DefaultPlatformConfiguration::DefaultPlatformConfiguration(
bool browser_test_mode_enabled)
: browser_test_mode_enabled_(browser_test_mode_enabled) {}
bool DefaultPlatformConfiguration::IsSupportedForChannel(
bool is_chrome_branded,
version_info::Channel channel) const {
// The profiler is always supported for local builds and the CQ.
if (!is_chrome_branded)
return true;
// Canary and dev are the only channels currently supported in release
// builds.
return channel == version_info::Channel::CANARY ||
channel == version_info::Channel::DEV;
}
#if defined(OS_ANDROID)
// The configuration to use for the Android platform. Applies to ARM32 which is
// the only Android architecture currently supported by StackSamplingProfiler.
// Defined in terms of DefaultPlatformConfiguration where Android does not
// differ from the default case.
class AndroidPlatformConfiguration : public DefaultPlatformConfiguration {
public:
explicit AndroidPlatformConfiguration(bool browser_test_mode_enabled);
protected:
bool IsSupportedForChannel(bool is_chrome_branded,
version_info::Channel channel) const override;
};
AndroidPlatformConfiguration::AndroidPlatformConfiguration(
bool browser_test_mode_enabled)
: DefaultPlatformConfiguration(browser_test_mode_enabled) {}
bool AndroidPlatformConfiguration::IsSupportedForChannel(
bool is_chrome_branded,
version_info::Channel channel) const {
// On Android profiling is only enabled in its own dedicated browser tests
// in local builds and the CQ.
// TODO(https://crbug.com/1004855): Enable across all browser tests.
return browser_test_mode_enabled();
}
#endif // defined(OS_ANDROID)
} // namespace
// static
std::unique_ptr<ThreadProfilerPlatformConfiguration>
ThreadProfilerPlatformConfiguration::Create(bool browser_test_mode_enabled) {
#if defined(OS_ANDROID)
using PlatformConfiguration = AndroidPlatformConfiguration;
#else
using PlatformConfiguration = DefaultPlatformConfiguration;
#endif
return std::make_unique<PlatformConfiguration>(browser_test_mode_enabled);
}
bool ThreadProfilerPlatformConfiguration::IsSupported(
bool is_chrome_branded,
version_info::Channel channel) const {
return base::StackSamplingProfiler::IsSupportedForCurrentPlatform() &&
IsSupportedForChannel(is_chrome_branded, channel);
}
// Copyright 2020 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_PROFILER_THREAD_PROFILER_PLATFORM_CONFIGURATION_H_
#define CHROME_COMMON_PROFILER_THREAD_PROFILER_PLATFORM_CONFIGURATION_H_
#include <memory>
#include "components/version_info/version_info.h"
// Encapsulates the platform-specific configuration for the ThreadProfiler.
//
// The interface functions this class make a distinction between 'supported' and
// 'enabled' state. Supported means the profiler can be run in *some*
// circumstances for *some* fraction of the population on the
// platform/branding/channel combination. This state is intended to enable
// experiment reporting. This avoids spamming UMA with experiment state on
// platforms/channels where the profiler is not being run.
//
// Enabled means we chose to the run the profiler on at least some threads on a
// platform/branding/channel combination that is configured for profiling. The
// overall enable/disable state should be reported to UMA in this case.
class ThreadProfilerPlatformConfiguration {
public:
virtual ~ThreadProfilerPlatformConfiguration() = default;
// Create the platform configuration.
static std::unique_ptr<ThreadProfilerPlatformConfiguration> Create(
bool browser_test_mode_enabled);
// True if the platform supports the StackSamplingProfiler and the profiler is
// to be run for the channel/chrome branding.
bool IsSupported(bool is_chrome_branded, version_info::Channel channel) const;
protected:
// True if the profiler is to be run for the channel/chrome branding on the
// platform. Does not need to check whether the StackSamplingProfiler is
// supported on the platform since that's done in IsSupported().
virtual bool IsSupportedForChannel(bool is_chrome_branded,
version_info::Channel channel) const = 0;
};
#endif // CHROME_COMMON_PROFILER_THREAD_PROFILER_PLATFORM_CONFIGURATION_H_
// Copyright 2020 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/profiler/thread_profiler_platform_configuration.h"
#include "base/profiler/profiler_buildflags.h"
#include "build/build_config.h"
#include "components/version_info/version_info.h"
#include "testing/gtest/include/gtest/gtest.h"
#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \
(defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
#define THREAD_PROFILER_SUPPORTED_ON_PLATFORM true
#else
#define THREAD_PROFILER_SUPPORTED_ON_PLATFORM false
#endif
// The browser_test_mode_enabled=true scenario is already covered by the browser
// tests so doesn't require separate testing here.
TEST(ThreadProfilerPlatformConfigurationTest, IsSupported) {
const std::unique_ptr<ThreadProfilerPlatformConfiguration> config =
ThreadProfilerPlatformConfiguration::Create(
/*browser_test_mode_enabled=*/false);
#if !THREAD_PROFILER_SUPPORTED_ON_PLATFORM
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::UNKNOWN));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::CANARY));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::DEV));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::BETA));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::STABLE));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/false,
version_info::Channel::UNKNOWN));
#elif defined(OS_ANDROID)
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::UNKNOWN));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::CANARY));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::DEV));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::BETA));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::STABLE));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/false,
version_info::Channel::UNKNOWN));
#else
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::UNKNOWN));
EXPECT_TRUE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::CANARY));
EXPECT_TRUE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::DEV));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::BETA));
EXPECT_FALSE(config->IsSupported(/*is_chrome_branded=*/true,
version_info::Channel::STABLE));
EXPECT_TRUE(config->IsSupported(/*is_chrome_branded=*/false,
version_info::Channel::UNKNOWN));
#endif
}
...@@ -3773,6 +3773,7 @@ test("unit_tests") { ...@@ -3773,6 +3773,7 @@ test("unit_tests") {
"../common/mac/mock_launchd.mm", "../common/mac/mock_launchd.mm",
"../common/net/safe_search_util_unittest.cc", "../common/net/safe_search_util_unittest.cc",
"../common/pref_names_util_unittest.cc", "../common/pref_names_util_unittest.cc",
"../common/profiler/thread_profiler_platform_configuration_unittest.cc",
"../common/profiler/thread_profiler_unittest.cc", "../common/profiler/thread_profiler_unittest.cc",
"../common/qr_code_generator/qr_code_generator_unittest.cc", "../common/qr_code_generator/qr_code_generator_unittest.cc",
"../renderer/chrome_content_renderer_client_unittest.cc", "../renderer/chrome_content_renderer_client_unittest.cc",
......
...@@ -686,7 +686,7 @@ void TracingSamplerProfiler::StartTracing( ...@@ -686,7 +686,7 @@ void TracingSamplerProfiler::StartTracing(
// On Android the sampling profiler is implemented by tracing service and is // On Android the sampling profiler is implemented by tracing service and is
// not yet supported by base::StackSamplingProfiler. So, only check this if // not yet supported by base::StackSamplingProfiler. So, only check this if
// service does not support unwinding in current platform. // service does not support unwinding in current platform.
if (!base::StackSamplingProfiler::IsSupported()) if (!base::StackSamplingProfiler::IsSupportedForCurrentPlatform())
return; return;
#endif // !(ANDROID_ARM64_UNWINDING_SUPPORTED || #endif // !(ANDROID_ARM64_UNWINDING_SUPPORTED ||
// ANDROID_CFI_UNWINDING_SUPPORTED) // ANDROID_CFI_UNWINDING_SUPPORTED)
......
...@@ -190,7 +190,7 @@ bool ShouldSkipTestForMacOS11() { ...@@ -190,7 +190,7 @@ bool ShouldSkipTestForMacOS11() {
// DCHECK here so that when the sampling profiler is re-enabled on macOS 11, // DCHECK here so that when the sampling profiler is re-enabled on macOS 11,
// these tests are also re-enabled. // these tests are also re-enabled.
if (base::mac::IsAtLeastOS11()) { if (base::mac::IsAtLeastOS11()) {
DCHECK(!base::StackSamplingProfiler::IsSupported()); DCHECK(!base::StackSamplingProfiler::IsSupportedForCurrentPlatform());
return true; return true;
} }
#endif #endif
......
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