• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_LIBSAMPLER_SAMPLER_H_
6 #define V8_LIBSAMPLER_SAMPLER_H_
7 
8 #include "include/v8.h"
9 
10 #include "src/base/atomicops.h"
11 #include "src/base/macros.h"
12 
13 namespace v8 {
14 namespace sampler {
15 
16 // ----------------------------------------------------------------------------
17 // Sampler
18 //
19 // A sampler periodically samples the state of the VM and optionally
20 // (if used for profiling) the program counter and stack pointer for
21 // the thread that created it.
22 
23 class Sampler {
24  public:
25   static const int kMaxFramesCountLog2 = 8;
26   static const unsigned kMaxFramesCount = (1u << kMaxFramesCountLog2) - 1;
27 
28   // Initializes the Sampler support. Called once at VM startup.
29   static void SetUp();
30   static void TearDown();
31 
32   // Initialize sampler.
33   explicit Sampler(Isolate* isolate);
34   virtual ~Sampler();
35 
isolate()36   Isolate* isolate() const { return isolate_; }
37 
38   // Performs stack sampling.
39   // Clients should override this method in order to do something on samples,
40   // for example buffer samples in a queue.
41   virtual void SampleStack(const v8::RegisterState& regs) = 0;
42 
43   // Start and stop sampler.
44   void Start();
45   void Stop();
46 
47   // Whether the sampling thread should use this Sampler for CPU profiling?
IsProfiling()48   bool IsProfiling() const {
49     return base::Relaxed_Load(&profiling_) > 0 &&
50            !base::Relaxed_Load(&has_processing_thread_);
51   }
52   void IncreaseProfilingDepth();
53   void DecreaseProfilingDepth();
54 
55   // Whether the sampler is running (that is, consumes resources).
IsActive()56   bool IsActive() const { return base::Relaxed_Load(&active_) != 0; }
57 
58   // CpuProfiler collects samples by calling DoSample directly
59   // without calling Start. To keep it working, we register the sampler
60   // with the CpuProfiler.
IsRegistered()61   bool IsRegistered() const { return base::Relaxed_Load(&registered_) != 0; }
62 
63   void DoSample();
64 
SetHasProcessingThread(bool value)65   void SetHasProcessingThread(bool value) {
66     base::Relaxed_Store(&has_processing_thread_, value);
67   }
68 
69   // Used in tests to make sure that stack sampling is performed.
js_sample_count()70   unsigned js_sample_count() const { return js_sample_count_; }
external_sample_count()71   unsigned external_sample_count() const { return external_sample_count_; }
StartCountingSamples()72   void StartCountingSamples() {
73     js_sample_count_ = 0;
74     external_sample_count_ = 0;
75     is_counting_samples_ = true;
76   }
77 
78   class PlatformData;
platform_data()79   PlatformData* platform_data() const { return data_; }
80 
81  protected:
82   // Counts stack samples taken in various VM states.
83   bool is_counting_samples_;
84   unsigned js_sample_count_;
85   unsigned external_sample_count_;
86 
87  private:
SetActive(bool value)88   void SetActive(bool value) { base::Relaxed_Store(&active_, value); }
SetRegistered(bool value)89   void SetRegistered(bool value) { base::Relaxed_Store(&registered_, value); }
90 
91   Isolate* isolate_;
92   base::Atomic32 profiling_;
93   base::Atomic32 has_processing_thread_;
94   base::Atomic32 active_;
95   base::Atomic32 registered_;
96   PlatformData* data_;  // Platform specific data.
97   DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
98 };
99 
100 }  // namespace sampler
101 }  // namespace v8
102 
103 #endif  // V8_LIBSAMPLER_SAMPLER_H_
104