• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_SAMPLER_H_
29 #define V8_SAMPLER_H_
30 
31 #include "atomicops.h"
32 #include "frames.h"
33 #include "v8globals.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 class Isolate;
39 
40 // ----------------------------------------------------------------------------
41 // Sampler
42 //
43 // A sampler periodically samples the state of the VM and optionally
44 // (if used for profiling) the program counter and stack pointer for
45 // the thread that created it.
46 
47 struct RegisterState {
RegisterStateRegisterState48   RegisterState() : pc(NULL), sp(NULL), fp(NULL) {}
49   Address pc;      // Instruction pointer.
50   Address sp;      // Stack pointer.
51   Address fp;      // Frame pointer.
52 };
53 
54 // TickSample captures the information collected for each sample.
55 struct TickSample {
TickSampleTickSample56   TickSample()
57       : state(OTHER),
58         pc(NULL),
59         external_callback(NULL),
60         frames_count(0),
61         has_external_callback(false),
62         top_frame_type(StackFrame::NONE) {}
63   void Init(Isolate* isolate, const RegisterState& state);
64   StateTag state;  // The state of the VM.
65   Address pc;      // Instruction pointer.
66   union {
67     Address tos;   // Top stack value (*sp).
68     Address external_callback;
69   };
70   static const int kMaxFramesCount = 64;
71   Address stack[kMaxFramesCount];  // Call stack.
72   int frames_count : 8;  // Number of captured frames.
73   bool has_external_callback : 1;
74   StackFrame::Type top_frame_type : 4;
75 };
76 
77 class Sampler {
78  public:
79   // Initializes the Sampler support. Called once at VM startup.
80   static void SetUp();
81   static void TearDown();
82 
83   // Initialize sampler.
84   Sampler(Isolate* isolate, int interval);
85   virtual ~Sampler();
86 
isolate()87   Isolate* isolate() const { return isolate_; }
interval()88   int interval() const { return interval_; }
89 
90   // Performs stack sampling.
91   void SampleStack(const RegisterState& regs);
92 
93   // Start and stop sampler.
94   void Start();
95   void Stop();
96 
97   // Whether the sampling thread should use this Sampler for CPU profiling?
IsProfiling()98   bool IsProfiling() const {
99     return NoBarrier_Load(&profiling_) > 0 &&
100         !NoBarrier_Load(&has_processing_thread_);
101   }
102   void IncreaseProfilingDepth();
103   void DecreaseProfilingDepth();
104 
105   // Whether the sampler is running (that is, consumes resources).
IsActive()106   bool IsActive() const { return NoBarrier_Load(&active_); }
107 
108   void DoSample();
109   // If true next sample must be initiated on the profiler event processor
110   // thread right after latest sample is processed.
SetHasProcessingThread(bool value)111   void SetHasProcessingThread(bool value) {
112     NoBarrier_Store(&has_processing_thread_, value);
113   }
114 
115   // Used in tests to make sure that stack sampling is performed.
js_and_external_sample_count()116   unsigned js_and_external_sample_count() const {
117     return js_and_external_sample_count_;
118   }
StartCountingSamples()119   void StartCountingSamples() {
120       is_counting_samples_ = true;
121       js_and_external_sample_count_ = 0;
122   }
123 
124   class PlatformData;
platform_data()125   PlatformData* platform_data() const { return data_; }
126 
127  protected:
128   // This method is called for each sampling period with the current
129   // program counter.
130   virtual void Tick(TickSample* sample) = 0;
131 
132  private:
SetActive(bool value)133   void SetActive(bool value) { NoBarrier_Store(&active_, value); }
134 
135   Isolate* isolate_;
136   const int interval_;
137   Atomic32 profiling_;
138   Atomic32 has_processing_thread_;
139   Atomic32 active_;
140   PlatformData* data_;  // Platform specific data.
141   bool is_counting_samples_;
142   // Counts stack samples taken in JS VM state.
143   unsigned js_and_external_sample_count_;
144   DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
145 };
146 
147 
148 } }  // namespace v8::internal
149 
150 #endif  // V8_SAMPLER_H_
151