blob: b17a2ed8d50e383c5a16da4c56f085464402a512 [file] [log] [blame]
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001// 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"
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000032#include "frames.h"
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000033#include "v8globals.h"
34
35namespace v8 {
36namespace internal {
37
38class 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
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000047struct RegisterState {
48 RegisterState() : pc(NULL), sp(NULL), fp(NULL) {}
49 Address pc; // Instruction pointer.
50 Address sp; // Stack pointer.
51 Address fp; // Frame pointer.
52};
53
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000054// TickSample captures the information collected for each sample.
55struct TickSample {
56 TickSample()
57 : state(OTHER),
58 pc(NULL),
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000059 external_callback(NULL),
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000060 frames_count(0),
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000061 has_external_callback(false),
62 top_frame_type(StackFrame::NONE) {}
63 void Init(Isolate* isolate, const RegisterState& state);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000064 StateTag state; // The state of the VM.
65 Address pc; // Instruction pointer.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000066 union {
67 Address tos; // Top stack value (*sp).
68 Address external_callback;
69 };
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000070 static const int kMaxFramesCount = 64;
71 Address stack[kMaxFramesCount]; // Call stack.
72 int frames_count : 8; // Number of captured frames.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000073 bool has_external_callback : 1;
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000074 StackFrame::Type top_frame_type : 4;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000075};
76
77class 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
87 Isolate* isolate() const { return isolate_; }
88 int interval() const { return interval_; }
89
90 // Performs stack sampling.
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000091 void SampleStack(const RegisterState& regs);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000092
93 // Start and stop sampler.
94 void Start();
95 void Stop();
96
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +000097 // Whether the sampling thread should use this Sampler for CPU profiling?
98 bool IsProfiling() const {
99 return NoBarrier_Load(&profiling_) > 0 &&
100 !NoBarrier_Load(&has_processing_thread_);
101 }
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000102 void IncreaseProfilingDepth();
103 void DecreaseProfilingDepth();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000104
105 // Whether the sampler is running (that is, consumes resources).
106 bool IsActive() const { return NoBarrier_Load(&active_); }
107
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000108 void DoSample();
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000109 // If true next sample must be initiated on the profiler event processor
110 // thread right after latest sample is processed.
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000111 void SetHasProcessingThread(bool value) {
112 NoBarrier_Store(&has_processing_thread_, value);
113 }
114
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000115 // Used in tests to make sure that stack sampling is performed.
danno@chromium.orgbee51992013-07-10 14:57:15 +0000116 unsigned js_and_external_sample_count() const {
117 return js_and_external_sample_count_;
118 }
119 void StartCountingSamples() {
120 is_counting_samples_ = true;
121 js_and_external_sample_count_ = 0;
122 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000123
124 class PlatformData;
125 PlatformData* platform_data() const { return data_; }
126
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +0000127 protected:
128 // This method is called for each sampling period with the current
129 // program counter.
130 virtual void Tick(TickSample* sample) = 0;
131
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000132 private:
133 void SetActive(bool value) { NoBarrier_Store(&active_, value); }
134
135 Isolate* isolate_;
136 const int interval_;
137 Atomic32 profiling_;
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000138 Atomic32 has_processing_thread_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000139 Atomic32 active_;
140 PlatformData* data_; // Platform specific data.
danno@chromium.orgbee51992013-07-10 14:57:15 +0000141 bool is_counting_samples_;
142 // Counts stack samples taken in JS VM state.
143 unsigned js_and_external_sample_count_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000144 DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
145};
146
147
148} } // namespace v8::internal
149
150#endif // V8_SAMPLER_H_