| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/libsampler/sampler.h" | 5 #include "src/libsampler/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 && !V8_OS_NACL && !V8_OS_AIX | 16 #if !V8_OS_QNX && !V8_OS_AIX |
| 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)) && !V8_OS_OPENBSD |
| 25 !V8_OS_OPENBSD && !V8_OS_NACL | |
| 26 #include <ucontext.h> | 25 #include <ucontext.h> |
| 27 #endif | 26 #endif |
| 28 | 27 |
| 29 #include <unistd.h> | 28 #include <unistd.h> |
| 30 | 29 |
| 31 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. | 30 // 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. | 31 // Old versions of the C library <signal.h> didn't define the type. |
| 33 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ | 32 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ |
| 34 (defined(__arm__) || defined(__aarch64__)) && \ | 33 (defined(__arm__) || defined(__aarch64__)) && \ |
| 35 !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) | 34 !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 if (--client_count_ == 0) Restore(); | 358 if (--client_count_ == 0) Restore(); |
| 360 } | 359 } |
| 361 | 360 |
| 362 static bool Installed() { | 361 static bool Installed() { |
| 363 base::LockGuard<base::Mutex> lock_guard(mutex_); | 362 base::LockGuard<base::Mutex> lock_guard(mutex_); |
| 364 return signal_handler_installed_; | 363 return signal_handler_installed_; |
| 365 } | 364 } |
| 366 | 365 |
| 367 private: | 366 private: |
| 368 static void Install() { | 367 static void Install() { |
| 369 #if !V8_OS_NACL | |
| 370 struct sigaction sa; | 368 struct sigaction sa; |
| 371 sa.sa_sigaction = &HandleProfilerSignal; | 369 sa.sa_sigaction = &HandleProfilerSignal; |
| 372 sigemptyset(&sa.sa_mask); | 370 sigemptyset(&sa.sa_mask); |
| 373 #if V8_OS_QNX | 371 #if V8_OS_QNX |
| 374 sa.sa_flags = SA_SIGINFO; | 372 sa.sa_flags = SA_SIGINFO; |
| 375 #else | 373 #else |
| 376 sa.sa_flags = SA_RESTART | SA_SIGINFO; | 374 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 377 #endif | 375 #endif |
| 378 signal_handler_installed_ = | 376 signal_handler_installed_ = |
| 379 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | 377 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 380 #endif // !V8_OS_NACL | |
| 381 } | 378 } |
| 382 | 379 |
| 383 static void Restore() { | 380 static void Restore() { |
| 384 #if !V8_OS_NACL | |
| 385 if (signal_handler_installed_) { | 381 if (signal_handler_installed_) { |
| 386 sigaction(SIGPROF, &old_signal_handler_, 0); | 382 sigaction(SIGPROF, &old_signal_handler_, 0); |
| 387 signal_handler_installed_ = false; | 383 signal_handler_installed_ = false; |
| 388 } | 384 } |
| 389 #endif | |
| 390 } | 385 } |
| 391 | 386 |
| 392 #if !V8_OS_NACL | |
| 393 static void FillRegisterState(void* context, RegisterState* regs); | 387 static void FillRegisterState(void* context, RegisterState* regs); |
| 394 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); | 388 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); |
| 395 #endif | 389 |
| 396 // Protects the process wide state below. | 390 // Protects the process wide state below. |
| 397 static base::Mutex* mutex_; | 391 static base::Mutex* mutex_; |
| 398 static int client_count_; | 392 static int client_count_; |
| 399 static bool signal_handler_installed_; | 393 static bool signal_handler_installed_; |
| 400 static struct sigaction old_signal_handler_; | 394 static struct sigaction old_signal_handler_; |
| 401 }; | 395 }; |
| 402 | 396 |
| 403 base::Mutex* SignalHandler::mutex_ = nullptr; | 397 base::Mutex* SignalHandler::mutex_ = nullptr; |
| 404 int SignalHandler::client_count_ = 0; | 398 int SignalHandler::client_count_ = 0; |
| 405 struct sigaction SignalHandler::old_signal_handler_; | 399 struct sigaction SignalHandler::old_signal_handler_; |
| 406 bool SignalHandler::signal_handler_installed_ = false; | 400 bool SignalHandler::signal_handler_installed_ = false; |
| 407 | 401 |
| 408 | 402 |
| 409 // As Native Client does not support signal handling, profiling is disabled. | |
| 410 #if !V8_OS_NACL | |
| 411 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, | 403 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
| 412 void* context) { | 404 void* context) { |
| 413 USE(info); | 405 USE(info); |
| 414 if (signal != SIGPROF) return; | 406 if (signal != SIGPROF) return; |
| 415 v8::RegisterState state; | 407 v8::RegisterState state; |
| 416 FillRegisterState(context, &state); | 408 FillRegisterState(context, &state); |
| 417 SamplerManager::instance()->DoSample(state); | 409 SamplerManager::instance()->DoSample(state); |
| 418 } | 410 } |
| 419 | 411 |
| 420 void SignalHandler::FillRegisterState(void* context, RegisterState* state) { | 412 void SignalHandler::FillRegisterState(void* context, RegisterState* state) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 state->sp = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_SP]); | 537 state->sp = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_SP]); |
| 546 state->fp = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_FP]); | 538 state->fp = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_FP]); |
| 547 #endif // V8_HOST_ARCH_* | 539 #endif // V8_HOST_ARCH_* |
| 548 #elif V8_OS_AIX | 540 #elif V8_OS_AIX |
| 549 state->pc = reinterpret_cast<void*>(mcontext.jmp_context.iar); | 541 state->pc = reinterpret_cast<void*>(mcontext.jmp_context.iar); |
| 550 state->sp = reinterpret_cast<void*>(mcontext.jmp_context.gpr[1]); | 542 state->sp = reinterpret_cast<void*>(mcontext.jmp_context.gpr[1]); |
| 551 state->fp = reinterpret_cast<void*>(mcontext.jmp_context.gpr[31]); | 543 state->fp = reinterpret_cast<void*>(mcontext.jmp_context.gpr[31]); |
| 552 #endif // V8_OS_AIX | 544 #endif // V8_OS_AIX |
| 553 } | 545 } |
| 554 | 546 |
| 555 #endif // !V8_OS_NACL | |
| 556 | |
| 557 #endif // USE_SIGNALS | 547 #endif // USE_SIGNALS |
| 558 | 548 |
| 559 | 549 |
| 560 void Sampler::SetUp() { | 550 void Sampler::SetUp() { |
| 561 #if defined(USE_SIGNALS) | 551 #if defined(USE_SIGNALS) |
| 562 SignalHandler::SetUp(); | 552 SignalHandler::SetUp(); |
| 563 #endif | 553 #endif |
| 564 } | 554 } |
| 565 | 555 |
| 566 | 556 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 #endif | 654 #endif |
| 665 SampleStack(state); | 655 SampleStack(state); |
| 666 } | 656 } |
| 667 ResumeThread(profiled_thread); | 657 ResumeThread(profiled_thread); |
| 668 } | 658 } |
| 669 | 659 |
| 670 #endif // USE_SIGNALS | 660 #endif // USE_SIGNALS |
| 671 | 661 |
| 672 } // namespace sampler | 662 } // namespace sampler |
| 673 } // namespace v8 | 663 } // namespace v8 |
| OLD | NEW |