Do not start sampler thread when CpuProfiler is active

Now that CpuProfiler sends does sampling on the profile event processing thread there is no need to launch sampler thread. The latter is used only for --prof profiler.

BUG=v8:2814
R=bmeurer@chromium.org, svenpanne@chromium.org

Review URL: https://codereview.chromium.org/23011029

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16430 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yurys@chromium.org 2013-08-29 14:03:38 +00:00
parent dc14d6f435
commit 7fc915b701
5 changed files with 57 additions and 66 deletions

View File

@ -139,24 +139,9 @@ void ProfilerEventsProcessor::ProcessEventsAndDoSample() {
}
void ProfilerEventsProcessor::ProcessEventsAndYield() {
// Process ticks until we have any.
if (ProcessTicks()) {
// All ticks of the current dequeue_order are processed,
// proceed to the next code event.
ProcessCodeEvent();
}
YieldCPU();
}
void ProfilerEventsProcessor::Run() {
while (running_) {
if (Sampler::CanSampleOnProfilerEventsProcessorThread()) {
ProcessEventsAndDoSample();
} else {
ProcessEventsAndYield();
}
ProcessEventsAndDoSample();
}
// Process remaining tick events.
@ -382,7 +367,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate)
next_profile_uid_(1),
generator_(NULL),
processor_(NULL),
need_to_stop_sampler_(false),
is_profiling_(false) {
}
@ -396,7 +380,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate,
next_profile_uid_(1),
generator_(test_generator),
processor_(test_processor),
need_to_stop_sampler_(false),
is_profiling_(false) {
}
@ -447,14 +430,8 @@ void CpuProfiler::StartProcessorIfNotStarted() {
logger->LogAccessorCallbacks();
LogBuiltins();
// Enable stack sampling.
if (Sampler::CanSampleOnProfilerEventsProcessorThread()) {
sampler->SetHasProcessingThread(true);
}
sampler->SetHasProcessingThread(true);
sampler->IncreaseProfilingDepth();
if (!sampler->IsActive()) {
sampler->Start();
need_to_stop_sampler_ = true;
}
processor_->StartSynchronously();
}
}
@ -487,20 +464,14 @@ void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
void CpuProfiler::StopProcessor() {
Logger* logger = isolate_->logger();
Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
sampler->DecreaseProfilingDepth();
is_profiling_ = false;
processor_->StopSynchronously();
delete processor_;
delete generator_;
processor_ = NULL;
generator_ = NULL;
if (Sampler::CanSampleOnProfilerEventsProcessorThread()) {
sampler->SetHasProcessingThread(false);
}
if (need_to_stop_sampler_) {
sampler->Stop();
need_to_stop_sampler_ = false;
}
sampler->SetHasProcessingThread(false);
sampler->DecreaseProfilingDepth();
logger->is_logging_ = saved_is_logging_;
}

View File

@ -163,7 +163,6 @@ class ProfilerEventsProcessor : public Thread {
bool ProcessTicks();
void ProcessEventsAndDoSample();
void ProcessEventsAndYield();
ProfileGenerator* generator_;
Sampler* sampler_;
@ -266,7 +265,6 @@ class CpuProfiler : public CodeEventListener {
ProfileGenerator* generator_;
ProfilerEventsProcessor* processor_;
bool saved_is_logging_;
bool need_to_stop_sampler_;
bool is_profiling_;
DISALLOW_COPY_AND_ASSIGN(CpuProfiler);

View File

@ -626,9 +626,9 @@ class Ticker: public Sampler {
}
void ClearProfiler() {
DecreaseProfilingDepth();
profiler_ = NULL;
if (IsActive()) Stop();
DecreaseProfilingDepth();
}
private:

View File

@ -248,8 +248,25 @@ class SimulatorHelper {
class SignalHandler : public AllStatic {
public:
static inline void EnsureInstalled() {
if (signal_handler_installed_) return;
static void SetUp() { if (!mutex_) mutex_ = new Mutex(); }
static void TearDown() { delete mutex_; }
static void IncreaseSamplerCount() {
LockGuard<Mutex> lock_guard(mutex_);
if (++client_count_ == 1) Install();
}
static void DecreaseSamplerCount() {
LockGuard<Mutex> lock_guard(mutex_);
if (--client_count_ == 0) Restore();
}
static bool Installed() {
return signal_handler_installed_;
}
private:
static void Install() {
struct sigaction sa;
sa.sa_sigaction = &HandleProfilerSignal;
sigemptyset(&sa.sa_mask);
@ -258,23 +275,24 @@ class SignalHandler : public AllStatic {
(sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
}
static inline void Restore() {
static void Restore() {
if (signal_handler_installed_) {
sigaction(SIGPROF, &old_signal_handler_, 0);
signal_handler_installed_ = false;
}
}
static inline bool Installed() {
return signal_handler_installed_;
}
private:
static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);
// Protects the process wide state below.
static Mutex* mutex_;
static int client_count_;
static bool signal_handler_installed_;
static struct sigaction old_signal_handler_;
};
Mutex* SignalHandler::mutex_ = NULL;
int SignalHandler::client_count_ = 0;
struct sigaction SignalHandler::old_signal_handler_;
bool SignalHandler::signal_handler_installed_ = false;
@ -299,7 +317,7 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
}
Sampler* sampler = isolate->logger()->sampler();
if (sampler == NULL || !sampler->IsActive()) return;
if (sampler == NULL) return;
RegisterState state;
@ -436,9 +454,6 @@ class SamplerThread : public Thread {
ASSERT(instance_->interval_ == sampler->interval());
instance_->active_samplers_.Add(sampler);
#if defined(USE_SIGNALS)
SignalHandler::EnsureInstalled();
#endif
if (need_to_start) instance_->StartSynchronously();
}
@ -457,9 +472,6 @@ class SamplerThread : public Thread {
if (instance_->active_samplers_.is_empty()) {
instance_to_remove = instance_;
instance_ = NULL;
#if defined(USE_SIGNALS)
SignalHandler::Restore();
#endif
}
}
@ -548,12 +560,18 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
void Sampler::SetUp() {
#if defined(USE_SIGNALS)
SignalHandler::SetUp();
#endif
SamplerThread::SetUp();
}
void Sampler::TearDown() {
SamplerThread::TearDown();
#if defined(USE_SIGNALS)
SignalHandler::TearDown();
#endif
}
@ -589,6 +607,22 @@ void Sampler::Stop() {
}
void Sampler::IncreaseProfilingDepth() {
NoBarrier_AtomicIncrement(&profiling_, 1);
#if defined(USE_SIGNALS)
SignalHandler::IncreaseSamplerCount();
#endif
}
void Sampler::DecreaseProfilingDepth() {
#if defined(USE_SIGNALS)
SignalHandler::DecreaseSamplerCount();
#endif
NoBarrier_AtomicIncrement(&profiling_, -1);
}
void Sampler::SampleStack(const RegisterState& state) {
TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
TickSample sample_obj;
@ -606,17 +640,6 @@ void Sampler::SampleStack(const RegisterState& state) {
}
bool Sampler::CanSampleOnProfilerEventsProcessorThread() {
#if defined(USE_SIGNALS)
return true;
#elif V8_OS_WIN || V8_OS_CYGWIN
return true;
#else
return false;
#endif
}
#if defined(USE_SIGNALS)
void Sampler::DoSample() {

View File

@ -99,16 +99,15 @@ class Sampler {
return NoBarrier_Load(&profiling_) > 0 &&
!NoBarrier_Load(&has_processing_thread_);
}
void IncreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, 1); }
void DecreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, -1); }
void IncreaseProfilingDepth();
void DecreaseProfilingDepth();
// Whether the sampler is running (that is, consumes resources).
bool IsActive() const { return NoBarrier_Load(&active_); }
void DoSample();
// If true next sample must be initiated on the profiler event processor
// thread right after latest sample is processed.
static bool CanSampleOnProfilerEventsProcessorThread();
void DoSample();
void SetHasProcessingThread(bool value) {
NoBarrier_Store(&has_processing_thread_, value);
}