Chromium Code Reviews| 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..e7d83a1b909618de56e661ef7a71195d2cc41dba 100644 |
| --- a/base/profiler/native_stack_sampler_win.cc |
| +++ b/base/profiler/native_stack_sampler_win.cc |
| @@ -15,13 +15,16 @@ |
| #include <utility> |
| #include <vector> |
| +#include "base/atomicops.h" |
|
Mike Wittman
2017/01/24 17:20:57
No longer needed.
bcwhite
2017/02/07 15:16:36
Done.
|
| #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" |
| #include "base/strings/utf_string_conversions.h" |
| +#include "base/synchronization/lock.h" |
|
Mike Wittman
2017/01/24 17:20:57
No longer needed.
bcwhite
2017/02/07 15:16:36
Done.
|
| #include "base/time/time.h" |
| #include "base/win/pe_image.h" |
| #include "base/win/scoped_handle.h" |
| @@ -392,10 +395,13 @@ class NativeStackSamplerWin : public NativeStackSampler { |
| ~NativeStackSamplerWin() override; |
| // StackSamplingProfiler::NativeStackSampler: |
| + std::unique_ptr<Common> CreateCommon() override; |
| void ProfileRecordingStarting( |
| + Common* common, |
| std::vector<StackSamplingProfiler::Module>* modules) override; |
| - void RecordStackSample(StackSamplingProfiler::Sample* sample) override; |
| - void ProfileRecordingStopped() override; |
| + void RecordStackSample(Common* common, |
| + StackSamplingProfiler::Sample* sample) override; |
| + void ProfileRecordingStopped(Common* common) override; |
| private: |
| enum { |
| @@ -407,6 +413,15 @@ class NativeStackSamplerWin : public NativeStackSampler { |
| kStackCopyBufferSize = 2 * 1024 * 1024 |
| }; |
| + class WinCommon : public Common { |
|
Mike Wittman
2017/01/24 17:20:57
WinCommon => CommonWin (or actually StackBufferWin
bcwhite
2017/02/07 15:16:35
Done.
|
| + public: |
| + WinCommon() {} |
| + ~WinCommon() override {} |
| + |
| + // Buffer to use for copies of the stack. |
| + unsigned char stack_copy_buffer_[kStackCopyBufferSize]; |
| + }; |
| + |
| // 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 +448,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_; |
| @@ -445,6 +456,11 @@ class NativeStackSamplerWin : public NativeStackSampler { |
| // current_modules_. |
| std::map<HMODULE, size_t> profile_module_index_; |
| + // This "in use" flag is used to validate the assumption that there are no |
| + // concurrent stack sampling requests regardless of how many instances of |
| + // this class are currently active. |
| + static subtle::AtomicWord stack_copy_buffer_in_use_; |
|
Mike Wittman
2017/01/24 17:20:57
No longer needed.
bcwhite
2017/02/07 15:16:35
Done.
|
| + |
| DISALLOW_COPY_AND_ASSIGN(NativeStackSamplerWin); |
| }; |
| @@ -456,35 +472,40 @@ 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_); |
| } |
| NativeStackSamplerWin::~NativeStackSamplerWin() { |
| } |
| +std::unique_ptr<NativeStackSampler::Common> |
| +NativeStackSamplerWin::CreateCommon() { |
| + return MakeUnique<WinCommon>(); |
| +} |
| + |
| void NativeStackSamplerWin::ProfileRecordingStarting( |
| + Common* common, |
| std::vector<StackSamplingProfiler::Module>* modules) { |
| current_modules_ = modules; |
| profile_module_index_.clear(); |
| } |
| void NativeStackSamplerWin::RecordStackSample( |
| + Common* common, |
| StackSamplingProfiler::Sample* sample) { |
| + DCHECK(common); |
| 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_, |
| + reinterpret_cast<WinCommon*>(common)->stack_copy_buffer_, |
|
Mike Wittman
2017/01/24 17:20:57
static_cast for downcast
bcwhite
2017/02/07 15:16:36
Done.
|
| + kStackCopyBufferSize, &stack, annotator_, sample, test_delegate_); |
| CopyToSample(stack, sample, current_modules_); |
| } |
| -void NativeStackSamplerWin::ProfileRecordingStopped() { |
| +void NativeStackSamplerWin::ProfileRecordingStopped(Common* common) { |
| current_modules_ = nullptr; |
| } |