Commit 0f15e7a2 authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

[heap profiler] Migrate UMA heap profiler off LegacyCallStackProfileBuilder

... and remove the latter as it was the last client.

BUG=916303,913570

Change-Id: Ida37eda8bcc61ca3382769e650f30165cd184c93
Reviewed-on: https://chromium-review.googlesource.com/c/1465145
Commit-Queue: Alexei Filippov <alph@chromium.org>
Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#632373}
parent 5e7e1b19
......@@ -137,7 +137,6 @@
#include "components/metrics/call_stack_profile_metrics_provider.h"
#include "components/metrics/call_stack_profile_params.h"
#include "components/metrics/expired_histogram_util.h"
#include "components/metrics/legacy_call_stack_profile_builder.h"
#include "components/metrics/metrics_reporting_default_state.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
......@@ -1893,11 +1892,6 @@ void ChromeBrowserMainParts::PostMainMessageLoopRun() {
#endif // defined(OS_ANDROID)
}
void ChromeBrowserMainParts::PreShutdown() {
metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
metrics::LegacyCallStackProfileBuilder::SHUTDOWN_START);
}
void ChromeBrowserMainParts::PostDestroyThreads() {
#if defined(OS_ANDROID)
// On Android, there is no quit/exit. So the browser's main message loop will
......
......@@ -67,7 +67,6 @@ class ChromeBrowserMainParts : public content::BrowserMainParts {
void PreMainMessageLoopRun() override;
bool MainMessageLoopRun(int* result_code) override;
void PostMainMessageLoopRun() override;
void PreShutdown() override;
void PostDestroyThreads() override;
// Additional stages for ChromeBrowserMainExtraParts. These stages are called
......
......@@ -23,7 +23,6 @@ include_rules = [
"+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/legacy_call_stack_profile_builder.h",
"+components/metrics/client_info.h",
"+components/metrics/metrics_pref_names.h",
"+components/nacl/common",
......
......@@ -10,21 +10,25 @@
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/metrics_hashes.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/rand_util.h"
#include "base/sampling_heap_profiler/module_cache.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "components/metrics/legacy_call_stack_profile_builder.h"
#include "components/metrics/call_stack_profile_builder.h"
#include "content/public/common/content_switches.h"
namespace {
const base::Feature kSamplingHeapProfilerFeature{
constexpr char kMetadataSizeField[] = "HeapProfiler.AllocationInBytes";
constexpr base::Feature kSamplingHeapProfilerFeature{
"SamplingHeapProfiler", base::FEATURE_DISABLED_BY_DEFAULT};
const char kSamplingHeapProfilerFeatureSamplingRateKB[] = "sampling-rate-kb";
constexpr char kSamplingHeapProfilerFeatureSamplingRateKB[] =
"sampling-rate-kb";
constexpr size_t kDefaultSamplingRateKB = 128;
constexpr base::TimeDelta kHeapCollectionInterval =
......@@ -36,11 +40,25 @@ base::TimeDelta RandomInterval(base::TimeDelta mean) {
return -std::log(base::RandDouble()) * mean;
}
} // namespace
class SampleMetadataRecorder : public metrics::MetadataRecorder {
public:
SampleMetadataRecorder()
: field_hash_(base::HashMetricName(kMetadataSizeField)) {}
void SetCurrentSampleSize(size_t size) { current_sample_size_ = size; }
std::pair<uint64_t, int64_t> GetHashAndValue() const override {
return std::make_pair(field_hash_, current_sample_size_);
}
using Frame = base::StackSamplingProfiler::Frame;
private:
const uint64_t field_hash_;
size_t current_sample_size_ = 0;
};
HeapProfilerController::HeapProfilerController() : weak_factory_(this) {}
} // namespace
HeapProfilerController::HeapProfilerController() = default;
HeapProfilerController::~HeapProfilerController() = default;
void HeapProfilerController::StartIfEnabled() {
......@@ -71,20 +89,17 @@ void HeapProfilerController::StartIfEnabled() {
auto* profiler = base::SamplingHeapProfiler::Get();
profiler->SetSamplingInterval(sampling_rate_kb * 1024);
profiler->Start();
ScheduleNextSnapshot();
}
void HeapProfilerController::ScheduleNextSnapshot() {
if (task_runner_for_test_) {
task_runner_for_test_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&HeapProfilerController::TakeSnapshot,
weak_factory_.GetWeakPtr()),
RandomInterval(kHeapCollectionInterval));
return;
if (!task_runner_) {
task_runner_ =
base::CreateTaskRunnerWithTraits({base::TaskPriority::BEST_EFFORT});
}
base::PostDelayedTaskWithTraits(
FROM_HERE, base::TaskTraits(base::TaskPriority::BEST_EFFORT),
task_runner_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&HeapProfilerController::TakeSnapshot,
weak_factory_.GetWeakPtr()),
RandomInterval(kHeapCollectionInterval));
......@@ -100,12 +115,15 @@ void HeapProfilerController::RetrieveAndSendSnapshot() {
base::SamplingHeapProfiler::Get()->GetSamples(0);
if (samples.empty())
return;
base::ModuleCache module_cache;
SampleMetadataRecorder metadata_recorder;
metrics::CallStackProfileParams params(
metrics::CallStackProfileParams::BROWSER_PROCESS,
metrics::CallStackProfileParams::UNKNOWN_THREAD,
metrics::CallStackProfileParams::PERIODIC_HEAP_COLLECTION);
metrics::LegacyCallStackProfileBuilder profile_builder(params);
metrics::CallStackProfileBuilder profile_builder(params, nullptr,
&metadata_recorder);
for (const base::SamplingHeapProfiler::Sample& sample : samples) {
std::vector<base::StackSamplingProfiler::Frame> frames;
......@@ -116,7 +134,9 @@ void HeapProfilerController::RetrieveAndSendSnapshot() {
module_cache.GetModuleForAddress(address);
frames.emplace_back(address, module);
}
profile_builder.OnSampleCompleted(std::move(frames), sample.total);
metadata_recorder.SetCurrentSampleSize(sample.total);
profile_builder.RecordMetadata();
profile_builder.OnSampleCompleted(std::move(frames));
}
profile_builder.OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
......
......@@ -5,6 +5,9 @@
#ifndef CHROME_COMMON_HEAP_PROFILER_CONTROLLER_H_
#define CHROME_COMMON_HEAP_PROFILER_CONTROLLER_H_
#include <utility>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
namespace base {
......@@ -21,8 +24,8 @@ class HeapProfilerController {
// Starts periodic heap snapshot collection.
void StartIfEnabled();
void SetTaskRunnerForTest(base::TaskRunner* task_runner) {
task_runner_for_test_ = task_runner;
void SetTaskRunnerForTest(scoped_refptr<base::TaskRunner> task_runner) {
task_runner_ = std::move(task_runner);
}
private:
......@@ -31,8 +34,8 @@ class HeapProfilerController {
void RetrieveAndSendSnapshot();
bool started_ = false;
base::TaskRunner* task_runner_for_test_ = nullptr;
base::WeakPtrFactory<HeapProfilerController> weak_factory_;
scoped_refptr<base::TaskRunner> task_runner_;
base::WeakPtrFactory<HeapProfilerController> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(HeapProfilerController);
};
......
......@@ -5,14 +5,52 @@
#include "chrome/common/heap_profiler_controller.h"
#include "base/command_line.h"
#include "base/metrics/metrics_hashes.h"
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/test/bind_test_util.h"
#include "base/test/test_mock_time_task_runner.h"
#include "components/metrics/legacy_call_stack_profile_builder.h"
#include "components/metrics/call_stack_profile_builder.h"
#include "content/public/common/content_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/sampled_profile.pb.h"
constexpr size_t kAllocationSize = 42 * 1024;
void CheckProfile(int* profiles_count,
base::TimeTicks time,
metrics::SampledProfile profile) {
const uint64_t kMetadataCountHash =
base::HashMetricName("HeapProfiler.AllocationInBytes");
EXPECT_EQ(metrics::SampledProfile::PERIODIC_HEAP_COLLECTION,
profile.trigger_event());
EXPECT_LT(0, profile.call_stack_profile().stack_sample_size());
const auto& metadata_hashes =
profile.call_stack_profile().metadata_name_hash();
EXPECT_LT(0, metadata_hashes.size());
const auto* metadata_count_iterator = std::find(
metadata_hashes.begin(), metadata_hashes.end(), kMetadataCountHash);
EXPECT_NE(metadata_count_iterator, metadata_hashes.end());
int metadata_count_index =
static_cast<int>(metadata_count_iterator - metadata_hashes.begin());
bool found = false;
for (const metrics::CallStackProfile::StackSample& sample :
profile.call_stack_profile().stack_sample()) {
EXPECT_LT(0, sample.metadata_size());
for (const metrics::CallStackProfile::MetadataItem& item :
sample.metadata()) {
if (item.name_hash_index() == metadata_count_index &&
item.value() >= static_cast<int64_t>(kAllocationSize)) {
found = true;
break;
}
}
}
EXPECT_TRUE(found);
++*profiles_count;
}
TEST(HeapProfilerControllerTest, ProfileCollectionsScheduler) {
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
base::TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner.get());
......@@ -21,21 +59,17 @@ TEST(HeapProfilerControllerTest, ProfileCollectionsScheduler) {
command_line->AppendSwitchASCII(switches::kSamplingHeapProfiler, "1");
int profiles_collected = 0;
metrics::LegacyCallStackProfileBuilder::SetBrowserProcessReceiverCallback(
base::BindLambdaForTesting(
[&](base::TimeTicks time, metrics::SampledProfile profile) {
EXPECT_EQ(metrics::SampledProfile::PERIODIC_HEAP_COLLECTION,
profile.trigger_event());
EXPECT_LE(1, profile.call_stack_profile().deprecated_sample_size());
++profiles_collected;
}));
metrics::CallStackProfileBuilder::SetBrowserProcessReceiverCallback(
base::BindRepeating(&CheckProfile, &profiles_collected));
base::PoissonAllocationSampler::Init();
HeapProfilerController controller;
controller.SetTaskRunnerForTest(task_runner.get());
controller.StartIfEnabled();
auto* sampler = base::PoissonAllocationSampler::Get();
sampler->SuppressRandomnessForTest(true);
sampler->RecordAlloc(reinterpret_cast<void*>(0x1337), 42000,
sampler->RecordAlloc(reinterpret_cast<void*>(0x1337), kAllocationSize,
base::PoissonAllocationSampler::kMalloc, nullptr);
sampler->RecordAlloc(reinterpret_cast<void*>(0x7331), kAllocationSize,
base::PoissonAllocationSampler::kMalloc, nullptr);
do {
task_runner->FastForwardBy(base::TimeDelta::FromHours(1));
......
......@@ -270,7 +270,7 @@ void ThreadProfiler::StartPeriodicSamplingCollection() {
std::make_unique<CallStackProfileBuilder>(
CallStackProfileParams(GetProcess(), thread_,
CallStackProfileParams::PERIODIC_COLLECTION),
work_id_recorder_.get(),
work_id_recorder_.get(), nullptr,
base::BindOnce(&ThreadProfiler::OnPeriodicCollectionCompleted,
owning_thread_task_runner_,
weak_factory_.GetWeakPtr())));
......
......@@ -279,12 +279,10 @@ source_set("child_call_stack_profile_builder") {
public = [
"call_stack_profile_builder.h",
"child_call_stack_profile_collector.h",
"legacy_call_stack_profile_builder.h",
]
sources = [
"call_stack_profile_builder.cc",
"child_call_stack_profile_collector.cc",
"legacy_call_stack_profile_builder.cc",
]
public_deps = [
":call_stack_profile_params",
......@@ -375,7 +373,6 @@ source_set("unit_tests") {
"field_trials_provider_unittest.cc",
"file_metrics_provider_unittest.cc",
"histogram_encoder_unittest.cc",
"legacy_call_stack_profile_builder_unittest.cc",
"machine_id_provider_win_unittest.cc",
"metrics_log_manager_unittest.cc",
"metrics_log_store_unittest.cc",
......
......@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
#include <tuple>
#include <utility>
#include "base/files/file_path.h"
......@@ -48,8 +49,10 @@ uint64_t HashModuleFilename(const base::FilePath& filename) {
CallStackProfileBuilder::CallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder,
const MetadataRecorder* metadata_recorder,
base::OnceClosure completed_callback)
: work_id_recorder_(work_id_recorder),
metadata_recorder_(metadata_recorder),
profile_start_time_(base::TimeTicks::Now()) {
completed_callback_ = std::move(completed_callback);
sampled_profile_.set_process(
......@@ -127,6 +130,24 @@ void CallStackProfileBuilder::OnSampleCompleted(
stack_sample_proto->set_stack_index(stack_loc->second);
if (is_continued_work_)
stack_sample_proto->set_continued_work(is_continued_work_);
// TODO(crbug.com/913570): Update metadata recording to not heap allocate
// and move to RecordMetadata().
if (metadata_recorder_) {
uint64_t item_hash;
int64_t item_value;
std::tie(item_hash, item_value) = metadata_recorder_->GetHashAndValue();
int next_item_index = call_stack_profile->metadata_name_hash_size();
auto result = metadata_hashes_cache_.emplace(item_hash, next_item_index);
if (result.second)
call_stack_profile->add_metadata_name_hash(item_hash);
CallStackProfile::MetadataItem* item = stack_sample_proto->add_metadata();
// TODO(crbug.com/913570): Only add metadata items if different than
// the value for the previous sample, per
// https://cs.chromium.org/chromium/src/third_party/metrics_proto/call_stack_profile.proto?rcl=8811ddb099&l=108-110.
item->set_name_hash_index(result.first->second);
item->set_value(item_value);
}
}
void CallStackProfileBuilder::OnProfileCompleted(
......
......@@ -7,9 +7,12 @@
#include <limits>
#include <map>
#include <unordered_map>
#include <utility>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/sampling_heap_profiler/module_cache.h"
#include "base/time/time.h"
......@@ -36,6 +39,17 @@ class WorkIdRecorder {
WorkIdRecorder& operator=(const WorkIdRecorder&) = delete;
};
// Records a metadata item to associate with the sample.
// TODO(crbug.com/913570): Extend to support multiple metadata items per sample.
class MetadataRecorder {
public:
MetadataRecorder() = default;
virtual ~MetadataRecorder() = default;
virtual std::pair<uint64_t, int64_t> GetHashAndValue() const = 0;
DISALLOW_COPY_AND_ASSIGN(MetadataRecorder);
};
// An instance of the class is meant to be passed to base::StackSamplingProfiler
// to collect profiles. The profiles collected are uploaded via the metrics log.
//
......@@ -54,6 +68,7 @@ class CallStackProfileBuilder
explicit CallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder = nullptr,
const MetadataRecorder* metadata_recorder = nullptr,
base::OnceClosure completed_callback = base::OnceClosure());
~CallStackProfileBuilder() override;
......@@ -91,6 +106,7 @@ class CallStackProfileBuilder
unsigned int last_work_id_ = std::numeric_limits<unsigned int>::max();
bool is_continued_work_ = false;
const WorkIdRecorder* const work_id_recorder_;
const MetadataRecorder* const metadata_recorder_;
// The SampledProfile protobuf message which contains the collected stack
// samples.
......@@ -100,7 +116,7 @@ class CallStackProfileBuilder
std::map<const CallStackProfile::Stack*, int, StackComparer> stack_index_;
// The indexes of modules, indexed by module's base_address.
std::map<uintptr_t, size_t> module_index_;
std::unordered_map<uintptr_t, size_t> module_index_;
// The distinct modules in the current profile.
std::vector<base::ModuleCache::Module> modules_;
......@@ -111,6 +127,9 @@ class CallStackProfileBuilder
// The start time of a profile collection.
const base::TimeTicks profile_start_time_;
// Maps metadata hash to index in |metadata_name_hash| array.
std::unordered_map<uint64_t, int> metadata_hashes_cache_;
DISALLOW_COPY_AND_ASSIGN(CallStackProfileBuilder);
};
......
......@@ -33,6 +33,7 @@ class TestingCallStackProfileBuilder : public CallStackProfileBuilder {
TestingCallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder = nullptr,
const MetadataRecorder* metadata_recorder = nullptr,
base::OnceClosure completed_callback = base::OnceClosure());
~TestingCallStackProfileBuilder() override;
......@@ -51,9 +52,11 @@ class TestingCallStackProfileBuilder : public CallStackProfileBuilder {
TestingCallStackProfileBuilder::TestingCallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder,
const MetadataRecorder* metadata_recorder,
base::OnceClosure completed_callback)
: CallStackProfileBuilder(profile_params,
work_id_recorder,
metadata_recorder,
std::move(completed_callback)) {}
TestingCallStackProfileBuilder::~TestingCallStackProfileBuilder() = default;
......@@ -71,7 +74,7 @@ TEST(CallStackProfileBuilderTest, ProfilingCompleted) {
EXPECT_CALL(mock_closure, Run()).Times(1);
auto profile_builder = std::make_unique<TestingCallStackProfileBuilder>(
kProfileParams, nullptr, mock_closure.Get());
kProfileParams, nullptr, nullptr, mock_closure.Get());
#if defined(OS_WIN)
uint64_t module_md5 = 0x46C3E4166659AC02ULL;
......@@ -406,4 +409,52 @@ TEST(CallStackProfileBuilderTest, WorkIds) {
EXPECT_TRUE(profile.stack_sample(4).continued_work());
}
TEST(CallStackProfileBuilderTest, MetadataRecorder) {
class TestMetadataRecorder : public MetadataRecorder {
public:
std::pair<uint64_t, int64_t> GetHashAndValue() const override {
return std::make_pair(0x5A105E8B9D40E132ull, current_value);
}
int64_t current_value;
};
TestMetadataRecorder metadata_recorder;
auto profile_builder = std::make_unique<TestingCallStackProfileBuilder>(
kProfileParams, nullptr, &metadata_recorder);
#if defined(OS_WIN)
base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
#else
base::FilePath module_path("/some/path/to/chrome");
#endif
Module module = {0x1000, "1", module_path};
Frame frame = {0x1000 + 0x10, module};
metadata_recorder.current_value = 5;
profile_builder->OnSampleCompleted({frame});
metadata_recorder.current_value = 8;
profile_builder->OnSampleCompleted({frame});
profile_builder->OnProfileCompleted(base::TimeDelta::FromMilliseconds(500),
base::TimeDelta::FromMilliseconds(100));
const SampledProfile& proto = profile_builder->test_sampled_profile();
ASSERT_TRUE(proto.has_call_stack_profile());
const CallStackProfile& profile = proto.call_stack_profile();
ASSERT_EQ(2, profile.stack_sample_size());
EXPECT_EQ(1, profile.stack_sample(0).metadata_size());
EXPECT_EQ(1, profile.stack_sample(1).metadata_size());
ASSERT_EQ(1, profile.metadata_name_hash_size());
EXPECT_EQ(0x5A105E8B9D40E132ull, profile.metadata_name_hash(0));
EXPECT_EQ(0, profile.stack_sample(0).metadata(0).name_hash_index());
EXPECT_EQ(5, profile.stack_sample(0).metadata(0).value());
EXPECT_EQ(0, profile.stack_sample(1).metadata(0).name_hash_index());
EXPECT_EQ(8, profile.stack_sample(1).metadata(0).value());
}
} // namespace metrics
// 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 COMPONENTS_METRICS_LEGACY_CALL_STACK_PROFILE_BUILDER_H_
#define COMPONENTS_METRICS_LEGACY_CALL_STACK_PROFILE_BUILDER_H_
#include <map>
#include <vector>
#include "base/callback.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/sampling_heap_profiler/module_cache.h"
#include "base/time/time.h"
#include "components/metrics/call_stack_profile_params.h"
#include "components/metrics/child_call_stack_profile_collector.h"
#include "third_party/metrics_proto/sampled_profile.pb.h"
namespace metrics {
// An instance of the class is meant to be passed to base::StackSamplingProfiler
// to collect profiles. The profiles collected are uploaded via the metrics log.
//
// This uses the legacy Sample encoding rather than the new StackSample
// encoding.
class LegacyCallStackProfileBuilder
: public base::StackSamplingProfiler::ProfileBuilder {
public:
// Frame represents an individual sampled stack frame with module information.
struct Frame {
Frame(uintptr_t instruction_pointer, size_t module_index);
~Frame();
// Default constructor to satisfy IPC macros. Do not use explicitly.
Frame();
// The sampled instruction pointer within the function.
uintptr_t instruction_pointer;
// Index of the module in the associated vector of mofules. We don't
// represent module state directly here to save space.
size_t module_index;
};
// Sample represents a set of stack frames with some extra information.
struct Sample {
Sample();
Sample(const Sample& sample);
~Sample();
// These constructors are used only during testing.
Sample(const Frame& frame);
Sample(const std::vector<Frame>& frames);
// The entire stack frame when the sample is taken.
std::vector<Frame> frames;
// A bit-field indicating which process milestones have passed. This can be
// used to tell where in the process lifetime the samples are taken. Just
// as a "lifetime" can only move forward, these bits mark the milestones of
// the processes life as they occur. Bits can be set but never reset. The
// actual definition of the individual bits is left to the user of this
// module.
uint32_t process_milestones = 0;
};
// These milestones of a process lifetime can be passed as process "mile-
// stones" to LegacyCallStackProfileBuilder::SetProcessMilestone(). Be sure to
// update the translation constants at the top of the .cc file when this is
// changed.
enum Milestones : int {
MAIN_LOOP_START,
MAIN_NAVIGATION_START,
MAIN_NAVIGATION_FINISHED,
FIRST_NONEMPTY_PAINT,
SHUTDOWN_START,
MILESTONES_MAX_VALUE
};
// |completed_callback| is made when sampling a profile completes. Other
// threads, including the UI thread, may block on callback completion so this
// should run as quickly as possible.
//
// IMPORTANT NOTE: The callback is invoked on a thread the profiler
// constructs, rather than on the thread used to construct the profiler, and
// thus the callback must be callable on any thread.
explicit LegacyCallStackProfileBuilder(
const CallStackProfileParams& profile_params,
base::OnceClosure completed_callback = base::OnceClosure());
~LegacyCallStackProfileBuilder() override;
// base::StackSamplingProfiler::ProfileBuilder:
void RecordMetadata() override;
void OnSampleCompleted(
std::vector<base::StackSamplingProfiler::Frame> frames) override;
void OnProfileCompleted(base::TimeDelta profile_duration,
base::TimeDelta sampling_period) override;
// The function is used by sampling heap profiler. Its samples already come
// with different counts.
void OnSampleCompleted(std::vector<base::StackSamplingProfiler::Frame> frames,
size_t count);
// Sets the callback to use for reporting browser process profiles. This
// indirection is required to avoid a dependency on unnecessary metrics code
// in child processes.
static void SetBrowserProcessReceiverCallback(
const base::RepeatingCallback<void(base::TimeTicks, SampledProfile)>&
callback);
// Sets the current system state that is recorded with each captured stack
// frame. This is thread-safe so can be called from anywhere. The parameter
// value should be from an enumeration of the appropriate type with values
// ranging from 0 to 31, inclusive. This sets bits within Sample field of
// |process_milestones|. The actual meanings of these bits are defined
// (globally) by the caller(s).
static void SetProcessMilestone(int milestone);
// Sets the CallStackProfileCollector interface from |browser_interface|.
// This function must be called within child processes.
static void SetParentProfileCollectorForChildProcess(
metrics::mojom::CallStackProfileCollectorPtr browser_interface);
protected:
// Test seam.
virtual void PassProfilesToMetricsProvider(SampledProfile sampled_profile);
private:
// The collected stack samples in proto buffer message format.
CallStackProfile proto_profile_;
// The process milestones to use for the next sample.
uint32_t process_milestones_;
// The indexes of samples, indexed by the sample.
std::map<Sample, int> sample_index_;
// The indexes of modules, indexed by module's base_address.
std::map<uintptr_t, size_t> module_index_;
// The distinct modules in the current profile.
std::vector<base::ModuleCache::Module> modules_;
// The process milestones of a previous sample.
uint32_t milestones_ = 0;
// Callback made when sampling a profile completes.
base::OnceClosure completed_callback_;
// The parameters associated with the sampled profile.
const CallStackProfileParams profile_params_;
// The start time of a profile collection.
const base::TimeTicks profile_start_time_;
DISALLOW_COPY_AND_ASSIGN(LegacyCallStackProfileBuilder);
};
} // namespace metrics
#endif // COMPONENTS_METRICS_LEGACY_CALL_STACK_PROFILE_BUILDER_H_
......@@ -21,7 +21,6 @@
#include "base/threading/platform_thread.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/metrics/legacy_call_stack_profile_builder.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/startup_metric_utils/browser/pref_names.h"
......@@ -579,8 +578,6 @@ void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
RecordHardFaultHistogram();
// Record timing of the browser message-loop start time.
metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
metrics::LegacyCallStackProfileBuilder::MAIN_LOOP_START);
if (!is_first_run && !g_process_creation_ticks.is_null()) {
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserMessageLoopStartTime",
......@@ -702,8 +699,6 @@ void RecordFirstWebContentsNonEmptyPaint(
if (!ShouldLogStartupHistogram())
return;
metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
metrics::LegacyCallStackProfileBuilder::FIRST_NONEMPTY_PAINT);
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.NonEmptyPaint2",
g_process_creation_ticks, now);
......@@ -727,8 +722,6 @@ void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks,
if (!ShouldLogStartupHistogram())
return;
metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
metrics::LegacyCallStackProfileBuilder::MAIN_NAVIGATION_START);
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100,
"Startup.FirstWebContents.MainNavigationStart", g_process_creation_ticks,
......@@ -758,8 +751,6 @@ void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks) {
if (!ShouldLogStartupHistogram())
return;
metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
metrics::LegacyCallStackProfileBuilder::MAIN_NAVIGATION_FINISHED);
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100,
"Startup.FirstWebContents.MainNavigationFinished",
......
......@@ -863,8 +863,6 @@ int BrowserMainLoop::PreCreateThreads() {
}
void BrowserMainLoop::PreShutdown() {
parts_->PreShutdown();
ui::Clipboard::OnPreShutdownForCurrentThread();
}
......
......@@ -99,9 +99,6 @@ class CONTENT_EXPORT BrowserMainParts {
// threads are stopped.
virtual void PostMainMessageLoopRun() {}
// Called when shutdown is about to begin.
virtual void PreShutdown() {}
// Called as the very last part of shutdown, after threads have been
// stopped and destroyed.
virtual void PostDestroyThreads() {}
......
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