blob: c3dce4ed7c2fec7e353cb06d1641f63e82092a84 [file] [log] [blame]
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001// Copyright 2013 the V8 project authors. All rights reserved.
rossberg@chromium.org34849642014-04-29 16:30:47 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004
5#ifndef V8_SAMPLER_H_
6#define V8_SAMPLER_H_
7
machenbach@chromium.org1e2d50c2014-06-06 00:04:56 +00008#include "src/base/atomicops.h"
machenbach@chromium.org196eb602014-06-04 00:06:13 +00009#include "src/frames.h"
10#include "src/globals.h"
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000011
12namespace v8 {
13namespace internal {
14
15class Isolate;
16
17// ----------------------------------------------------------------------------
18// Sampler
19//
20// A sampler periodically samples the state of the VM and optionally
21// (if used for profiling) the program counter and stack pointer for
22// the thread that created it.
23
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000024struct RegisterState {
25 RegisterState() : pc(NULL), sp(NULL), fp(NULL) {}
26 Address pc; // Instruction pointer.
27 Address sp; // Stack pointer.
28 Address fp; // Frame pointer.
29};
30
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000031// TickSample captures the information collected for each sample.
32struct TickSample {
33 TickSample()
34 : state(OTHER),
35 pc(NULL),
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000036 external_callback(NULL),
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000037 frames_count(0),
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000038 has_external_callback(false),
39 top_frame_type(StackFrame::NONE) {}
40 void Init(Isolate* isolate, const RegisterState& state);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000041 StateTag state; // The state of the VM.
42 Address pc; // Instruction pointer.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000043 union {
44 Address tos; // Top stack value (*sp).
45 Address external_callback;
46 };
machenbach@chromium.org08e75692014-06-25 00:05:37 +000047 static const unsigned kMaxFramesCountLog2 = 8;
48 static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000049 Address stack[kMaxFramesCount]; // Call stack.
yangguo@chromium.org5de00742014-07-01 11:58:10 +000050 base::TimeTicks timestamp;
machenbach@chromium.org08e75692014-06-25 00:05:37 +000051 unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000052 bool has_external_callback : 1;
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000053 StackFrame::Type top_frame_type : 4;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000054};
55
56class Sampler {
57 public:
58 // Initializes the Sampler support. Called once at VM startup.
59 static void SetUp();
60 static void TearDown();
61
62 // Initialize sampler.
63 Sampler(Isolate* isolate, int interval);
64 virtual ~Sampler();
65
66 Isolate* isolate() const { return isolate_; }
67 int interval() const { return interval_; }
68
69 // Performs stack sampling.
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000070 void SampleStack(const RegisterState& regs);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000071
72 // Start and stop sampler.
73 void Start();
74 void Stop();
75
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +000076 // Whether the sampling thread should use this Sampler for CPU profiling?
77 bool IsProfiling() const {
machenbach@chromium.org1e2d50c2014-06-06 00:04:56 +000078 return base::NoBarrier_Load(&profiling_) > 0 &&
79 !base::NoBarrier_Load(&has_processing_thread_);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +000080 }
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +000081 void IncreaseProfilingDepth();
82 void DecreaseProfilingDepth();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000083
84 // Whether the sampler is running (that is, consumes resources).
machenbach@chromium.org1e2d50c2014-06-06 00:04:56 +000085 bool IsActive() const { return base::NoBarrier_Load(&active_); }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000086
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +000087 void DoSample();
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +000088 // If true next sample must be initiated on the profiler event processor
89 // thread right after latest sample is processed.
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +000090 void SetHasProcessingThread(bool value) {
machenbach@chromium.org1e2d50c2014-06-06 00:04:56 +000091 base::NoBarrier_Store(&has_processing_thread_, value);
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +000092 }
93
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000094 // Used in tests to make sure that stack sampling is performed.
danno@chromium.orgbee51992013-07-10 14:57:15 +000095 unsigned js_and_external_sample_count() const {
96 return js_and_external_sample_count_;
97 }
98 void StartCountingSamples() {
99 is_counting_samples_ = true;
100 js_and_external_sample_count_ = 0;
101 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000102
103 class PlatformData;
104 PlatformData* platform_data() const { return data_; }
105
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +0000106 protected:
107 // This method is called for each sampling period with the current
108 // program counter.
109 virtual void Tick(TickSample* sample) = 0;
110
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000111 private:
machenbach@chromium.org1e2d50c2014-06-06 00:04:56 +0000112 void SetActive(bool value) { base::NoBarrier_Store(&active_, value); }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000113
114 Isolate* isolate_;
115 const int interval_;
machenbach@chromium.org1e2d50c2014-06-06 00:04:56 +0000116 base::Atomic32 profiling_;
117 base::Atomic32 has_processing_thread_;
118 base::Atomic32 active_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000119 PlatformData* data_; // Platform specific data.
danno@chromium.orgbee51992013-07-10 14:57:15 +0000120 bool is_counting_samples_;
121 // Counts stack samples taken in JS VM state.
122 unsigned js_and_external_sample_count_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000123 DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
124};
125
126
127} } // namespace v8::internal
128
129#endif // V8_SAMPLER_H_