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; |
} |