v8/src/sampler.h

129 lines
3.6 KiB
C
Raw Normal View History

// Copyright 2013 the V8 project 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 V8_SAMPLER_H_
#define V8_SAMPLER_H_
#include "atomicops.h"
#include "frames.h"
#include "globals.h"
namespace v8 {
namespace internal {
class Isolate;
// ----------------------------------------------------------------------------
// Sampler
//
// A sampler periodically samples the state of the VM and optionally
// (if used for profiling) the program counter and stack pointer for
// the thread that created it.
struct RegisterState {
RegisterState() : pc(NULL), sp(NULL), fp(NULL) {}
Address pc; // Instruction pointer.
Address sp; // Stack pointer.
Address fp; // Frame pointer.
};
// TickSample captures the information collected for each sample.
struct TickSample {
TickSample()
: state(OTHER),
pc(NULL),
external_callback(NULL),
frames_count(0),
has_external_callback(false),
top_frame_type(StackFrame::NONE) {}
void Init(Isolate* isolate, const RegisterState& state);
StateTag state; // The state of the VM.
Address pc; // Instruction pointer.
union {
Address tos; // Top stack value (*sp).
Address external_callback;
};
static const int kMaxFramesCount = 64;
Address stack[kMaxFramesCount]; // Call stack.
TimeTicks timestamp;
int frames_count : 8; // Number of captured frames.
bool has_external_callback : 1;
StackFrame::Type top_frame_type : 4;
};
class Sampler {
public:
// Initializes the Sampler support. Called once at VM startup.
static void SetUp();
static void TearDown();
// Initialize sampler.
Sampler(Isolate* isolate, int interval);
virtual ~Sampler();
Isolate* isolate() const { return isolate_; }
int interval() const { return interval_; }
// Performs stack sampling.
void SampleStack(const RegisterState& regs);
// Start and stop sampler.
void Start();
void Stop();
Support higher CPU profiler sampling rate on posix systems New flag is added that allows to specify CPU profiler sampling rate in microseconds as command line argument. It was tested to work fine with 100us interval(currently it is 1ms). Default values are kept the same as in the current implementation. The new implementation is enabled only on POSIX platforms which use signals to collect samples. Other platforms that pause thread being sampled are to follow. SIGPROF signals are now sent on the profiler event processor thread to make sure that the processing thread does fall far behind the sampling. The patch is based on the previous one that was rolled out in r13851. The main difference is that the circular queue is not modified for now. On Linux sampling for CPU profiler is initiated on the profiler event processor thread, other platforms to follow. CPU profiler continues to use SamplingCircularQueue, we will probably replace it with a single sample buffer when Mac and Win ports support profiling on the event processing thread. When --prof option is specified profiling is initiated either on the profiler event processor thread if CPU profiler is on or on the SignalSender thread as it used to be if no CPU profiles are being collected. ProfilerEventsProcessor::ProcessEventsAndDoSample now waits in a tight loop, processing collected samples until sampling interval expires. To save CPU resources I'm planning to change that to use nanosleep as only one sample is expected in the queue at any point. BUG=v8:2814 R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/21101002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16310 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-08-26 07:17:12 +00:00
// Whether the sampling thread should use this Sampler for CPU profiling?
bool IsProfiling() const {
return NoBarrier_Load(&profiling_) > 0 &&
!NoBarrier_Load(&has_processing_thread_);
}
void IncreaseProfilingDepth();
void DecreaseProfilingDepth();
// Whether the sampler is running (that is, consumes resources).
bool IsActive() const { return NoBarrier_Load(&active_); }
void DoSample();
Support higher CPU profiler sampling rate on posix systems New flag is added that allows to specify CPU profiler sampling rate in microseconds as command line argument. It was tested to work fine with 100us interval(currently it is 1ms). Default values are kept the same as in the current implementation. The new implementation is enabled only on POSIX platforms which use signals to collect samples. Other platforms that pause thread being sampled are to follow. SIGPROF signals are now sent on the profiler event processor thread to make sure that the processing thread does fall far behind the sampling. The patch is based on the previous one that was rolled out in r13851. The main difference is that the circular queue is not modified for now. On Linux sampling for CPU profiler is initiated on the profiler event processor thread, other platforms to follow. CPU profiler continues to use SamplingCircularQueue, we will probably replace it with a single sample buffer when Mac and Win ports support profiling on the event processing thread. When --prof option is specified profiling is initiated either on the profiler event processor thread if CPU profiler is on or on the SignalSender thread as it used to be if no CPU profiles are being collected. ProfilerEventsProcessor::ProcessEventsAndDoSample now waits in a tight loop, processing collected samples until sampling interval expires. To save CPU resources I'm planning to change that to use nanosleep as only one sample is expected in the queue at any point. BUG=v8:2814 R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/21101002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16310 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-08-26 07:17:12 +00:00
// If true next sample must be initiated on the profiler event processor
// thread right after latest sample is processed.
void SetHasProcessingThread(bool value) {
NoBarrier_Store(&has_processing_thread_, value);
}
// Used in tests to make sure that stack sampling is performed.
unsigned js_and_external_sample_count() const {
return js_and_external_sample_count_;
}
void StartCountingSamples() {
is_counting_samples_ = true;
js_and_external_sample_count_ = 0;
}
class PlatformData;
PlatformData* platform_data() const { return data_; }
protected:
// This method is called for each sampling period with the current
// program counter.
virtual void Tick(TickSample* sample) = 0;
private:
void SetActive(bool value) { NoBarrier_Store(&active_, value); }
Isolate* isolate_;
const int interval_;
Atomic32 profiling_;
Support higher CPU profiler sampling rate on posix systems New flag is added that allows to specify CPU profiler sampling rate in microseconds as command line argument. It was tested to work fine with 100us interval(currently it is 1ms). Default values are kept the same as in the current implementation. The new implementation is enabled only on POSIX platforms which use signals to collect samples. Other platforms that pause thread being sampled are to follow. SIGPROF signals are now sent on the profiler event processor thread to make sure that the processing thread does fall far behind the sampling. The patch is based on the previous one that was rolled out in r13851. The main difference is that the circular queue is not modified for now. On Linux sampling for CPU profiler is initiated on the profiler event processor thread, other platforms to follow. CPU profiler continues to use SamplingCircularQueue, we will probably replace it with a single sample buffer when Mac and Win ports support profiling on the event processing thread. When --prof option is specified profiling is initiated either on the profiler event processor thread if CPU profiler is on or on the SignalSender thread as it used to be if no CPU profiles are being collected. ProfilerEventsProcessor::ProcessEventsAndDoSample now waits in a tight loop, processing collected samples until sampling interval expires. To save CPU resources I'm planning to change that to use nanosleep as only one sample is expected in the queue at any point. BUG=v8:2814 R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/21101002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16310 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-08-26 07:17:12 +00:00
Atomic32 has_processing_thread_;
Atomic32 active_;
PlatformData* data_; // Platform specific data.
bool is_counting_samples_;
// Counts stack samples taken in JS VM state.
unsigned js_and_external_sample_count_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
};
} } // namespace v8::internal
#endif // V8_SAMPLER_H_