Index: base/profiler/stack_sampling_profiler.h |
diff --git a/base/profiler/stack_sampling_profiler.h b/base/profiler/stack_sampling_profiler.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ff322901e66a0d7cfc9739fb40f2ed75b11b9c2e |
--- /dev/null |
+++ b/base/profiler/stack_sampling_profiler.h |
@@ -0,0 +1,130 @@ |
+// Copyright 2015 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_PROFILER_STACK_SAMPLING_PROFILER_H_ |
+#define BASE_PROFILER_STACK_SAMPLING_PROFILER_H_ |
+ |
+#include <string> |
+#include <vector> |
+ |
+#include "base/base_export.h" |
+#include "base/files/file_path.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/strings/string16.h" |
+#include "base/threading/platform_thread.h" |
+#include "base/time/time.h" |
+ |
+namespace base { |
+ |
+// StackSamplingProfiler periodically stops a thread to sample its stack, for |
+// the purpose of collecting information about which code paths are |
+// executing. This information is used in aggregate by UMA to identify hot |
+// and/or janky code paths. The current implementation samples periodically for |
+// a short period after invoking Start. |
+// |
+// To use: create a StackSamplingProfiler, call Start to start the sampling, |
+// then (optionally) call Stop to stop the sampling. |
+class BASE_EXPORT StackSamplingProfiler { |
+ public: |
+ // Module represents the module (DLL or exe) corresponding to a stack frame. |
+ struct Module { |
+ // An opaque binary string that uniquely identifies a particular program |
+ // version with high probability. This is parsed from headers of the loaded |
+ // module. |
+ // For binaries generated by GNU tools: |
+ // Contents of the .note.gnu.build-id field. |
+ // On Windows: |
+ // GUID + AGE in the debug image headers of a module. |
+ std::string id; |
+ // The filename of the module. |
+ base::FilePath filename; |
+ }; |
+ |
+ // Frame represents an individual sampled stack frame with module information. |
+ struct Frame { |
+ // Instruction pointer subtracted by module base. |
+ uint64 ip_offset; |
+ // Index of the module in the array of modules. We don't represent module |
+ // state directly here to save space. |
+ int module_index; |
+ }; |
+ |
+ // Sample represents a set of stack frames. |
+ using Sample = std::vector<Frame>; |
+ |
+ // Profile represents a set of samples. |
+ struct Profile { |
+ Profile(); |
+ ~Profile(); |
+ |
+ std::vector<Module> modules; |
+ std::vector<Sample> samples; |
+ // Duration of this profile. |
+ base::TimeDelta profile_duration; |
+ // Time between samples. |
+ base::TimeDelta sampling_period; |
+ }; |
+ |
+ // NativeStackSampler abstracts the native implementation required to record a |
+ // stack sample for a given thread. |
+ class NativeStackSampler { |
+ public: |
+ virtual ~NativeStackSampler(); |
+ |
+ // Create a stack sampler that records samples for |thread_handle|. Returns |
+ // null if this platform does not support stack sampling. |
+ static scoped_ptr<NativeStackSampler> Create(PlatformThreadId thread_id); |
+ |
+ // Notify the sampler that we're starting to record a new profile. This |
+ // function is called on the SamplingThread. |
+ virtual void ProfileRecordingStarting(Profile* profile) = 0; |
+ |
+ // Record a stack sample. This function is called on the SamplingThread. |
+ virtual void RecordStackSample(Sample* sample) = 0; |
+ |
+ // Notify the sampler that we've stopped recording the current profile. This |
+ // function is called on the SamplingThread. |
+ virtual void ProfileRecordingStopped() = 0; |
+ |
+ protected: |
+ NativeStackSampler(); |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(NativeStackSampler); |
+ }; |
+ |
+ StackSamplingProfiler(PlatformThreadId thread_id); |
+ ~StackSamplingProfiler(); |
+ |
+ // Initializes the profiler and starts sampling. |
+ void Start(); |
+ // Stops the profiler and any ongoing sampling. |
+ void Stop(); |
+ |
+ // Gets the pending profiles into *|profiles|. This function is thread safe. |
+ static void GetPendingProfiles(std::vector<Profile>* profiles); |
+ |
+ private: |
+ class SamplingThread; |
+ struct SamplingThreadDeleter { |
+ void operator() (SamplingThread* thread) const; |
+ }; |
+ |
+ void CollectPendingProfiles(const std::vector<Profile>& profiles); |
+ |
+ PlatformThreadId thread_id_; |
+ |
+ scoped_ptr<SamplingThread, SamplingThreadDeleter> sampling_thread_; |
+ scoped_ptr<NativeStackSampler> native_sampler_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(StackSamplingProfiler); |
+}; |
+ |
+// Defined to allow equality check of Samples. |
+BASE_EXPORT bool operator==(const StackSamplingProfiler::Frame &a, |
+ const StackSamplingProfiler::Frame &b); |
+ |
+} // namespace base |
+ |
+#endif // BASE_PROFILER_STACK_SAMPLING_PROFILER_H_ |