Commit d6363e47 authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

[sampling heap profiler] Extract Poisson sampler into a separate class.

Make Poisson sampler a separate class that is responsible for listening
for allocation and doing the sampling with given sampling interval.

SamplingHeapProfiler is now an observer of PoissonAllocationObserver.
Once a sample added it record the native stack and stores the sample
in the map. The list of recorded samples can then be retrieved by clients.

TBR=ajwong@chromium.org
BUG=803276

Change-Id: I1e568b9839d9cc0099704ba1b9f047c14a46a0ee
Reviewed-on: https://chromium-review.googlesource.com/1189713Reviewed-by: default avatarAlexei Filippov <alph@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Commit-Queue: Alexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#586369}
parent fef1e34b
...@@ -731,6 +731,8 @@ jumbo_component("base") { ...@@ -731,6 +731,8 @@ jumbo_component("base") {
"sampling_heap_profiler/module_cache.h", "sampling_heap_profiler/module_cache.h",
"sampling_heap_profiler/module_cache_mac.cc", "sampling_heap_profiler/module_cache_mac.cc",
"sampling_heap_profiler/module_cache_win.cc", "sampling_heap_profiler/module_cache_win.cc",
"sampling_heap_profiler/poisson_allocation_sampler.cc",
"sampling_heap_profiler/poisson_allocation_sampler.h",
"sampling_heap_profiler/sampling_heap_profiler.cc", "sampling_heap_profiler/sampling_heap_profiler.cc",
"sampling_heap_profiler/sampling_heap_profiler.h", "sampling_heap_profiler/sampling_heap_profiler.h",
"scoped_clear_errno.h", "scoped_clear_errno.h",
...@@ -3094,7 +3096,7 @@ if (is_android) { ...@@ -3094,7 +3096,7 @@ if (is_android) {
} }
android_library("base_junit_test_support") { android_library("base_junit_test_support") {
# Plaform checks are broken for Robolectric. # Platform checks are broken for Robolectric.
bypass_platform_checks = true bypass_platform_checks = true
testonly = true testonly = true
java_files = [ java_files = [
......
This diff is collapsed.
// 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 BASE_SAMPLING_HEAP_PROFILER_POISSON_ALLOCATION_SAMPLER_H_
#define BASE_SAMPLING_HEAP_PROFILER_POISSON_ALLOCATION_SAMPLER_H_
#include <memory>
#include <vector>
#include "base/base_export.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_local.h"
namespace base {
template <typename T>
class NoDestructor;
class LockFreeAddressHashSet;
// This singleton class implements Poisson sampling of the incoming allocations
// stream. It hooks onto base::allocator and base::PartitionAlloc.
// An extra custom allocator can be hooked via SetHooksInstallCallback method.
// The only control parameter is sampling interval that controls average value
// of the sampling intervals. The actual intervals between samples are
// randomized using Poisson distribution to mitigate patterns in the allocation
// stream.
// Once accumulated allocation sizes fill up the current sample interval,
// a sample is generated and sent to the observers via |SampleAdded| call.
// When the corresponding memory that triggered the sample is freed observers
// get notified with |SampleRemoved| call.
//
class BASE_EXPORT PoissonAllocationSampler {
public:
enum AllocatorType : uint32_t { kMalloc, kPartitionAlloc, kBlinkGC, kMax };
class SamplesObserver {
public:
virtual ~SamplesObserver() = default;
virtual void SampleAdded(void* address,
size_t size,
size_t total,
AllocatorType type,
const char* context) = 0;
virtual void SampleRemoved(void* address) = 0;
};
// Must be called early during the process initialization. It creates and
// reserves a TLS slot.
static void Init();
// This is an entry point for plugging in an external allocator.
// Profiler will invoke the provided callback upon initialization.
// The callback should install hooks onto the corresponding memory allocator
// and make them invoke PoissonAllocationSampler::RecordAlloc and
// PoissonAllocationSampler::RecordFree upon corresponding allocation events.
//
// If the method is called after profiler is initialized, the callback
// is invoked right away.
static void SetHooksInstallCallback(void (*hooks_install_callback)());
void AddSamplesObserver(SamplesObserver*);
void RemoveSamplesObserver(SamplesObserver*);
void Start();
void Stop();
void SetSamplingInterval(size_t sampling_interval);
void SuppressRandomnessForTest(bool suppress);
static void RecordAlloc(void* address,
size_t,
AllocatorType,
const char* context);
static void RecordFree(void* address);
static PoissonAllocationSampler* Get();
private:
PoissonAllocationSampler();
~PoissonAllocationSampler() = delete;
static void InstallAllocatorHooksOnce();
static bool InstallAllocatorHooks();
static size_t GetNextSampleInterval(size_t base_interval);
static LockFreeAddressHashSet& sampled_addresses_set();
void DoRecordAlloc(size_t total_allocated,
size_t allocation_size,
void* address,
AllocatorType type,
const char* context);
void DoRecordFree(void* address);
void BalanceAddressesHashSet();
ThreadLocalBoolean entered_;
Lock mutex_;
std::vector<std::unique_ptr<LockFreeAddressHashSet>> sampled_addresses_stack_;
std::vector<SamplesObserver*> observers_;
static PoissonAllocationSampler* instance_;
friend class NoDestructor<PoissonAllocationSampler>;
DISALLOW_COPY_AND_ASSIGN(PoissonAllocationSampler);
};
} // namespace base
#endif // BASE_SAMPLING_HEAP_PROFILER_POISSON_ALLOCATION_SAMPLER_H_
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
#ifndef BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_ #ifndef BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_
#define BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_ #define BASE_SAMPLING_HEAP_PROFILER_SAMPLING_HEAP_PROFILER_H_
#include <memory>
#include <stack>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/threading/thread_local.h" #include "base/threading/thread_local.h"
...@@ -20,17 +19,13 @@ namespace base { ...@@ -20,17 +19,13 @@ namespace base {
template <typename T> template <typename T>
class NoDestructor; class NoDestructor;
class LockFreeAddressHashSet;
// The class implements sampling profiling of native memory heap. // The class implements sampling profiling of native memory heap.
// It hooks on base::allocator and base::PartitionAlloc. // It uses PoissonAllocationSampler to aggregate the heap allocations and
// When started it selects and records allocation samples based on // record samples.
// the sampling_interval parameter.
// The recorded samples can then be retrieved using GetSamples method. // The recorded samples can then be retrieved using GetSamples method.
class BASE_EXPORT SamplingHeapProfiler { class BASE_EXPORT SamplingHeapProfiler
: private PoissonAllocationSampler::SamplesObserver {
public: public:
enum AllocatorType : uint32_t { kMalloc, kPartitionAlloc, kBlinkGC, kMax };
class BASE_EXPORT Sample { class BASE_EXPORT Sample {
public: public:
Sample(const Sample&); Sample(const Sample&);
...@@ -48,80 +43,33 @@ class BASE_EXPORT SamplingHeapProfiler { ...@@ -48,80 +43,33 @@ class BASE_EXPORT SamplingHeapProfiler {
uint32_t ordinal; uint32_t ordinal;
}; };
class SamplesObserver {
public:
virtual ~SamplesObserver() = default;
virtual void SampleAdded(void* address,
size_t size,
size_t total,
AllocatorType type,
const char* context) = 0;
virtual void SampleRemoved(void* address) = 0;
};
// Must be called early during the process initialization. It creates and
// reserves a TLS slot.
static void InitTLSSlot();
// This is an entry point for plugging in an external allocator.
// Profiler will invoke the provided callback upon initialization.
// The callback should install hooks onto the corresponding memory allocator
// and make them invoke SamplingHeapProfiler::RecordAlloc and
// SamplingHeapProfiler::RecordFree upon corresponding allocation events.
//
// If the method is called after profiler is initialized, the callback
// is invoked right away.
static void SetHooksInstallCallback(void (*hooks_install_callback)());
void AddSamplesObserver(SamplesObserver*);
void RemoveSamplesObserver(SamplesObserver*);
uint32_t Start(); uint32_t Start();
void Stop(); void Stop();
void SetSamplingInterval(size_t sampling_interval); void SetSamplingInterval(size_t sampling_interval);
void SuppressRandomnessForTest(bool suppress);
std::vector<Sample> GetSamples(uint32_t profile_id); std::vector<Sample> GetSamples(uint32_t profile_id);
static void RecordAlloc(void* address, static void Init();
size_t, static SamplingHeapProfiler* Get();
AllocatorType,
const char* context,
uint32_t skip_frames = 0);
static void RecordFree(void* address);
static SamplingHeapProfiler* GetInstance();
private: private:
SamplingHeapProfiler(); SamplingHeapProfiler();
~SamplingHeapProfiler() = delete; ~SamplingHeapProfiler() override;
static void InstallAllocatorHooksOnce(); // PoissonAllocationSampler::SamplesObserver
static bool InstallAllocatorHooks(); void SampleAdded(void* address,
static size_t GetNextSampleInterval(size_t base_interval); size_t size,
size_t total,
void DoRecordAlloc(size_t total_allocated, PoissonAllocationSampler::AllocatorType type,
size_t allocation_size, const char* context) override;
void* address, void SampleRemoved(void* address) override;
AllocatorType type,
const char* context, ThreadLocalBoolean entered_;
uint32_t skip_frames); Lock mutex_;
void DoRecordFree(void* address);
void RecordStackTrace(Sample*, uint32_t skip_frames);
static LockFreeAddressHashSet& sampled_addresses_set();
void BalanceAddressesHashSet();
base::ThreadLocalBoolean entered_;
base::Lock mutex_;
std::stack<std::unique_ptr<LockFreeAddressHashSet>> sampled_addresses_stack_;
std::unordered_map<void*, Sample> samples_; std::unordered_map<void*, Sample> samples_;
std::vector<SamplesObserver*> observers_;
uint32_t last_sample_ordinal_ = 1; uint32_t last_sample_ordinal_ = 1;
static SamplingHeapProfiler* instance_; friend class NoDestructor<SamplingHeapProfiler>;
friend class base::NoDestructor<SamplingHeapProfiler>;
DISALLOW_COPY_AND_ASSIGN(SamplingHeapProfiler); DISALLOW_COPY_AND_ASSIGN(SamplingHeapProfiler);
}; };
......
...@@ -22,14 +22,14 @@ class SamplingHeapProfilerTest : public ::testing::Test { ...@@ -22,14 +22,14 @@ class SamplingHeapProfilerTest : public ::testing::Test {
#endif #endif
}; };
class SamplesCollector : public SamplingHeapProfiler::SamplesObserver { class SamplesCollector : public PoissonAllocationSampler::SamplesObserver {
public: public:
explicit SamplesCollector(size_t watch_size) : watch_size_(watch_size) {} explicit SamplesCollector(size_t watch_size) : watch_size_(watch_size) {}
void SampleAdded(void* address, void SampleAdded(void* address,
size_t size, size_t size,
size_t, size_t,
SamplingHeapProfiler::AllocatorType, PoissonAllocationSampler::AllocatorType,
const char*) override { const char*) override {
if (sample_added || size != watch_size_) if (sample_added || size != watch_size_)
return; return;
...@@ -50,18 +50,18 @@ class SamplesCollector : public SamplingHeapProfiler::SamplesObserver { ...@@ -50,18 +50,18 @@ class SamplesCollector : public SamplingHeapProfiler::SamplesObserver {
void* sample_address_ = nullptr; void* sample_address_ = nullptr;
}; };
TEST_F(SamplingHeapProfilerTest, CollectSamples) { TEST_F(SamplingHeapProfilerTest, SampleObserver) {
SamplingHeapProfiler::InitTLSSlot(); PoissonAllocationSampler::Init();
SamplesCollector collector(10000); SamplesCollector collector(10000);
SamplingHeapProfiler* profiler = SamplingHeapProfiler::GetInstance(); auto* sampler = PoissonAllocationSampler::Get();
profiler->SuppressRandomnessForTest(true); sampler->SuppressRandomnessForTest(true);
profiler->SetSamplingInterval(1024); sampler->SetSamplingInterval(1024);
profiler->Start(); sampler->Start();
profiler->AddSamplesObserver(&collector); sampler->AddSamplesObserver(&collector);
void* volatile p = malloc(10000); void* volatile p = malloc(10000);
free(p); free(p);
profiler->Stop(); sampler->Stop();
profiler->RemoveSamplesObserver(&collector); sampler->RemoveSamplesObserver(&collector);
CHECK(collector.sample_added); CHECK(collector.sample_added);
CHECK(collector.sample_removed); CHECK(collector.sample_removed);
} }
...@@ -102,9 +102,9 @@ class MyThread2 : public SimpleThread { ...@@ -102,9 +102,9 @@ class MyThread2 : public SimpleThread {
}; };
void CheckAllocationPattern(void (*allocate_callback)()) { void CheckAllocationPattern(void (*allocate_callback)()) {
SamplingHeapProfiler::InitTLSSlot(); SamplingHeapProfiler::Init();
SamplingHeapProfiler* profiler = SamplingHeapProfiler::GetInstance(); auto* profiler = SamplingHeapProfiler::Get();
profiler->SuppressRandomnessForTest(false); PoissonAllocationSampler::Get()->SuppressRandomnessForTest(false);
profiler->SetSamplingInterval(10240); profiler->SetSamplingInterval(10240);
base::TimeTicks t0 = base::TimeTicks::Now(); base::TimeTicks t0 = base::TimeTicks::Now();
std::map<size_t, size_t> sums; std::map<size_t, size_t> sums;
......
...@@ -29,7 +29,7 @@ class TLSDestructionCheckerForX11; ...@@ -29,7 +29,7 @@ class TLSDestructionCheckerForX11;
namespace base { namespace base {
class SamplingHeapProfiler; class PoissonAllocationSampler;
namespace debug { namespace debug {
class GlobalActivityTracker; class GlobalActivityTracker;
...@@ -162,7 +162,7 @@ class BASE_EXPORT ThreadLocalStorage { ...@@ -162,7 +162,7 @@ class BASE_EXPORT ThreadLocalStorage {
// thread destruction. Attempting to call Slot::Get() during destruction is // thread destruction. Attempting to call Slot::Get() during destruction is
// disallowed and will hit a DCHECK. Any code that relies on TLS during thread // disallowed and will hit a DCHECK. Any code that relies on TLS during thread
// destruction must first check this method before calling Slot::Get(). // destruction must first check this method before calling Slot::Get().
friend class base::SamplingHeapProfiler; friend class base::PoissonAllocationSampler;
friend class base::internal::ThreadLocalStorageTestInternal; friend class base::internal::ThreadLocalStorageTestInternal;
friend class base::trace_event::MallocDumpProvider; friend class base::trace_event::MallocDumpProvider;
friend class debug::GlobalActivityTracker; friend class debug::GlobalActivityTracker;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/process/process_handle.h" #include "base/process/process_handle.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h" #include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -564,7 +564,7 @@ bool TestDriver::RunTest(const Options& options) { ...@@ -564,7 +564,7 @@ bool TestDriver::RunTest(const Options& options) {
options_ = options; options_ = options;
if (options_.should_sample) if (options_.should_sample)
base::SamplingHeapProfiler::GetInstance()->SuppressRandomnessForTest(true); base::PoissonAllocationSampler::Get()->SuppressRandomnessForTest(true);
running_on_ui_thread_ = running_on_ui_thread_ =
content::BrowserThread::CurrentlyOn(content::BrowserThread::UI); content::BrowserThread::CurrentlyOn(content::BrowserThread::UI);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h" #include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/threading/thread_id_name_manager.h" #include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_local.h" #include "base/threading/thread_local.h"
...@@ -683,7 +683,7 @@ class FrameSerializer { ...@@ -683,7 +683,7 @@ class FrameSerializer {
} // namespace } // namespace
void InitTLSSlot() { void InitTLSSlot() {
base::SamplingHeapProfiler::InitTLSSlot(); base::PoissonAllocationSampler::Init();
InitializeReentrancyKey(); InitializeReentrancyKey();
ignore_result(ShimStateTLS()); ignore_result(ShimStateTLS());
} }
......
...@@ -9,17 +9,17 @@ ...@@ -9,17 +9,17 @@
namespace heap_profiling { namespace heap_profiling {
namespace { namespace {
AllocatorType ConvertType(base::SamplingHeapProfiler::AllocatorType type) { AllocatorType ConvertType(base::PoissonAllocationSampler::AllocatorType type) {
static_assert( static_assert(static_cast<uint32_t>(
static_cast<uint32_t>(base::SamplingHeapProfiler::AllocatorType::kMax) == base::PoissonAllocationSampler::AllocatorType::kMax) ==
static_cast<uint32_t>(AllocatorType::kCount), static_cast<uint32_t>(AllocatorType::kCount),
"AllocatorType lengths do not match."); "AllocatorType lengths do not match.");
switch (type) { switch (type) {
case base::SamplingHeapProfiler::AllocatorType::kMalloc: case base::PoissonAllocationSampler::AllocatorType::kMalloc:
return AllocatorType::kMalloc; return AllocatorType::kMalloc;
case base::SamplingHeapProfiler::AllocatorType::kPartitionAlloc: case base::PoissonAllocationSampler::AllocatorType::kPartitionAlloc:
return AllocatorType::kPartitionAlloc; return AllocatorType::kPartitionAlloc;
case base::SamplingHeapProfiler::AllocatorType::kBlinkGC: case base::PoissonAllocationSampler::AllocatorType::kBlinkGC:
return AllocatorType::kOilpan; return AllocatorType::kOilpan;
default: default:
NOTREACHED(); NOTREACHED();
...@@ -30,24 +30,24 @@ AllocatorType ConvertType(base::SamplingHeapProfiler::AllocatorType type) { ...@@ -30,24 +30,24 @@ AllocatorType ConvertType(base::SamplingHeapProfiler::AllocatorType type) {
} // namespace } // namespace
SamplingProfilerWrapper::SamplingProfilerWrapper() { SamplingProfilerWrapper::SamplingProfilerWrapper() {
base::SamplingHeapProfiler::GetInstance()->AddSamplesObserver(this); base::PoissonAllocationSampler::Get()->AddSamplesObserver(this);
} }
SamplingProfilerWrapper::~SamplingProfilerWrapper() { SamplingProfilerWrapper::~SamplingProfilerWrapper() {
base::SamplingHeapProfiler::GetInstance()->RemoveSamplesObserver(this); base::PoissonAllocationSampler::Get()->RemoveSamplesObserver(this);
} }
void SamplingProfilerWrapper::StartProfiling(size_t sampling_rate) { void SamplingProfilerWrapper::StartProfiling(size_t sampling_rate) {
auto* profiler = base::SamplingHeapProfiler::GetInstance(); auto* sampler = base::PoissonAllocationSampler::Get();
profiler->SetSamplingInterval(sampling_rate); sampler->SetSamplingInterval(sampling_rate);
profiler->Start(); sampler->Start();
} }
void SamplingProfilerWrapper::SampleAdded( void SamplingProfilerWrapper::SampleAdded(
void* address, void* address,
size_t size, size_t size,
size_t total, size_t total,
base::SamplingHeapProfiler::AllocatorType type, base::PoissonAllocationSampler::AllocatorType type,
const char* context) { const char* context) {
RecordAndSendAlloc(ConvertType(type), address, size, context); RecordAndSendAlloc(ConvertType(type), address, size, context);
} }
......
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
#include <memory> #include <memory>
#include "base/sampling_heap_profiler/sampling_heap_profiler.h" #include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
namespace heap_profiling { namespace heap_profiling {
class SamplingProfilerWrapper class SamplingProfilerWrapper
: private base::SamplingHeapProfiler::SamplesObserver { : private base::PoissonAllocationSampler::SamplesObserver {
public: public:
SamplingProfilerWrapper(); SamplingProfilerWrapper();
~SamplingProfilerWrapper() override; ~SamplingProfilerWrapper() override;
...@@ -20,11 +20,11 @@ class SamplingProfilerWrapper ...@@ -20,11 +20,11 @@ class SamplingProfilerWrapper
void StartProfiling(size_t sampling_rate); void StartProfiling(size_t sampling_rate);
private: private:
// base::SamplingHeapProfiler::SamplesObserver // base::PoissonAllocationSampler::SamplesObserver
void SampleAdded(void* address, void SampleAdded(void* address,
size_t size, size_t size,
size_t total, size_t total,
base::SamplingHeapProfiler::AllocatorType, base::PoissonAllocationSampler::AllocatorType,
const char* context) override; const char* context) override;
void SampleRemoved(void* address) override; void SampleRemoved(void* address) override;
}; };
......
...@@ -75,10 +75,9 @@ int BrowserMainRunnerImpl::Initialize(const MainFunctionParams& parameters) { ...@@ -75,10 +75,9 @@ int BrowserMainRunnerImpl::Initialize(const MainFunctionParams& parameters) {
const base::TimeTicks start_time_step1 = base::TimeTicks::Now(); const base::TimeTicks start_time_step1 = base::TimeTicks::Now();
base::SamplingHeapProfiler::InitTLSSlot(); base::SamplingHeapProfiler::Init();
if (parameters.command_line.HasSwitch(switches::kSamplingHeapProfiler)) { if (parameters.command_line.HasSwitch(switches::kSamplingHeapProfiler)) {
base::SamplingHeapProfiler* profiler = base::SamplingHeapProfiler* profiler = base::SamplingHeapProfiler::Get();
base::SamplingHeapProfiler::GetInstance();
unsigned sampling_interval = 0; unsigned sampling_interval = 0;
bool parsed = bool parsed =
base::StringToUint(parameters.command_line.GetSwitchValueASCII( base::StringToUint(parameters.command_line.GetSwitchValueASCII(
......
...@@ -40,7 +40,7 @@ Response MemoryHandler::GetBrowserSamplingProfile( ...@@ -40,7 +40,7 @@ Response MemoryHandler::GetBrowserSamplingProfile(
std::unique_ptr<Array<Memory::SamplingProfileNode>> samples = std::unique_ptr<Array<Memory::SamplingProfileNode>> samples =
Array<Memory::SamplingProfileNode>::create(); Array<Memory::SamplingProfileNode>::create();
std::vector<base::SamplingHeapProfiler::Sample> raw_samples = std::vector<base::SamplingHeapProfiler::Sample> raw_samples =
base::SamplingHeapProfiler::GetInstance()->GetSamples(0); base::SamplingHeapProfiler::Get()->GetSamples(0);
for (auto& sample : raw_samples) { for (auto& sample : raw_samples) {
std::unique_ptr<Array<String>> stack = Array<String>::create(); std::unique_ptr<Array<String>> stack = Array<String>::create();
......
...@@ -84,10 +84,9 @@ int RendererMain(const MainFunctionParams& parameters) { ...@@ -84,10 +84,9 @@ int RendererMain(const MainFunctionParams& parameters) {
const base::CommandLine& command_line = parameters.command_line; const base::CommandLine& command_line = parameters.command_line;
base::SamplingHeapProfiler::InitTLSSlot(); base::SamplingHeapProfiler::Init();
if (command_line.HasSwitch(switches::kSamplingHeapProfiler)) { if (command_line.HasSwitch(switches::kSamplingHeapProfiler)) {
base::SamplingHeapProfiler* profiler = base::SamplingHeapProfiler* profiler = base::SamplingHeapProfiler::Get();
base::SamplingHeapProfiler::GetInstance();
unsigned sampling_interval = 0; unsigned sampling_interval = 0;
bool parsed = base::StringToUint( bool parsed = base::StringToUint(
command_line.GetSwitchValueASCII(switches::kSamplingHeapProfiler), command_line.GetSwitchValueASCII(switches::kSamplingHeapProfiler),
......
include_rules = [ include_rules = [
"+base/time/time_override.h", "+base/time/time_override.h",
"+base/sampling_heap_profiler/module_cache.h", "+base/sampling_heap_profiler/module_cache.h",
"+base/sampling_heap_profiler/poisson_allocation_sampler.h",
"+base/sampling_heap_profiler/sampling_heap_profiler.h", "+base/sampling_heap_profiler/sampling_heap_profiler.h",
# for base::GetUniqueIdForProcess # for base::GetUniqueIdForProcess
"+base/process/process_handle.h", "+base/process/process_handle.h",
......
...@@ -81,18 +81,18 @@ Response InspectorMemoryAgent::startSampling( ...@@ -81,18 +81,18 @@ Response InspectorMemoryAgent::startSampling(
in_sampling_interval.fromMaybe(kDefaultNativeMemorySamplingInterval); in_sampling_interval.fromMaybe(kDefaultNativeMemorySamplingInterval);
if (interval <= 0) if (interval <= 0)
return Response::Error("Invalid sampling rate."); return Response::Error("Invalid sampling rate.");
base::SamplingHeapProfiler::GetInstance()->SetSamplingInterval(interval); base::SamplingHeapProfiler::Get()->SetSamplingInterval(interval);
sampling_profile_interval_.Set(interval); sampling_profile_interval_.Set(interval);
if (in_suppressRandomness.fromMaybe(false)) if (in_suppressRandomness.fromMaybe(false))
base::SamplingHeapProfiler::GetInstance()->SuppressRandomnessForTest(true); base::PoissonAllocationSampler::Get()->SuppressRandomnessForTest(true);
profile_id_ = base::SamplingHeapProfiler::GetInstance()->Start(); profile_id_ = base::SamplingHeapProfiler::Get()->Start();
return Response::OK(); return Response::OK();
} }
Response InspectorMemoryAgent::stopSampling() { Response InspectorMemoryAgent::stopSampling() {
if (sampling_profile_interval_.Get() == 0) if (sampling_profile_interval_.Get() == 0)
return Response::Error("Sampling profiler is not started."); return Response::Error("Sampling profiler is not started.");
base::SamplingHeapProfiler::GetInstance()->Stop(); base::SamplingHeapProfiler::Get()->Stop();
sampling_profile_interval_.Clear(); sampling_profile_interval_.Clear();
return Response::OK(); return Response::OK();
} }
...@@ -116,7 +116,7 @@ InspectorMemoryAgent::GetSamplingProfileById(uint32_t id) { ...@@ -116,7 +116,7 @@ InspectorMemoryAgent::GetSamplingProfileById(uint32_t id) {
samples = samples =
protocol::Array<protocol::Memory::SamplingProfileNode>::create(); protocol::Array<protocol::Memory::SamplingProfileNode>::create();
std::vector<base::SamplingHeapProfiler::Sample> raw_samples = std::vector<base::SamplingHeapProfiler::Sample> raw_samples =
base::SamplingHeapProfiler::GetInstance()->GetSamples(id); base::SamplingHeapProfiler::Get()->GetSamples(id);
for (auto& it : raw_samples) { for (auto& it : raw_samples) {
std::unique_ptr<protocol::Array<protocol::String>> stack = std::unique_ptr<protocol::Array<protocol::String>> stack =
......
...@@ -29,7 +29,6 @@ include_rules = [ ...@@ -29,7 +29,6 @@ include_rules = [
"+base/numerics/safe_conversions.h", "+base/numerics/safe_conversions.h",
"+base/rand_util.h", "+base/rand_util.h",
"+base/run_loop.h", "+base/run_loop.h",
"+base/sampling_heap_profiler/sampling_heap_profiler.h",
"+base/strings/pattern.h", "+base/strings/pattern.h",
"+base/strings/string_util.h", "+base/strings/string_util.h",
"+base/strings/stringprintf.h", "+base/strings/stringprintf.h",
......
...@@ -8,6 +8,7 @@ include_rules = [ ...@@ -8,6 +8,7 @@ include_rules = [
# Dependencies. # Dependencies.
"+base/atomicops.h", "+base/atomicops.h",
"+base/bits.h", "+base/bits.h",
"+base/sampling_heap_profiler/poisson_allocation_sampler.h",
"+base/synchronization/lock.h", "+base/synchronization/lock.h",
"+third_party/blink/renderer/platform/bindings", "+third_party/blink/renderer/platform/bindings",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/platform/heap/process_heap.h" #include "third_party/blink/renderer/platform/heap/process_heap.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h" #include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "third_party/blink/renderer/platform/heap/gc_info.h" #include "third_party/blink/renderer/platform/heap/gc_info.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/persistent_node.h" #include "third_party/blink/renderer/platform/heap/persistent_node.h"
...@@ -15,13 +15,13 @@ namespace blink { ...@@ -15,13 +15,13 @@ namespace blink {
namespace { namespace {
void BlinkGCAllocHook(uint8_t* address, size_t size, const char* context) { void BlinkGCAllocHook(uint8_t* address, size_t size, const char* context) {
base::SamplingHeapProfiler::RecordAlloc( base::PoissonAllocationSampler::RecordAlloc(
address, size, base::SamplingHeapProfiler::AllocatorType::kBlinkGC, address, size, base::PoissonAllocationSampler::AllocatorType::kBlinkGC,
context); context);
} }
void BlinkGCFreeHook(uint8_t* address) { void BlinkGCFreeHook(uint8_t* address) {
base::SamplingHeapProfiler::RecordFree(address); base::PoissonAllocationSampler::RecordFree(address);
} }
} // namespace } // namespace
...@@ -33,7 +33,7 @@ void ProcessHeap::Init() { ...@@ -33,7 +33,7 @@ void ProcessHeap::Init() {
GCInfoTable::CreateGlobalTable(); GCInfoTable::CreateGlobalTable();
base::SamplingHeapProfiler::SetHooksInstallCallback([]() { base::PoissonAllocationSampler::SetHooksInstallCallback([]() {
HeapAllocHooks::SetAllocationHook(&BlinkGCAllocHook); HeapAllocHooks::SetAllocationHook(&BlinkGCAllocHook);
HeapAllocHooks::SetFreeHook(&BlinkGCFreeHook); HeapAllocHooks::SetFreeHook(&BlinkGCFreeHook);
}); });
......
...@@ -314,6 +314,7 @@ _CONFIG = [ ...@@ -314,6 +314,7 @@ _CONFIG = [
'paths': ['third_party/blink/renderer/core/inspector/inspector_memory_agent.cc'], 'paths': ['third_party/blink/renderer/core/inspector/inspector_memory_agent.cc'],
'allowed': [ 'allowed': [
'base::ModuleCache', 'base::ModuleCache',
'base::PoissonAllocationSampler',
'base::SamplingHeapProfiler', 'base::SamplingHeapProfiler',
], ],
}, },
......
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