Index: src/platform-openbsd.cc |
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc |
index 4c29023c0a5b01c68b10981e53af21978b64970e..e1aff17377170605b7d04851e27fe565c130ec7d 100644 |
--- a/src/platform-openbsd.cc |
+++ b/src/platform-openbsd.cc |
@@ -53,7 +53,6 @@ |
#include "platform-posix.h" |
#include "platform.h" |
-#include "simulator.h" |
#include "v8threads.h" |
#include "vm-state-inl.h" |
@@ -729,260 +728,17 @@ Semaphore* OS::CreateSemaphore(int count) { |
} |
-static pthread_t GetThreadID() { |
- return pthread_self(); |
-} |
- |
- |
-class Sampler::PlatformData : public Malloced { |
- public: |
- PlatformData() |
- : vm_tid_(GetThreadID()), |
- profiled_thread_id_(ThreadId::Current()) {} |
- |
- pthread_t vm_tid() const { return vm_tid_; } |
- ThreadId profiled_thread_id() { return profiled_thread_id_; } |
- |
- private: |
- pthread_t vm_tid_; |
- ThreadId profiled_thread_id_; |
-}; |
- |
- |
-static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
- USE(info); |
- if (signal != SIGPROF) return; |
- Isolate* isolate = Isolate::UncheckedCurrent(); |
- if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |
- // We require a fully initialized and entered isolate. |
- return; |
- } |
- if (v8::Locker::IsActive() && |
- !isolate->thread_manager()->IsLockedByCurrentThread()) { |
- return; |
- } |
- |
- Sampler* sampler = isolate->logger()->sampler(); |
- if (sampler == NULL || !sampler->IsActive()) return; |
- |
-#if defined(USE_SIMULATOR) |
-#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS |
- ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); |
- Isolate::PerIsolateThreadData* per_thread_data = isolate-> |
- FindPerThreadDataForThread(thread_id); |
- if (!per_thread_data) return; |
- Simulator* sim = per_thread_data->simulator(); |
- // Check if there is active simulator before allocating TickSample. |
- if (!sim) return; |
-#endif |
-#endif // USE_SIMULATOR |
- |
- TickSample sample_obj; |
- TickSample* sample = isolate->cpu_profiler()->TickSampleEvent(); |
- if (sample == NULL) sample = &sample_obj; |
- |
- // Extracting the sample from the context is extremely machine dependent. |
- sample->state = isolate->current_vm_state(); |
- ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
-#if defined(USE_SIMULATOR) |
-#if V8_TARGET_ARCH_ARM |
- sample->pc = reinterpret_cast<Address>(sim->get_register(Simulator::pc)); |
- sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp)); |
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11)); |
-#elif V8_TARGET_ARCH_MIPS |
- sample->pc = reinterpret_cast<Address>(sim->get_register(Simulator::pc)); |
- sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp)); |
- sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp)); |
-#endif |
-#else |
-#ifdef __NetBSD__ |
- mcontext_t& mcontext = ucontext->uc_mcontext; |
-#if V8_HOST_ARCH_IA32 |
- sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]); |
- sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]); |
- sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]); |
-#elif V8_HOST_ARCH_X64 |
- sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]); |
- sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]); |
- sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]); |
-#endif // V8_HOST_ARCH |
-#else // OpenBSD |
-#if V8_HOST_ARCH_IA32 |
- sample->pc = reinterpret_cast<Address>(ucontext->sc_eip); |
- sample->sp = reinterpret_cast<Address>(ucontext->sc_esp); |
- sample->fp = reinterpret_cast<Address>(ucontext->sc_ebp); |
-#elif V8_HOST_ARCH_X64 |
- sample->pc = reinterpret_cast<Address>(ucontext->sc_rip); |
- sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp); |
- sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp); |
-#endif // V8_HOST_ARCH |
-#endif // __NetBSD__ |
-#endif // USE_SIMULATOR |
- sampler->SampleStack(sample); |
- sampler->Tick(sample); |
-} |
- |
- |
-class SignalSender : public Thread { |
- public: |
- static const int kSignalSenderStackSize = 64 * KB; |
- |
- 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); |
- if (instance_ == NULL) { |
- // Start a thread that will send SIGPROF signal to VM threads, |
- // when CPU profiling will be enabled. |
- instance_ = new SignalSender(sampler->interval()); |
- instance_->StartSynchronously(); |
- } else { |
- ASSERT(instance_->interval_ == sampler->interval()); |
- } |
- } |
- |
- static void RemoveActiveSampler(Sampler* sampler) { |
- ScopedLock lock(mutex_); |
- SamplerRegistry::RemoveActiveSampler(sampler); |
- if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { |
- instance_->Join(); |
- delete instance_; |
- instance_ = NULL; |
- RestoreSignalHandler(); |
- } |
- } |
- |
- // 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 (!signal_handler_installed_) InstallSignalHandler(); |
- SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this); |
- } else if (signal_handler_installed_) { |
- RestoreSignalHandler(); |
- } |
- Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough. |
- } |
- } |
- |
- static void DoCpuProfile(Sampler* sampler, void* raw_sender) { |
- if (!sampler->IsProfiling()) return; |
- SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender); |
- sender->SendProfilingSignal(sampler->platform_data()->vm_tid()); |
- } |
- |
- void SendProfilingSignal(pthread_t tid) { |
- if (!signal_handler_installed_) return; |
- pthread_kill(tid, SIGPROF); |
- } |
- |
- void Sleep() { |
- // Convert ms to us and subtract 100 us to compensate delays |
- // occuring during signal delivery. |
- useconds_t interval = interval_ * 1000 - 100; |
- int result = usleep(interval); |
-#ifdef DEBUG |
- if (result != 0 && errno != EINTR) { |
- fprintf(stderr, |
- "SignalSender usleep error; interval = %u, errno = %d\n", |
- interval, |
- errno); |
- ASSERT(result == 0 || errno == EINTR); |
- } |
-#endif |
- USE(result); |
- } |
- |
- 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: |
- DISALLOW_COPY_AND_ASSIGN(SignalSender); |
-}; |
- |
- |
-Mutex* SignalSender::mutex_ = NULL; |
-SignalSender* SignalSender::instance_ = NULL; |
-struct sigaction SignalSender::old_signal_handler_; |
-bool SignalSender::signal_handler_installed_ = false; |
- |
- |
void OS::SetUp() { |
// Seed the random number generator. We preserve microsecond resolution. |
uint64_t seed = Ticks() ^ (getpid() << 16); |
srandom(static_cast<unsigned int>(seed)); |
limit_mutex = CreateMutex(); |
- SignalSender::SetUp(); |
} |
void OS::TearDown() { |
- SignalSender::TearDown(); |
delete limit_mutex; |
} |
-Sampler::Sampler(Isolate* isolate, int interval) |
- : isolate_(isolate), |
- interval_(interval), |
- profiling_(false), |
- active_(false), |
- samples_taken_(0) { |
- data_ = new PlatformData; |
-} |
- |
- |
-Sampler::~Sampler() { |
- ASSERT(!IsActive()); |
- delete data_; |
-} |
- |
- |
-void Sampler::Start() { |
- ASSERT(!IsActive()); |
- SetActive(true); |
- SignalSender::AddActiveSampler(this); |
-} |
- |
- |
-void Sampler::Stop() { |
- ASSERT(IsActive()); |
- SignalSender::RemoveActiveSampler(this); |
- SetActive(false); |
-} |
- |
- |
} } // namespace v8::internal |