Index: src/platform-linux.cc |
diff --git a/src/platform-linux.cc b/src/platform-linux.cc |
index f571b990217b569b9ee1beeb95ce1e21d62c0920..0359b2d79e98d59f8ea8f1f5d7970607b581bc44 100644 |
--- a/src/platform-linux.cc |
+++ b/src/platform-linux.cc |
@@ -1127,84 +1127,14 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
} |
-class CpuProfilerSignalHandler { |
- public: |
- static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } |
- static void TearDown() { delete mutex_; } |
- |
- static bool RegisterProfilingSampler() { |
- ScopedLock lock(mutex_); |
- if (!profiling_samplers_count_) InstallSignalHandler(); |
- ++profiling_samplers_count_; |
- return signal_handler_installed_; |
- } |
- |
- static void UnregisterProfilingSampler() { |
- ScopedLock lock(mutex_); |
- ASSERT(profiling_samplers_count_ > 0); |
- if (!profiling_samplers_count_) return; |
- if (profiling_samplers_count_ == 1) RestoreSignalHandler(); |
- --profiling_samplers_count_; |
- } |
- |
- private: |
- static void InstallSignalHandler() { |
- struct sigaction sa; |
- sa.sa_sigaction = ProfilerSignalHandler; |
- sigemptyset(&sa.sa_mask); |
- sa.sa_flags = SA_RESTART | SA_SIGINFO; |
- signal_handler_installed_ = |
- (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
- } |
- |
- static void RestoreSignalHandler() { |
- if (signal_handler_installed_) { |
- sigaction(SIGPROF, &old_signal_handler_, 0); |
- signal_handler_installed_ = false; |
- } |
- } |
- |
- // Protects the process wide state below. |
- static Mutex* mutex_; |
- static int profiling_samplers_count_; |
- static bool signal_handler_installed_; |
- static struct sigaction old_signal_handler_; |
-}; |
- |
- |
-Mutex* CpuProfilerSignalHandler::mutex_ = NULL; |
-int CpuProfilerSignalHandler::profiling_samplers_count_ = 0; |
-bool CpuProfilerSignalHandler::signal_handler_installed_ = false; |
-struct sigaction CpuProfilerSignalHandler::old_signal_handler_; |
- |
- |
class Sampler::PlatformData : public Malloced { |
public: |
- PlatformData() |
- : vm_tgid_(getpid()), |
- vm_tid_(GetThreadID()), |
- signal_handler_installed_(false) {} |
+ PlatformData() : vm_tid_(GetThreadID()) {} |
- void set_signal_handler_installed(bool value) { |
- signal_handler_installed_ = value; |
- } |
- |
- void SendProfilingSignal() { |
- if (!signal_handler_installed_) return; |
- // Glibc doesn't provide a wrapper for tgkill(2). |
-#if defined(ANDROID) |
- syscall(__NR_tgkill, vm_tgid_, vm_tid_, SIGPROF); |
-#else |
- int result = syscall(SYS_tgkill, vm_tgid_, vm_tid_, SIGPROF); |
- USE(result); |
- ASSERT(result == 0); |
-#endif |
- } |
+ int vm_tid() const { return vm_tid_; } |
private: |
- const int vm_tgid_; |
const int vm_tid_; |
- bool signal_handler_installed_; |
}; |
@@ -1214,11 +1144,28 @@ class SignalSender : public Thread { |
explicit SignalSender(int interval) |
: Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), |
+ vm_tgid_(getpid()), |
interval_(interval) {} |
static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } |
static void TearDown() { delete mutex_; } |
+ static void InstallSignalHandler() { |
+ struct sigaction sa; |
+ sa.sa_sigaction = ProfilerSignalHandler; |
+ sigemptyset(&sa.sa_mask); |
+ sa.sa_flags = SA_RESTART | SA_SIGINFO; |
+ signal_handler_installed_ = |
+ (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
+ } |
+ |
+ static void RestoreSignalHandler() { |
+ if (signal_handler_installed_) { |
+ sigaction(SIGPROF, &old_signal_handler_, 0); |
+ signal_handler_installed_ = false; |
+ } |
+ } |
+ |
static void AddActiveSampler(Sampler* sampler) { |
ScopedLock lock(mutex_); |
SamplerRegistry::AddActiveSampler(sampler); |
@@ -1239,6 +1186,7 @@ class SignalSender : public Thread { |
RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); |
delete instance_; |
instance_ = NULL; |
+ RestoreSignalHandler(); |
} |
} |
@@ -1250,8 +1198,10 @@ class SignalSender : public Thread { |
// When CPU profiling is enabled both JavaScript and C++ code is |
// profiled. We must not suspend. |
if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) { |
+ if (!signal_handler_installed_) InstallSignalHandler(); |
SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this); |
} else { |
+ if (signal_handler_installed_) RestoreSignalHandler(); |
if (RuntimeProfiler::WaitForSomeIsolateToEnterJS()) continue; |
} |
Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough. |
@@ -1260,7 +1210,20 @@ class SignalSender : public Thread { |
static void DoCpuProfile(Sampler* sampler, void* raw_sender) { |
if (!sampler->IsProfiling()) return; |
- sampler->DoSample(); |
+ SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender); |
+ sender->SendProfilingSignal(sampler->platform_data()->vm_tid()); |
+ } |
+ |
+ void SendProfilingSignal(int tid) { |
+ if (!signal_handler_installed_) return; |
+ // Glibc doesn't provide a wrapper for tgkill(2). |
+#if defined(ANDROID) |
+ syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF); |
+#else |
+ int result = syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF); |
+ USE(result); |
+ ASSERT(result == 0); |
+#endif |
} |
void Sleep() { |
@@ -1284,11 +1247,13 @@ class SignalSender : public Thread { |
#endif // ANDROID |
} |
+ const int vm_tgid_; |
const int interval_; |
// Protects the process wide state below. |
static Mutex* mutex_; |
static SignalSender* instance_; |
+ static bool signal_handler_installed_; |
static struct sigaction old_signal_handler_; |
private: |
@@ -1299,6 +1264,7 @@ class SignalSender : public Thread { |
Mutex* SignalSender::mutex_ = NULL; |
SignalSender* SignalSender::instance_ = NULL; |
struct sigaction SignalSender::old_signal_handler_; |
+bool SignalSender::signal_handler_installed_ = false; |
void OS::SetUp() { |
@@ -1326,12 +1292,10 @@ void OS::SetUp() { |
} |
#endif |
SignalSender::SetUp(); |
- CpuProfilerSignalHandler::SetUp(); |
} |
void OS::TearDown() { |
- CpuProfilerSignalHandler::TearDown(); |
SignalSender::TearDown(); |
delete limit_mutex; |
} |
@@ -1341,7 +1305,6 @@ Sampler::Sampler(Isolate* isolate, int interval) |
: isolate_(isolate), |
interval_(interval), |
profiling_(false), |
- has_processing_thread_(false), |
active_(false), |
samples_taken_(0) { |
data_ = new PlatformData; |
@@ -1368,26 +1331,4 @@ void Sampler::Stop() { |
} |
-bool Sampler::CanSampleOnProfilerEventsProcessorThread() { |
- return true; |
-} |
- |
- |
-void Sampler::DoSample() { |
- platform_data()->SendProfilingSignal(); |
-} |
- |
- |
-void Sampler::StartProfiling() { |
- platform_data()->set_signal_handler_installed( |
- CpuProfilerSignalHandler::RegisterProfilingSampler()); |
-} |
- |
- |
-void Sampler::StopProfiling() { |
- CpuProfilerSignalHandler::UnregisterProfilingSampler(); |
- platform_data()->set_signal_handler_installed(false); |
-} |
- |
- |
} } // namespace v8::internal |