Revision: 14297
Author: [email protected]
Date: Wed Apr 17 00:20:24 2013
Log: Nuke SamplerRegistry
The registry is a simple list of active Samplers but uses additional Mutex.
Useful parts were merged into SamplerThread, others removed completely.
BUG=None
Review URL: https://codereview.chromium.org/14293009
http://code.google.com/p/v8/source/detail?r=14297
Modified:
/branches/bleeding_edge/src/log.cc
/branches/bleeding_edge/src/log.h
/branches/bleeding_edge/src/sampler.cc
/branches/bleeding_edge/src/v8.cc
=======================================
--- /branches/bleeding_edge/src/log.cc Tue Apr 16 05:30:51 2013
+++ /branches/bleeding_edge/src/log.cc Wed Apr 17 00:20:24 2013
@@ -1928,66 +1928,5 @@
return log_->Close();
}
-
-
-// Protects the state below.
-static Mutex* active_samplers_mutex = NULL;
-
-List<Sampler*>* SamplerRegistry::active_samplers_ = NULL;
-
-
-void SamplerRegistry::SetUp() {
- if (!active_samplers_mutex) {
- active_samplers_mutex = OS::CreateMutex();
- }
-}
-
-
-bool SamplerRegistry::IterateActiveSamplers(VisitSampler func, void*
param) {
- ScopedLock lock(active_samplers_mutex);
- for (int i = 0;
- ActiveSamplersExist() && i < active_samplers_->length();
- ++i) {
- func(active_samplers_->at(i), param);
- }
- return ActiveSamplersExist();
-}
-
-
-static void ComputeCpuProfiling(Sampler* sampler, void* flag_ptr) {
- bool* flag = reinterpret_cast<bool*>(flag_ptr);
- *flag |= sampler->IsProfiling();
-}
-
-
-SamplerRegistry::State SamplerRegistry::GetState() {
- bool flag = false;
- if (!IterateActiveSamplers(&ComputeCpuProfiling, &flag)) {
- return HAS_NO_SAMPLERS;
- }
- return flag ? HAS_CPU_PROFILING_SAMPLERS : HAS_SAMPLERS;
-}
-
-
-void SamplerRegistry::AddActiveSampler(Sampler* sampler) {
- ASSERT(sampler->IsActive());
- ScopedLock lock(active_samplers_mutex);
- if (active_samplers_ == NULL) {
- active_samplers_ = new List<Sampler*>;
- } else {
- ASSERT(!active_samplers_->Contains(sampler));
- }
- active_samplers_->Add(sampler);
-}
-
-
-void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) {
- ASSERT(sampler->IsActive());
- ScopedLock lock(active_samplers_mutex);
- ASSERT(active_samplers_ != NULL);
- bool removed = active_samplers_->RemoveElement(sampler);
- ASSERT(removed);
- USE(removed);
-}
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/log.h Tue Apr 16 05:06:43 2013
+++ /branches/bleeding_edge/src/log.h Wed Apr 17 00:20:24 2013
@@ -505,40 +505,6 @@
};
-// Process wide registry of samplers.
-class SamplerRegistry : public AllStatic {
- public:
- enum State {
- HAS_NO_SAMPLERS,
- HAS_SAMPLERS,
- HAS_CPU_PROFILING_SAMPLERS
- };
-
- static void SetUp();
-
- typedef void (*VisitSampler)(Sampler*, void*);
-
- static State GetState();
-
- // Iterates over all active samplers keeping the internal lock held.
- // Returns whether there are any active samplers.
- static bool IterateActiveSamplers(VisitSampler func, void* param);
-
- // Adds/Removes an active sampler.
- static void AddActiveSampler(Sampler* sampler);
- static void RemoveActiveSampler(Sampler* sampler);
-
- private:
- static bool ActiveSamplersExist() {
- return active_samplers_ != NULL && !active_samplers_->is_empty();
- }
-
- static List<Sampler*>* active_samplers_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(SamplerRegistry);
-};
-
-
// Class that extracts stack trace, used for profiling.
class StackTracer : public AllStatic {
public:
=======================================
--- /branches/bleeding_edge/src/sampler.cc Tue Apr 16 05:06:43 2013
+++ /branches/bleeding_edge/src/sampler.cc Wed Apr 17 00:20:24 2013
@@ -65,12 +65,6 @@
#include "v8threads.h"
-namespace v8 {
-namespace internal {
-
-
-#if defined(USE_SIGNALS)
-
#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
// Not all versions of Android's C library provide ucontext_t.
@@ -146,6 +140,11 @@
#endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T)
+namespace v8 {
+namespace internal {
+
+#if defined(USE_SIGNALS)
+
class Sampler::PlatformData : public Malloced {
public:
PlatformData()
@@ -161,7 +160,41 @@
};
-static void ProfilerSignalHandler(int signal, siginfo_t* info, void*
context) {
+class SignalHandler : public AllStatic {
+ public:
+ static inline void EnsureInstalled() {
+ if (signal_handler_installed_) return;
+ struct sigaction sa;
+ sa.sa_sigaction = &HandleProfilerSignal;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+ signal_handler_installed_ =
+ (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
+ }
+
+ static inline 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);
+ static bool signal_handler_installed_;
+ static struct sigaction old_signal_handler_;
+};
+
+struct sigaction SignalHandler::old_signal_handler_;
+bool SignalHandler::signal_handler_installed_ = false;
+
+
+void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
+ void* context) {
#if defined(__native_client__)
// As Native Client does not support signal handling, profiling
// is disabled.
@@ -360,83 +393,78 @@
static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
static void TearDown() { delete mutex_; }
-
-#if defined(USE_SIGNALS)
- 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;
- }
- }
-#endif
static void AddActiveSampler(Sampler* sampler) {
+ bool need_to_start = false;
ScopedLock lock(mutex_);
- SamplerRegistry::AddActiveSampler(sampler);
if (instance_ == NULL) {
// Start a thread that will send SIGPROF signal to VM threads,
// when CPU profiling will be enabled.
instance_ = new SamplerThread(sampler->interval());
- instance_->StartSynchronously();
- } else {
- ASSERT(instance_->interval_ == sampler->interval());
+ need_to_start = true;
}
+
+ ASSERT(sampler->IsActive());
+ ASSERT(!instance_->active_samplers_.Contains(sampler));
+ ASSERT(instance_->interval_ == sampler->interval());
+ instance_->active_samplers_.Add(sampler);
+
+#if defined(USE_SIGNALS)
+ SignalHandler::EnsureInstalled();
+#endif
+ if (need_to_start) instance_->StartSynchronously();
}
static void RemoveActiveSampler(Sampler* sampler) {
- ScopedLock lock(mutex_);
- SamplerRegistry::RemoveActiveSampler(sampler);
- if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
- instance_->Join();
- delete instance_;
- instance_ = NULL;
+ SamplerThread* instance_to_remove = NULL;
+ {
+ ScopedLock lock(mutex_);
+
+ ASSERT(sampler->IsActive());
+ bool removed = instance_->active_samplers_.RemoveElement(sampler);
+ ASSERT(removed);
+ USE(removed);
+
+ // We cannot delete the instance immediately as we need to Join() the
+ // thread but we are holding mutex_ and the thread may try to
acquire it.
+ if (instance_->active_samplers_.is_empty()) {
+ instance_to_remove = instance_;
+ instance_ = NULL;
#if defined(USE_SIGNALS)
- RestoreSignalHandler();
+ SignalHandler::Restore();
#endif
+ }
}
+
+ if (!instance_to_remove) return;
+ instance_to_remove->Join();
+ delete instance_to_remove;
}
// Implement Thread::Run().
virtual void Run() {
- SamplerRegistry::State state;
- while ((state = SamplerRegistry::GetState()) !=
- SamplerRegistry::HAS_NO_SAMPLERS) {
- // When CPU profiling is enabled both JavaScript and C++ code is
- // profiled. We must not suspend.
- if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) {
-#if defined(USE_SIGNALS)
- if (!signal_handler_installed_) InstallSignalHandler();
-#endif
- SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this);
- } else {
-#if defined(USE_SIGNALS)
- if (signal_handler_installed_) RestoreSignalHandler();
-#endif
+ while (true) {
+ {
+ ScopedLock lock(mutex_);
+ if (active_samplers_.is_empty()) break;
+ // When CPU profiling is enabled both JavaScript and C++ code is
+ // profiled. We must not suspend.
+ for (int i = 0; i < active_samplers_.length(); ++i) {
+ Sampler* sampler = active_samplers_.at(i);
+ if (!sampler->isolate()->IsInitialized()) continue;
+ if (!sampler->IsProfiling()) continue;
+ SampleContext(sampler);
+ }
}
OS::Sleep(interval_);
}
}
- static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
- if (!sampler->isolate()->IsInitialized()) return;
- if (!sampler->IsProfiling()) return;
- SamplerThread* sender = reinterpret_cast<SamplerThread*>(raw_sender);
- sender->SampleContext(sampler);
- }
-
+ private:
#if defined(USE_SIGNALS)
void SampleContext(Sampler* sampler) {
- if (!signal_handler_installed_) return;
+ if (!SignalHandler::Installed()) return;
pthread_t tid = sampler->platform_data()->vm_tid();
int result = pthread_kill(tid, SIGPROF);
USE(result);
@@ -575,27 +603,20 @@
#endif // USE_SIGNALS
- const int interval_;
// Protects the process wide state below.
static Mutex* mutex_;
static SamplerThread* instance_;
-#if defined(USE_SIGNALS)
- static bool signal_handler_installed_;
- static struct sigaction old_signal_handler_;
-#endif
+
+ const int interval_;
+ List<Sampler*> active_samplers_;
- private:
DISALLOW_COPY_AND_ASSIGN(SamplerThread);
};
Mutex* SamplerThread::mutex_ = NULL;
SamplerThread* SamplerThread::instance_ = NULL;
-#if defined(USE_SIGNALS)
-struct sigaction SamplerThread::old_signal_handler_;
-bool SamplerThread::signal_handler_installed_ = false;
-#endif
void Sampler::SetUp() {
=======================================
--- /branches/bleeding_edge/src/v8.cc Mon Apr 15 06:57:41 2013
+++ /branches/bleeding_edge/src/v8.cc Wed Apr 17 00:20:24 2013
@@ -37,7 +37,6 @@
#include "heap-profiler.h"
#include "hydrogen.h"
#include "lithium-allocator.h"
-#include "log.h"
#include "objects.h"
#include "once.h"
#include "platform.h"
@@ -281,7 +280,6 @@
ElementsAccessor::InitializeOncePerProcess();
LOperand::SetUpCaches();
SetUpJSCallerSavedCodeData();
- SamplerRegistry::SetUp();
ExternalReference::SetUp();
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.