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 |