Commit 9877275d authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

Sampling Heap Profiler: Add --sampling-heap-profiler command-line switch.

The patch adds --sampling-heap-profiler command-line switch that enables
profiler at the renderer process startup.
If the rate is not provided it uses the default sampling interval of 128 KiB.

BUG=803276

Change-Id: I6da0e5fc5083a20b8eec7dc987df6105db24b6d7
Reviewed-on: https://chromium-review.googlesource.com/882604
Commit-Queue: Alexei Filippov <alph@chromium.org>
Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532204}
parent 798fc420
...@@ -3175,6 +3175,10 @@ const FeatureEntry kFeatureEntries[] = { ...@@ -3175,6 +3175,10 @@ const FeatureEntry kFeatureEntries[] = {
flag_descriptions::kForceEffectiveConnectionTypeDescription, kOsAll, flag_descriptions::kForceEffectiveConnectionTypeDescription, kOsAll,
MULTI_VALUE_TYPE(kForceEffectiveConnectionTypeChoices)}, MULTI_VALUE_TYPE(kForceEffectiveConnectionTypeChoices)},
{"sampling-heap-profiler", flag_descriptions::kSamplingHeapProfilerName,
flag_descriptions::kSamplingHeapProfilerDescription, kOsAll,
SINGLE_VALUE_TYPE(switches::kSamplingHeapProfiler)},
{"enable-heap-profiling", flag_descriptions::kEnableHeapProfilingName, {"enable-heap-profiling", flag_descriptions::kEnableHeapProfilingName,
flag_descriptions::kEnableHeapProfilingDescription, kOsAll, flag_descriptions::kEnableHeapProfilingDescription, kOsAll,
MULTI_VALUE_TYPE(kEnableHeapProfilingChoices)}, MULTI_VALUE_TYPE(kEnableHeapProfilingChoices)},
......
...@@ -1212,6 +1212,11 @@ const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting."; ...@@ -1212,6 +1212,11 @@ const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting.";
const char kSafeSearchUrlReportingDescription[] = const char kSafeSearchUrlReportingDescription[] =
"If enabled, inappropriate URLs can be reported back to SafeSearch."; "If enabled, inappropriate URLs can be reported back to SafeSearch.";
const char kSamplingHeapProfilerName[] = "Native memory sampling profiler.";
const char kSamplingHeapProfilerDescription[] =
"Enables native memory sampling profiler with specified rate in KiB. "
"If sampling rate is not provided the default value of 128 KiB is used.";
const char kSaveasMenuLabelExperimentName[] = const char kSaveasMenuLabelExperimentName[] =
"Switch 'Save as' menu labels to 'Download'"; "Switch 'Save as' menu labels to 'Download'";
const char kSaveasMenuLabelExperimentDescription[] = const char kSaveasMenuLabelExperimentDescription[] =
......
...@@ -749,6 +749,9 @@ extern const char kResourceLoadSchedulerDescription[]; ...@@ -749,6 +749,9 @@ extern const char kResourceLoadSchedulerDescription[];
extern const char kSafeSearchUrlReportingName[]; extern const char kSafeSearchUrlReportingName[];
extern const char kSafeSearchUrlReportingDescription[]; extern const char kSafeSearchUrlReportingDescription[];
extern const char kSamplingHeapProfilerName[];
extern const char kSamplingHeapProfilerDescription[];
extern const char kSaveasMenuLabelExperimentName[]; extern const char kSaveasMenuLabelExperimentName[];
extern const char kSaveasMenuLabelExperimentDescription[]; extern const char kSaveasMenuLabelExperimentDescription[];
......
...@@ -2620,6 +2620,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( ...@@ -2620,6 +2620,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kRegisterPepperPlugins, switches::kRegisterPepperPlugins,
switches::kRendererStartupDialog, switches::kRendererStartupDialog,
switches::kRootLayerScrolls, switches::kRootLayerScrolls,
switches::kSamplingHeapProfiler,
switches::kShowPaintRects, switches::kShowPaintRects,
switches::kStatsCollectionController, switches::kStatsCollectionController,
switches::kTestType, switches::kTestType,
......
...@@ -751,6 +751,9 @@ const char kReducedReferrerGranularity[] = ...@@ -751,6 +751,9 @@ const char kReducedReferrerGranularity[] =
// Handles frame scrolls via the root RenderLayer instead of the FrameView. // Handles frame scrolls via the root RenderLayer instead of the FrameView.
const char kRootLayerScrolls[] = "root-layer-scrolls"; const char kRootLayerScrolls[] = "root-layer-scrolls";
// Enables native memory sampling profiler with a given rate (default 128 KiB).
const char kSamplingHeapProfiler[] = "sampling-heap-profiler";
// Causes the process to run as a sandbox IPC subprocess. // Causes the process to run as a sandbox IPC subprocess.
const char kSandboxIPCProcess[] = "sandbox-ipc"; const char kSandboxIPCProcess[] = "sandbox-ipc";
......
...@@ -162,6 +162,7 @@ extern const char kGpuLauncher[]; ...@@ -162,6 +162,7 @@ extern const char kGpuLauncher[];
CONTENT_EXPORT extern const char kGpuProcess[]; CONTENT_EXPORT extern const char kGpuProcess[];
CONTENT_EXPORT extern const char kGpuSandboxStartEarly[]; CONTENT_EXPORT extern const char kGpuSandboxStartEarly[];
CONTENT_EXPORT extern const char kGpuStartupDialog[]; CONTENT_EXPORT extern const char kGpuStartupDialog[];
CONTENT_EXPORT extern const char kSamplingHeapProfiler[];
CONTENT_EXPORT extern const char kHistoryEntryRequiresUserGesture[]; CONTENT_EXPORT extern const char kHistoryEntryRequiresUserGesture[];
CONTENT_EXPORT extern const char kIgnoreCertificateErrorsSPKIList[]; CONTENT_EXPORT extern const char kIgnoreCertificateErrorsSPKIList[];
CONTENT_EXPORT extern const char kInProcessGPU[]; CONTENT_EXPORT extern const char kInProcessGPU[];
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/pending_task.h" #include "base/pending_task.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#include "content/renderer/renderer_main_platform_delegate.h" #include "content/renderer/renderer_main_platform_delegate.h"
#include "media/media_features.h" #include "media/media_features.h"
#include "ppapi/features/features.h" #include "ppapi/features/features.h"
#include "third_party/WebKit/public/platform/SamplingHeapProfiler.h"
#include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h" #include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h"
#include "third_party/skia/include/core/SkGraphics.h" #include "third_party/skia/include/core/SkGraphics.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
...@@ -99,7 +101,19 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -99,7 +101,19 @@ int RendererMain(const MainFunctionParams& parameters) {
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex( base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
kTraceEventRendererProcessSortIndex); kTraceEventRendererProcessSortIndex);
const base::CommandLine& parsed_command_line = parameters.command_line; const base::CommandLine& command_line = parameters.command_line;
if (command_line.HasSwitch(switches::kSamplingHeapProfiler)) {
blink::SamplingHeapProfiler* profiler =
blink::SamplingHeapProfiler::GetInstance();
unsigned sampling_interval = 0;
bool parsed = base::StringToUint(
command_line.GetSwitchValueASCII(switches::kSamplingHeapProfiler),
&sampling_interval);
if (parsed && sampling_interval > 0)
profiler->SetSamplingInterval(sampling_interval * 1024);
profiler->Start();
}
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool; base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool;
...@@ -110,9 +124,9 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -110,9 +124,9 @@ int RendererMain(const MainFunctionParams& parameters) {
// locale (at login time for Chrome OS), we have to set the ICU default // locale (at login time for Chrome OS), we have to set the ICU default
// locale for renderer process here. // locale for renderer process here.
// ICU locale will be used for fallback font selection etc. // ICU locale will be used for fallback font selection etc.
if (parsed_command_line.HasSwitch(switches::kLang)) { if (command_line.HasSwitch(switches::kLang)) {
const std::string locale = const std::string locale =
parsed_command_line.GetSwitchValueASCII(switches::kLang); command_line.GetSwitchValueASCII(switches::kLang);
base::i18n::SetICUDefaultLocale(locale); base::i18n::SetICUDefaultLocale(locale);
} }
#endif #endif
...@@ -148,7 +162,7 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -148,7 +162,7 @@ int RendererMain(const MainFunctionParams& parameters) {
// flag allowing us to attach a debugger. // flag allowing us to attach a debugger.
// Do not move this function down since that would mean we can't easily debug // Do not move this function down since that would mean we can't easily debug
// whatever occurs before it. // whatever occurs before it.
HandleRendererErrorTestParameters(parsed_command_line); HandleRendererErrorTestParameters(command_line);
RendererMainPlatformDelegate platform(parameters); RendererMainPlatformDelegate platform(parameters);
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
...@@ -165,7 +179,7 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -165,7 +179,7 @@ int RendererMain(const MainFunctionParams& parameters) {
base::PlatformThread::SetName("CrRendererMain"); base::PlatformThread::SetName("CrRendererMain");
bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox); bool no_sandbox = command_line.HasSwitch(switches::kNoSandbox);
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// If we have any pending LibraryLoader histograms, record them. // If we have any pending LibraryLoader histograms, record them.
......
...@@ -26,12 +26,13 @@ namespace { ...@@ -26,12 +26,13 @@ namespace {
const unsigned kMagicSignature = 0x14690ca5; const unsigned kMagicSignature = 0x14690ca5;
const unsigned kDefaultAlignment = 16; const unsigned kDefaultAlignment = 16;
const unsigned kSkipAllocatorFrames = 4; const unsigned kSkipAllocatorFrames = 4;
const size_t kDefaultSamplingInterval = 128 * 1024;
bool g_deterministic; bool g_deterministic;
Atomic32 g_running; Atomic32 g_running;
AtomicWord g_cumulative_counter = 0; AtomicWord g_cumulative_counter = 0;
AtomicWord g_threshold; AtomicWord g_threshold = kDefaultSamplingInterval;
AtomicWord g_sampling_interval = 128 * 1024; AtomicWord g_sampling_interval = kDefaultSamplingInterval;
uint32_t g_last_sample_ordinal = 0; uint32_t g_last_sample_ordinal = 0;
inline bool HasBeenSampledFastCheck(void* address) { inline bool HasBeenSampledFastCheck(void* address) {
...@@ -46,6 +47,10 @@ SamplingNativeHeapProfiler::Sample::Sample(size_t size, ...@@ -46,6 +47,10 @@ SamplingNativeHeapProfiler::Sample::Sample(size_t size,
unsigned offset) unsigned offset)
: size(size), count(count), ordinal(ordinal), offset(offset) {} : size(size), count(count), ordinal(ordinal), offset(offset) {}
SamplingHeapProfiler* SamplingHeapProfiler::GetInstance() {
return SamplingNativeHeapProfiler::GetInstance();
}
void* SamplingNativeHeapProfiler::AllocFn(const AllocatorDispatch* self, void* SamplingNativeHeapProfiler::AllocFn(const AllocatorDispatch* self,
size_t size, size_t size,
void* context) { void* context) {
...@@ -199,13 +204,13 @@ bool SamplingNativeHeapProfiler::InstallAllocatorHooks() { ...@@ -199,13 +204,13 @@ bool SamplingNativeHeapProfiler::InstallAllocatorHooks() {
uint32_t SamplingNativeHeapProfiler::Start() { uint32_t SamplingNativeHeapProfiler::Start() {
InstallAllocatorHooksOnce(); InstallAllocatorHooksOnce();
base::subtle::Release_Store(&g_threshold, g_sampling_interval); base::subtle::Barrier_AtomicIncrement(&g_running, 1);
base::subtle::Release_Store(&g_running, true);
return g_last_sample_ordinal; return g_last_sample_ordinal;
} }
void SamplingNativeHeapProfiler::Stop() { void SamplingNativeHeapProfiler::Stop() {
base::subtle::Release_Store(&g_running, false); AtomicWord count = base::subtle::Barrier_AtomicIncrement(&g_running, -1);
CHECK_GE(count, 0);
} }
void SamplingNativeHeapProfiler::SetSamplingInterval(size_t sampling_interval) { void SamplingNativeHeapProfiler::SetSamplingInterval(size_t sampling_interval) {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/threading/thread_local.h" #include "base/threading/thread_local.h"
#include "platform/PlatformExport.h" #include "platform/PlatformExport.h"
#include "public/platform/SamplingHeapProfiler.h"
namespace base { namespace base {
template <typename T> template <typename T>
...@@ -22,7 +23,7 @@ struct DefaultSingletonTraits; ...@@ -22,7 +23,7 @@ struct DefaultSingletonTraits;
namespace blink { namespace blink {
class PLATFORM_EXPORT SamplingNativeHeapProfiler { class PLATFORM_EXPORT SamplingNativeHeapProfiler : public SamplingHeapProfiler {
public: public:
class Sample { class Sample {
public: public:
...@@ -41,9 +42,9 @@ class PLATFORM_EXPORT SamplingNativeHeapProfiler { ...@@ -41,9 +42,9 @@ class PLATFORM_EXPORT SamplingNativeHeapProfiler {
SamplingNativeHeapProfiler() = default; SamplingNativeHeapProfiler() = default;
uint32_t Start(); uint32_t Start() override;
void Stop(); void Stop() override;
void SetSamplingInterval(size_t sampling_interval); void SetSamplingInterval(size_t sampling_interval) override;
void SuppressRandomnessForTest(); void SuppressRandomnessForTest();
std::vector<Sample> GetSamples(uint32_t profile_id); std::vector<Sample> GetSamples(uint32_t profile_id);
......
...@@ -123,6 +123,7 @@ source_set("blink_headers") { ...@@ -123,6 +123,7 @@ source_set("blink_headers") {
"platform/InterfaceRegistry.h", "platform/InterfaceRegistry.h",
"platform/Platform.h", "platform/Platform.h",
"platform/PointerProperties.h", "platform/PointerProperties.h",
"platform/SamplingHeapProfiler.h",
"platform/ShapeProperties.h", "platform/ShapeProperties.h",
"platform/TaskType.h", "platform/TaskType.h",
"platform/URLConversion.h", "platform/URLConversion.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.
#ifndef SamplingHeapProfiler_h
#define SamplingHeapProfiler_h
#include "WebCommon.h"
namespace blink {
class BLINK_PLATFORM_EXPORT SamplingHeapProfiler {
public:
static SamplingHeapProfiler* GetInstance();
virtual uint32_t Start() = 0;
virtual void Stop() = 0;
virtual void SetSamplingInterval(size_t sampling_interval) = 0;
protected:
SamplingHeapProfiler() = default;
virtual ~SamplingHeapProfiler() = default;
};
} // namespace blink
#endif // SamplingHeapProfiler_h
...@@ -26334,6 +26334,7 @@ from previous Chrome versions. ...@@ -26334,6 +26334,7 @@ from previous Chrome versions.
<int value="762700519" label="enable-checker-imaging"/> <int value="762700519" label="enable-checker-imaging"/>
<int value="765306424" label="ModuleScriptsDynamicImport:disabled"/> <int value="765306424" label="ModuleScriptsDynamicImport:disabled"/>
<int value="765803208" label="AutofillShowTypePredictions:enabled"/> <int value="765803208" label="AutofillShowTypePredictions:enabled"/>
<int value="766898398" label="sampling-heap-profiler"/>
<int value="772348426" label="AffiliationBasedMatching:enabled"/> <int value="772348426" label="AffiliationBasedMatching:enabled"/>
<int value="773919225" label="disable-office-editing-component-extension"/> <int value="773919225" label="disable-office-editing-component-extension"/>
<int value="779086132" label="enable-data-reduction-proxy-alt"/> <int value="779086132" label="enable-data-reduction-proxy-alt"/>
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