| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/sampler.h" | 5 #include "src/sampler.h" |
| 6 | 6 |
| 7 #if V8_OS_POSIX && !V8_OS_CYGWIN | 7 #if V8_OS_POSIX && !V8_OS_CYGWIN |
| 8 | 8 |
| 9 #define USE_SIGNALS | 9 #define USE_SIGNALS |
| 10 | 10 |
| 11 #include <errno.h> | 11 #include <errno.h> |
| 12 #include <pthread.h> | 12 #include <pthread.h> |
| 13 #include <signal.h> | 13 #include <signal.h> |
| 14 #include <sys/time.h> | 14 #include <sys/time.h> |
| 15 | 15 |
| 16 #if !V8_OS_QNX | 16 #if !V8_OS_QNX && !V8_OS_NACL |
| 17 #include <sys/syscall.h> // NOLINT | 17 #include <sys/syscall.h> // NOLINT |
| 18 #endif | 18 #endif |
| 19 | 19 |
| 20 #if V8_OS_MACOSX | 20 #if V8_OS_MACOSX |
| 21 #include <mach/mach.h> | 21 #include <mach/mach.h> |
| 22 // OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> | 22 // OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> |
| 23 // and is a typedef for struct sigcontext. There is no uc_mcontext. | 23 // and is a typedef for struct sigcontext. There is no uc_mcontext. |
| 24 #elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) \ | 24 #elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) && \ |
| 25 && !V8_OS_OPENBSD | 25 !V8_OS_OPENBSD && !V8_OS_NACL |
| 26 #include <ucontext.h> | 26 #include <ucontext.h> |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 #include <unistd.h> | 29 #include <unistd.h> |
| 30 | 30 |
| 31 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. | 31 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. |
| 32 // Old versions of the C library <signal.h> didn't define the type. | 32 // Old versions of the C library <signal.h> didn't define the type. |
| 33 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ | 33 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ |
| 34 (defined(__arm__) || defined(__aarch64__)) && \ | 34 (defined(__arm__) || defined(__aarch64__)) && \ |
| 35 !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) | 35 !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 base::LockGuard<base::Mutex> lock_guard(mutex_); | 287 base::LockGuard<base::Mutex> lock_guard(mutex_); |
| 288 if (--client_count_ == 0) Restore(); | 288 if (--client_count_ == 0) Restore(); |
| 289 } | 289 } |
| 290 | 290 |
| 291 static bool Installed() { | 291 static bool Installed() { |
| 292 return signal_handler_installed_; | 292 return signal_handler_installed_; |
| 293 } | 293 } |
| 294 | 294 |
| 295 private: | 295 private: |
| 296 static void Install() { | 296 static void Install() { |
| 297 #if !V8_OS_NACL |
| 297 struct sigaction sa; | 298 struct sigaction sa; |
| 298 sa.sa_sigaction = &HandleProfilerSignal; | 299 sa.sa_sigaction = &HandleProfilerSignal; |
| 299 sigemptyset(&sa.sa_mask); | 300 sigemptyset(&sa.sa_mask); |
| 300 #if V8_OS_QNX | 301 #if V8_OS_QNX |
| 301 sa.sa_flags = SA_SIGINFO; | 302 sa.sa_flags = SA_SIGINFO; |
| 302 #else | 303 #else |
| 303 sa.sa_flags = SA_RESTART | SA_SIGINFO; | 304 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 304 #endif | 305 #endif |
| 305 signal_handler_installed_ = | 306 signal_handler_installed_ = |
| 306 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | 307 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 308 #endif |
| 307 } | 309 } |
| 308 | 310 |
| 309 static void Restore() { | 311 static void Restore() { |
| 312 #if !V8_OS_NACL |
| 310 if (signal_handler_installed_) { | 313 if (signal_handler_installed_) { |
| 311 sigaction(SIGPROF, &old_signal_handler_, 0); | 314 sigaction(SIGPROF, &old_signal_handler_, 0); |
| 312 signal_handler_installed_ = false; | 315 signal_handler_installed_ = false; |
| 313 } | 316 } |
| 317 #endif |
| 314 } | 318 } |
| 315 | 319 |
| 320 #if !V8_OS_NACL |
| 316 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); | 321 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); |
| 322 #endif |
| 317 // Protects the process wide state below. | 323 // Protects the process wide state below. |
| 318 static base::Mutex* mutex_; | 324 static base::Mutex* mutex_; |
| 319 static int client_count_; | 325 static int client_count_; |
| 320 static bool signal_handler_installed_; | 326 static bool signal_handler_installed_; |
| 321 static struct sigaction old_signal_handler_; | 327 static struct sigaction old_signal_handler_; |
| 322 }; | 328 }; |
| 323 | 329 |
| 324 | 330 |
| 325 base::Mutex* SignalHandler::mutex_ = NULL; | 331 base::Mutex* SignalHandler::mutex_ = NULL; |
| 326 int SignalHandler::client_count_ = 0; | 332 int SignalHandler::client_count_ = 0; |
| 327 struct sigaction SignalHandler::old_signal_handler_; | 333 struct sigaction SignalHandler::old_signal_handler_; |
| 328 bool SignalHandler::signal_handler_installed_ = false; | 334 bool SignalHandler::signal_handler_installed_ = false; |
| 329 | 335 |
| 330 | 336 |
| 337 // As Native Client does not support signal handling, profiling is disabled. |
| 338 #if !V8_OS_NACL |
| 331 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, | 339 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
| 332 void* context) { | 340 void* context) { |
| 333 #if V8_OS_NACL | |
| 334 // As Native Client does not support signal handling, profiling | |
| 335 // is disabled. | |
| 336 return; | |
| 337 #else | |
| 338 USE(info); | 341 USE(info); |
| 339 if (signal != SIGPROF) return; | 342 if (signal != SIGPROF) return; |
| 340 Isolate* isolate = Isolate::UnsafeCurrent(); | 343 Isolate* isolate = Isolate::UnsafeCurrent(); |
| 341 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 344 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |
| 342 // We require a fully initialized and entered isolate. | 345 // We require a fully initialized and entered isolate. |
| 343 return; | 346 return; |
| 344 } | 347 } |
| 345 if (v8::Locker::IsActive() && | 348 if (v8::Locker::IsActive() && |
| 346 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 349 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
| 347 return; | 350 return; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 state.sp = reinterpret_cast<Address>(mcontext.cpu.esp); | 473 state.sp = reinterpret_cast<Address>(mcontext.cpu.esp); |
| 471 state.fp = reinterpret_cast<Address>(mcontext.cpu.ebp); | 474 state.fp = reinterpret_cast<Address>(mcontext.cpu.ebp); |
| 472 #elif V8_HOST_ARCH_ARM | 475 #elif V8_HOST_ARCH_ARM |
| 473 state.pc = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_PC]); | 476 state.pc = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_PC]); |
| 474 state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]); | 477 state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]); |
| 475 state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]); | 478 state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]); |
| 476 #endif // V8_HOST_ARCH_* | 479 #endif // V8_HOST_ARCH_* |
| 477 #endif // V8_OS_QNX | 480 #endif // V8_OS_QNX |
| 478 #endif // USE_SIMULATOR | 481 #endif // USE_SIMULATOR |
| 479 sampler->SampleStack(state); | 482 sampler->SampleStack(state); |
| 483 } |
| 480 #endif // V8_OS_NACL | 484 #endif // V8_OS_NACL |
| 481 } | |
| 482 | 485 |
| 483 #endif | 486 #endif |
| 484 | 487 |
| 485 | 488 |
| 486 class SamplerThread : public base::Thread { | 489 class SamplerThread : public base::Thread { |
| 487 public: | 490 public: |
| 488 static const int kSamplerThreadStackSize = 64 * KB; | 491 static const int kSamplerThreadStackSize = 64 * KB; |
| 489 | 492 |
| 490 explicit SamplerThread(int interval) | 493 explicit SamplerThread(int interval) |
| 491 : Thread(base::Thread::Options("SamplerThread", kSamplerThreadStackSize)), | 494 : Thread(base::Thread::Options("SamplerThread", kSamplerThreadStackSize)), |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 #endif // USE_SIMULATOR | 741 #endif // USE_SIMULATOR |
| 739 SampleStack(state); | 742 SampleStack(state); |
| 740 } | 743 } |
| 741 ResumeThread(profiled_thread); | 744 ResumeThread(profiled_thread); |
| 742 } | 745 } |
| 743 | 746 |
| 744 #endif // USE_SIGNALS | 747 #endif // USE_SIGNALS |
| 745 | 748 |
| 746 | 749 |
| 747 } } // namespace v8::internal | 750 } } // namespace v8::internal |
| OLD | NEW |