~Ticker() { if (IsActive()) Stop(); }
- virtual void SampleStack(TickSample* sample) {
- ASSERT(IsSynchronous());
- StackTracer::Trace(sample);
- }
-
virtual void Tick(TickSample* sample) {
if (profiler_) profiler_->Insert(sample);
if (window_) window_->AddState(sample->state);
if (!window_ && IsActive()) Stop();
}
+ protected:
+ virtual void DoSampleStack(TickSample* sample) {
+ ASSERT(IsSynchronous());
+ StackTracer::Trace(sample);
+ }
+
private:
SlidingStateWindow* window_;
Profiler* profiler_;
class Sampler {
public:
// Initialize sampler.
- explicit Sampler(int interval, bool profiling);
+ Sampler(int interval, bool profiling);
virtual ~Sampler();
// Performs stack sampling.
- virtual void SampleStack(TickSample* sample) = 0;
+ void SampleStack(TickSample* sample) {
+ DoSampleStack(sample);
+ IncSamplesTaken();
+ }
// This method is called for each sampling period with the current
// program counter.
// Whether the sampler is running (that is, consumes resources).
bool IsActive() const { return active_; }
+ // Used in tests to make sure that stack sampling is performed.
+ int samples_taken() const { return samples_taken_; }
+ void ResetSamplesTaken() { samples_taken_ = 0; }
+
class PlatformData;
+ protected:
+ virtual void DoSampleStack(TickSample* sample) = 0;
+
private:
+ void IncSamplesTaken() { if (++samples_taken_ < 0) samples_taken_ = 0; }
+
const int interval_;
const bool profiling_;
const bool synchronous_;
bool active_;
PlatformData* data_; // Platform specific data.
+ int samples_taken_; // Counts stack samples taken.
DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
};
class LoggerTestHelper : public AllStatic {
public:
static bool IsSamplerActive() { return Logger::IsProfilerSamplerActive(); }
+ static void ResetSamplesTaken() {
+ reinterpret_cast<Sampler*>(Logger::ticker_)->ResetSamplesTaken();
+ }
+ static bool has_samples_taken() {
+ return reinterpret_cast<Sampler*>(Logger::ticker_)->samples_taken() > 0;
+ }
};
} // namespace v8::internal
using v8::internal::LoggerTestHelper;
-// Under Linux, we need to check if signals were delivered to avoid false
-// positives. Under other platforms profiling is done via a high-priority
-// thread, so this case never happen.
-static bool was_sigprof_received = true;
-#ifdef __linux__
-
-struct sigaction old_sigprof_handler;
-pthread_t our_thread;
-
-static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) {
- if (signal != SIGPROF || !pthread_equal(pthread_self(), our_thread)) return;
- was_sigprof_received = true;
- old_sigprof_handler.sa_sigaction(signal, info, context);
-}
-
-#endif // __linux__
-
-
namespace {
class ScopedLoggerInitializer {
static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
+ CHECK(!LoggerTestHelper::IsSamplerActive());
+ LoggerTestHelper::ResetSamplesTaken();
+
Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0);
CHECK(LoggerTestHelper::IsSamplerActive());
const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/
CHECK_NE(NULL, matcher->Find(code_creation));
-#ifdef __linux__
- // Intercept SIGPROF handler to make sure that the test process
- // had received it. Under load, system can defer it causing test failure.
- // It is important to execute this after 'ResumeProfiler'.
- our_thread = pthread_self();
- was_sigprof_received = false;
- struct sigaction sa;
- sa.sa_sigaction = SigProfSignalHandler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_SIGINFO;
- CHECK_EQ(0, sigaction(SIGPROF, &sa, &old_sigprof_handler));
-#endif // __linux__
-
// Force compiler to generate new code by parametrizing source.
EmbeddedVector<char, 100> script_src;
i::OS::SNPrintF(script_src,
CHECK_NE(NULL, matcher->Find(code_creation));
const char* tick = "\ntick,";
const bool ticks_found = matcher->Find(tick) != NULL;
- CHECK_EQ(was_sigprof_received, ticks_found);
+ CHECK_EQ(LoggerTestHelper::has_samples_taken(), ticks_found);
}