| Index: base/profiler/native_stack_sampler_win.cc
|
| diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc
|
| index e1605109fe960d769523733b2a1190700b250d28..47c14f41470110efea91e5dfb20b9167715da1d2 100644
|
| --- a/base/profiler/native_stack_sampler_win.cc
|
| +++ b/base/profiler/native_stack_sampler_win.cc
|
| @@ -18,6 +18,7 @@
|
| #include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "base/profiler/win32_stack_frame_unwinder.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/stringprintf.h"
|
| @@ -386,6 +387,24 @@ void SuspendThreadAndRecordStack(
|
|
|
| class NativeStackSamplerWin : public NativeStackSampler {
|
| public:
|
| + enum {
|
| + // Intended to hold the largest stack used by Chrome. The default Win32
|
| + // reserved stack size is 1 MB and Chrome Windows threads currently always
|
| + // use the default, but this allows for expansion if it occurs. The size
|
| + // beyond the actual stack size consists of unallocated virtual memory pages
|
| + // so carries little cost (just a bit of wasted address space).
|
| + kStackCopyBufferSize = 2 * 1024 * 1024
|
| + };
|
| +
|
| + class StackBufferWin : public StackBuffer {
|
| + public:
|
| + StackBufferWin() {}
|
| + ~StackBufferWin() override {}
|
| +
|
| + // Buffer to use for copies of the stack.
|
| + unsigned char stack_copy_buffer_[kStackCopyBufferSize];
|
| + };
|
| +
|
| NativeStackSamplerWin(win::ScopedHandle thread_handle,
|
| AnnotateCallback annotator,
|
| NativeStackSamplerTestDelegate* test_delegate);
|
| @@ -394,19 +413,11 @@ class NativeStackSamplerWin : public NativeStackSampler {
|
| // StackSamplingProfiler::NativeStackSampler:
|
| void ProfileRecordingStarting(
|
| std::vector<StackSamplingProfiler::Module>* modules) override;
|
| - void RecordStackSample(StackSamplingProfiler::Sample* sample) override;
|
| - void ProfileRecordingStopped() override;
|
| + void RecordStackSample(StackBuffer* stackbuffer,
|
| + StackSamplingProfiler::Sample* sample) override;
|
| + void ProfileRecordingStopped(StackBuffer* stackbuffer) override;
|
|
|
| private:
|
| - enum {
|
| - // Intended to hold the largest stack used by Chrome. The default Win32
|
| - // reserved stack size is 1 MB and Chrome Windows threads currently always
|
| - // use the default, but this allows for expansion if it occurs. The size
|
| - // beyond the actual stack size consists of unallocated virtual memory pages
|
| - // so carries little cost (just a bit of wasted address space).
|
| - kStackCopyBufferSize = 2 * 1024 * 1024
|
| - };
|
| -
|
| // Attempts to query the module filename, base address, and id for
|
| // |module_handle|, and store them in |module|. Returns true if it succeeded.
|
| static bool GetModuleForHandle(HMODULE module_handle,
|
| @@ -433,10 +444,6 @@ class NativeStackSamplerWin : public NativeStackSampler {
|
| // The stack base address corresponding to |thread_handle_|.
|
| const void* const thread_stack_base_address_;
|
|
|
| - // Buffer to use for copies of the stack. We use the same buffer for all the
|
| - // samples to avoid the overhead of multiple allocations and frees.
|
| - const std::unique_ptr<unsigned char[]> stack_copy_buffer_;
|
| -
|
| // Weak. Points to the modules associated with the profile being recorded
|
| // between ProfileRecordingStarting() and ProfileRecordingStopped().
|
| std::vector<StackSamplingProfiler::Module>* current_modules_;
|
| @@ -456,8 +463,7 @@ NativeStackSamplerWin::NativeStackSamplerWin(
|
| annotator_(annotator),
|
| test_delegate_(test_delegate),
|
| thread_stack_base_address_(
|
| - GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase),
|
| - stack_copy_buffer_(new unsigned char[kStackCopyBufferSize]) {
|
| + GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase) {
|
| DCHECK(annotator_);
|
| }
|
|
|
| @@ -471,20 +477,20 @@ void NativeStackSamplerWin::ProfileRecordingStarting(
|
| }
|
|
|
| void NativeStackSamplerWin::RecordStackSample(
|
| + StackBuffer* stackbuffer,
|
| StackSamplingProfiler::Sample* sample) {
|
| + DCHECK(stackbuffer);
|
| DCHECK(current_modules_);
|
|
|
| - if (!stack_copy_buffer_)
|
| - return;
|
| -
|
| std::vector<RecordedFrame> stack;
|
| - SuspendThreadAndRecordStack(thread_handle_.Get(), thread_stack_base_address_,
|
| - stack_copy_buffer_.get(), kStackCopyBufferSize,
|
| - &stack, annotator_, sample, test_delegate_);
|
| + SuspendThreadAndRecordStack(
|
| + thread_handle_.Get(), thread_stack_base_address_,
|
| + static_cast<StackBufferWin*>(stackbuffer)->stack_copy_buffer_,
|
| + kStackCopyBufferSize, &stack, annotator_, sample, test_delegate_);
|
| CopyToSample(stack, sample, current_modules_);
|
| }
|
|
|
| -void NativeStackSamplerWin::ProfileRecordingStopped() {
|
| +void NativeStackSamplerWin::ProfileRecordingStopped(StackBuffer* stackbuffer) {
|
| current_modules_ = nullptr;
|
| }
|
|
|
| @@ -563,4 +569,9 @@ std::unique_ptr<NativeStackSampler> NativeStackSampler::Create(
|
| return std::unique_ptr<NativeStackSampler>();
|
| }
|
|
|
| +std::unique_ptr<NativeStackSampler::StackBuffer>
|
| +NativeStackSampler::CreateStackBuffer() {
|
| + return MakeUnique<NativeStackSamplerWin::StackBufferWin>();
|
| +}
|
| +
|
| } // namespace base
|
|
|